From 4b1913c2c46b4253e77176c647987356c9d8d8fa Mon Sep 17 00:00:00 2001 From: Tom Beckmann Date: Wed, 13 Jun 2012 23:42:27 +0200 Subject: [PATCH] Added close button to workspaces, scroll position indicator --- src/Main.vala | 4 ++ src/Widgets/WorkspaceView.vala | 78 +++++++++++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/src/Main.vala b/src/Main.vala index c28fbea3..ad324180 100644 --- a/src/Main.vala +++ b/src/Main.vala @@ -31,6 +31,8 @@ namespace Gala WorkspaceView workspace_view; Clutter.Actor elements; + public unowned Compositor compositor; + Window? moving; //place for the window that is being moved over public Plugin () @@ -49,6 +51,8 @@ namespace Gala { var screen = get_screen (); + compositor = Compositor.new (screen.get_display ()); + elements = Compositor.get_stage_for_screen (screen); clutter_actor_reparent (Compositor.get_window_group_for_screen (screen), elements); clutter_actor_reparent (Compositor.get_overlay_group_for_screen (screen), elements); diff --git a/src/Widgets/WorkspaceView.vala b/src/Widgets/WorkspaceView.vala index 86bbd6b6..e9868760 100644 --- a/src/Widgets/WorkspaceView.vala +++ b/src/Widgets/WorkspaceView.vala @@ -33,6 +33,7 @@ namespace Gala Gdk.Pixbuf background_pix; Clutter.CairoTexture workspace_thumb; Clutter.CairoTexture current_workspace; + Clutter.CairoTexture scroll; const int current_border = 5; @@ -88,15 +89,21 @@ namespace Gala workspaces = new Clutter.Actor (); var box_layout = new Clutter.BoxLayout (); - box_layout.spacing = 12; workspaces.set_layout_manager (box_layout); + box_layout.spacing = 12; + bg = new Clutter.CairoTexture (500, (uint)height); bg.auto_resize = true; bg.add_constraint (new Clutter.BindConstraint (this, Clutter.BindCoordinate.WIDTH, 0)); bg.add_constraint (new Clutter.BindConstraint (this, Clutter.BindCoordinate.HEIGHT, 0)); bg.draw.connect (draw_background); + scroll = new Clutter.CairoTexture (100, 12); + scroll.height = 12; + scroll.auto_resize = true; + scroll.draw.connect (draw_scroll); + leave_event.connect ((e) => { if (!contains (e.related)) hide (); @@ -233,6 +240,7 @@ namespace Gala /*add_child (tile); removed for now until Luna+1 */ add_child (current_workspace); add_child (workspaces); + add_child (scroll); workspace_thumb.visible = false; //will only be used for cloning } @@ -259,6 +267,15 @@ namespace Gala return false; } + bool draw_scroll (Cairo.Context cr) + { + Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, 4, 4, scroll.width-12, 4, 2); + cr.set_source_rgba (1, 1, 1, 0.8); + cr.fill (); + + return false; + } + bool draw_background (Cairo.Context cr) { cr.rectangle (0, 1, width, height); @@ -327,17 +344,20 @@ namespace Gala const float scroll_speed = 30.0f; public override bool scroll_event (Clutter.ScrollEvent event) { - if (event.direction == Clutter.ScrollDirection.UP && workspaces.width + workspaces.x > width) { //left + if ((event.direction == Clutter.ScrollDirection.DOWN || event.direction == Clutter.ScrollDirection.RIGHT) + && workspaces.width + workspaces.x > width) { //left workspaces.x -= scroll_speed; current_workspace.x -= scroll_speed; - } else if (event.direction == Clutter.ScrollDirection.DOWN && workspaces.x < 0) { //right + } else if ((event.direction == Clutter.ScrollDirection.UP || event.direction == Clutter.ScrollDirection.LEFT) + && workspaces.x < 0) { //right workspaces.x += scroll_speed; current_workspace.x += scroll_speed; } + scroll.x = Math.fabsf (width/workspaces.width*workspaces.x); + return false; } - //FIXME move all this positioning stuff to a separate function which is only called by screen size changes public new void show () { if (visible) @@ -369,6 +389,11 @@ namespace Gala icons.set_layout_manager (new Clutter.BoxLayout ()); var backg = new Clutter.Clone (workspace_thumb); + var close = new GtkClutter.Texture (); + try { + close.set_from_pixbuf (Granite.Widgets.get_close_pixbuf ()); + } catch (Error e) { warning (e.message); } + var shown_applications = new List (); space.list_windows ().foreach ((w) => { @@ -407,6 +432,32 @@ namespace Gala group.height = 160; + if (space.index () != screen.n_workspaces - 1) //dont allow closing the last one + group.add_child (close); + close.x = -12.0f; + close.y = -10.0f; + close.reactive = true; + close.scale_gravity = Clutter.Gravity.CENTER; + close.scale_x = 0; + close.scale_y = 0; + + close.button_release_event.connect (() => { + space.list_windows ().foreach ((w) => { + if (w.window_type != WindowType.DOCK) { + var gw = Gdk.X11Window.foreign_new_for_display (Gdk.Display.get_default (), + w.get_xwindow ()); + if (gw != null) + gw.destroy (); + } + }); + Timeout.add (250, () => { //give the windows time to close + screen.remove_workspace (space, screen.get_display ().get_current_time ()); + return false; + }); + hide (); + return true; + }); + group.reactive = true; group.button_release_event.connect (() => { space.activate (plugin.get_screen ().get_display ().get_current_time ()); @@ -414,6 +465,14 @@ namespace Gala hide (); return true; }); + group.enter_event.connect (() => { + close.animate (Clutter.AnimationMode.EASE_OUT_ELASTIC, 400, scale_x:1.0f, scale_y:1.0f); + return true; + }); + group.leave_event.connect (() => { + close.animate (Clutter.AnimationMode.EASE_IN_QUAD, 400, scale_x:0.0f, scale_y:0.0f); + return false; + }); workspaces.add_child (group); } @@ -421,10 +480,12 @@ namespace Gala var new_idx = screen.get_active_workspace ().index (); workspaces.x = width / 2 - workspaces.width / 2; - workspaces.y = 25; + workspaces.y = 20; current_workspace.y = workspaces.y - current_border; + scroll.y = height - 12; + visible = true; grab_key_focus (); Timeout.add (50, () => { @@ -434,7 +495,14 @@ namespace Gala animating = false; return false; }); //catch hot corner hiding problem and indicator placement + animate (Clutter.AnimationMode.EASE_OUT_QUAD, 250, y : area.height - height, opacity : 255); + + scroll.visible = workspaces.width > width; + if (scroll.visible) { + scroll.width = width/workspaces.width*width; + workspaces.x = 0.0f; + } } public new void hide ()