summaryrefslogtreecommitdiff
diff options
authorNeil Jagdish Patel <neil.patel@canonical.com>2010-08-24 13:02:16 +0100
committerNeil Jagdish Patel <neil.patel@canonical.com>2010-08-24 13:02:16 +0100
commitde1d46e08a477e69108fb6aaa5142d66da004278 (patch)
tree7e8144ef13214e50ae5f6fd4ff5aca4ff72d78e4
parent6ece6e81bad2d838899dc040631eafb512341ad1 (diff)
parent0bb8516abcda57f320160c87432867de30a7332a (diff)
[merge] trunk
(bzr r424.1.28)
-rw-r--r--.bzrignore5
-rw-r--r--configure.ac3
-rw-r--r--targets/mutter/Makefile.am1
-rw-r--r--targets/mutter/expose-manager.vala124
-rw-r--r--targets/mutter/plugin.vala70
-rw-r--r--targets/mutter/spaces-manager.vala190
-rw-r--r--tests/ui/test-home-button.vala1
-rw-r--r--tests/unit/test-appinfo-manager.vala18
-rw-r--r--unity-private/Makefile.am8
-rw-r--r--unity-private/launcher/quicklist-check-menu-item.vala4
-rw-r--r--unity-private/launcher/quicklist-image-menu-item.vala4
-rw-r--r--unity-private/launcher/quicklist-menu-item.vala4
-rw-r--r--unity-private/launcher/quicklist-radio-menu-item.vala4
-rw-r--r--unity-private/launcher/quicklist-view.vala15
-rw-r--r--unity-private/launcher/scroller-controller.vala46
-rw-r--r--unity-private/launcher/scroller-view.vala358
-rw-r--r--unity-private/launcher/scrollerchild.vala58
-rw-r--r--unity-private/panel/panel-home-button.vala8
-rw-r--r--unity-private/panel/panel-indicator-object-entry-view.vala20
-rw-r--r--unity-private/panel/panel-tray.vala14
-rw-r--r--unity-private/panel/panel-window-buttons.vala100
-rw-r--r--unity-private/places/places-controller.vala31
-rw-r--r--unity-private/places/places-default-renderer-group.vala170
-rw-r--r--unity-private/places/places-default-renderer.vala175
-rw-r--r--unity-private/places/places-place-home-renderer.vala235
-rw-r--r--unity-private/places/places-place-home.vala26
-rw-r--r--unity-private/places/places-place-model.vala2
-rw-r--r--unity-private/places/places-place-search-bar.vala9
-rw-r--r--unity-private/places/places-place-search-sections-bar.vala129
-rw-r--r--unity-private/places/places-view.vala5
-rw-r--r--unity-private/places/places-volume-child-controller.vala174
-rw-r--r--unity-private/places/places-volume-controller.vala73
-rw-r--r--unity-private/testing/test-window.vala1
-rw-r--r--unity-private/unity-utils.c34
-rw-r--r--unity-private/utils.vala7
-rw-r--r--unity/Makefile.am1
-rw-r--r--unity/icon-postprocessor.vala69
-rw-r--r--unity/quicklist-rendering.vala61
-rw-r--r--unity/shell.vala4
-rw-r--r--unity/unity-appinfo-manager.vala180
-rw-r--r--unity/unity-cairo-canvas.vala2
-rw-r--r--unity/unity-place.vala48
-rw-r--r--unity/unity-stripe-texture.vala126
-rw-r--r--vapi/clutter-1.0.vapi4
-rw-r--r--vapi/mutter-2.28.vapi5
45 files changed, 2217 insertions, 409 deletions
diff --git a/.bzrignore b/.bzrignore
index 7034e2473..8f8851524 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -341,6 +341,8 @@ unity-private/places/places-folder-browser-renderer.c
unity/unity-place-activation.c
unity-private/places/places-place-search-navigation.c
unity-private/panel/panel-window-buttons.c
+unity-private/places/places-volume-controller.c
+unity-private/places/places-volume-child-controller.c
tests/unit/test-place-browser.c
unity-private/gesture/gesture-dispatcher-xcb-glu.c
unity-private/gesture/gesture-dispatcher-xcb.c
@@ -348,3 +350,6 @@ unity-private/gesture/gesture-dispatcher.c
unity-private/gesture/gesture-event.c
unity-private/gesture/gesture-dispatcher-geis-glu.c
unity-private/gesture/gesture-dispatcher-geis.c
+unity-private/places/places-place-home-renderer.c
+unity/unity-stripe-texture.c
+
diff --git a/configure.ac b/configure.ac
index 10b3d1885..538569273 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
m4_define([unity_major], [0])
m4_define([unity_minor], [2])
-m4_define([unity_micro], [25])
+m4_define([unity_micro], [28])
m4_define([unity_api],
[unity_major.unity_minor])
@@ -116,6 +116,7 @@ PKG_CHECK_MODULES(BASE,
indicator
libbamf >= 0.2
libgnomeui-2.0
+ pango >= 1.6.0
unique-1.0
unity-misc
x11)
diff --git a/targets/mutter/Makefile.am b/targets/mutter/Makefile.am
index bbb6d5b80..1e34e1d33 100644
--- a/targets/mutter/Makefile.am
+++ b/targets/mutter/Makefile.am
@@ -22,6 +22,7 @@ libunity_mutter_la_CPPFLAGS = \
-I$(top_srcdir)/unity \
-I$(top_srcdir)/unity-private \
-I$(top_srcdir)/src \
+ -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
$(BASE_CFLAGS) \
$(MUTTER_CFLAGS) \
$(MAINTAINER_CFLAGS)
diff --git a/targets/mutter/expose-manager.vala b/targets/mutter/expose-manager.vala
index 33a490f8a..22f513d44 100644
--- a/targets/mutter/expose-manager.vala
+++ b/targets/mutter/expose-manager.vala
@@ -24,11 +24,22 @@ namespace Unity
{
private Clutter.Clone clone;
private Clutter.Actor darken_box;
+ private Clutter.Actor original_parent;
private bool hovered;
+ private bool dragging;
+ private float drag_start_x;
+ private float drag_start_y;
+ private bool drag_moved;
+
+ public Clutter.Actor pre_drag_parent { get { return original_parent; } }
+ public float pre_drag_scale_x { get; private set; }
+ public float pre_drag_scale_y { get; private set; }
public bool fade_on_close { get; set; }
public unowned Clutter.Actor source { get; private set; }
+
+ public signal void drag_dropped (Clutter.Actor onto);
public uint8 hovered_opacity { get; set; }
public uint8 unhovered_opacity { get; set; }
@@ -42,12 +53,15 @@ namespace Unity
darken_box.opacity = darken;
}
}
+
+ public bool enable_dnd { get; set; }
public ExposeClone (Clutter.Actor source)
{
darken = 0;
hovered_opacity = 255;
unhovered_opacity = 255;
+ enable_dnd = false;
this.source = source;
@@ -56,6 +70,8 @@ namespace Unity
else
clone = new Clutter.Clone (source);
+ source.destroy.connect (on_source_destroyed);
+
add_actor (clone);
clone.show ();
clone.reactive = true;
@@ -75,6 +91,102 @@ namespace Unity
{
this.enter_event.connect (this.on_mouse_enter);
this.leave_event.connect (this.on_mouse_leave);
+ this.button_press_event.connect (this.on_button_press);
+ }
+
+ private void on_source_destroyed ()
+ {
+ destroy ();
+ }
+
+ private bool on_button_press (Clutter.Event evnt)
+ {
+ if (!enable_dnd)
+ return false;
+
+ start_drag (evnt);
+ return true;
+ }
+
+ private void start_drag (Clutter.Event evnt)
+ {
+ dragging = true;
+ this.get_stage ().captured_event.connect (on_stage_captured_event);
+ original_parent = get_parent ();
+
+ float x, y;
+ double scale_x, scale_y;
+ evnt.get_coords (out x, out y);
+ get_scale (out scale_x, out scale_y);
+
+ drag_start_x = x;
+ drag_start_y = y;
+
+ pre_drag_scale_x = (float) scale_x;
+ pre_drag_scale_y = (float) scale_y;
+
+ drag_moved = false;
+ }
+
+ private void end_drag (int x, int y)
+ {
+ dragging = false;
+ clone.reactive = true;
+ reactive = true;
+ this.get_stage ().captured_event.disconnect (on_stage_captured_event);
+
+ if (!drag_moved)
+ return;
+
+ hide ();
+ Clutter.Actor target = (get_stage () as Clutter.Stage).get_actor_at_pos (Clutter.PickMode.REACTIVE, x, y);
+ show ();
+
+ drag_dropped (target);
+
+ on_mouse_leave (null);
+ }
+
+ private bool on_stage_captured_event (Clutter.Event event)
+ {
+ float x, y;
+ event.get_coords (out x, out y);
+
+ if (!dragging)
+ {
+ end_drag ((int) x, (int) y);
+ return false;
+ }
+
+ if (event.type == Clutter.EventType.MOTION)
+ {
+ if (Math.fabs (event.motion.x - drag_start_x) > 30 || Math.fabs (event.motion.y - drag_start_y) > 30 || drag_moved)
+ {
+ if (!drag_moved)
+ {
+ float width, height;
+
+ get_transformed_size (out width, out height);
+
+ reparent (get_stage ());
+
+ this.set_scale (width / this.width, height / this.height);
+
+ raise_top ();
+ drag_moved = true;
+ reactive = false;
+ clone.reactive = false;
+ }
+ set_position (event.motion.x - width / 2, event.motion.y - height / 2);
+ }
+ }
+ else if (event.type == Clutter.EventType.BUTTON_RELEASE)
+ {
+ end_drag ((int) x, (int) y);
+ return drag_moved;
+ }
+
+ return false;
}
private bool on_mouse_enter (Clutter.Event evnt)
@@ -85,7 +197,7 @@ namespace Unity
return false;
}
- private bool on_mouse_leave (Clutter.Event evnt)
+ private bool on_mouse_leave (Clutter.Event? evnt)
{
hovered = false;
opacity = unhovered_opacity;
@@ -172,7 +284,7 @@ namespace Unity
expose_group.destroy ();
expose_group = new Clutter.Group ();
- Clutter.Actor window_group = owner.plugin.get_normal_window_group ();
+ Clutter.Actor window_group = owner.plugin.get_window_group ();
(window_group as Clutter.Container).add_actor (expose_group);
expose_group.raise_top ();
@@ -195,6 +307,8 @@ namespace Unity
expose_group.add_actor (clone);
+ clone.destroy.connect (on_clone_destroyed);
+
clone.hovered_opacity = hovered_opacity;
clone.unhovered_opacity = unhovered_opacity;
clone.opacity = unhovered_opacity;
@@ -223,6 +337,12 @@ namespace Unity
stage.captured_event.connect (on_stage_captured_event);
}
+ private void on_clone_destroyed ()
+ {
+ if (expose_group.get_children ().length () <= 1)
+ end_expose ();
+ }
+
public void end_expose ()
{
if (!expose_showing)
diff --git a/targets/mutter/plugin.vala b/targets/mutter/plugin.vala
index 646867611..ddaae16a0 100644
--- a/targets/mutter/plugin.vala
+++ b/targets/mutter/plugin.vala
@@ -110,6 +110,12 @@ namespace Unity
public bool menus_swallow_events { get { return false; } }
+ private bool _super_key_active = false;
+ public bool super_key_active {
+ get { return _super_key_active; }
+ set { _super_key_active = value; }
+ }
+
public bool expose_showing { get { return expose_manager.expose_showing; } }
private static const int PANEL_HEIGHT = 24;
@@ -161,6 +167,7 @@ namespace Unity
construct
{
+ fullscreen_requests = new Gee.ArrayList<Object> ();
Unity.global_shell = this;
Unity.TimelineLogger.get_default(); // just inits the timer for logging
// attempt to get a boot logging filename
@@ -208,8 +215,8 @@ namespace Unity
private bool real_construct ()
{
START_FUNCTION ();
-
- fullscreen_requests = new Gee.ArrayList<Object> ();
+
+ Clutter.set_gl_picking_enabled (false);
this.stage = (Clutter.Stage)this.plugin.get_stage ();
this.stage.actor_added.connect ((a) => { ensure_input_region (); });
@@ -237,6 +244,26 @@ namespace Unity
Clutter.Group window_group = (Clutter.Group) this.plugin.get_window_group ();
+ /* we need to hook into the super key bound by mutter for g-shell.
+ don't ask me why mutter binds things for g-shell explictly...
+ */
+ Mutter.MetaDisplay display = Mutter.MetaScreen.get_display (plugin.get_screen ());
+ display.overlay_key_down.connect (() => {
+ super_key_active = true;
+ });
+
+ display.overlay_key.connect (() => {
+ super_key_active = false;
+ });
+
+ display.overlay_key_with_modifier.connect ((keysym) => {
+ super_key_modifier_release (keysym);
+ });
+
+ display.overlay_key_with_modifier_down.connect ((keysym) => {
+ super_key_modifier_press (keysym);
+ });
+
this.background = new Background ();
this.stage.add_actor (background);
this.background.lower_bottom ();
@@ -1118,13 +1145,10 @@ namespace Unity
int width,
int height)
{
- /*FIXME: This doesn't work in Mutter
if (window.get_data<string> (UNDECORATED_HINT) == null)
{
- uint32 xid = (uint32)window.get_x_window ();
- Utils.window_set_decorations (xid, 0);
+ Utils.window_set_decorations (Mutter.MetaWindow.get_xwindow (window.get_meta_window ()), 0);
}
- */
this.window_maximized (this, window, x, y, width, height);
@@ -1137,13 +1161,10 @@ namespace Unity
int width,
int height)
{
- /* FIXME: This doesn't work in Mutter
if (window.get_data<string> (UNDECORATED_HINT) == null)
{
- uint32 xid = (uint32)window.get_x_window ();
- Utils.window_set_decorations (xid, 1);
+ Utils.window_set_decorations (Mutter.MetaWindow.get_xwindow (window.get_meta_window ()), 1);
}
- */
this.window_unmaximized (this, window, x, y, width, height);
@@ -1152,11 +1173,30 @@ namespace Unity
public void map (Mutter.Window window)
{
- /* FIXME: This doesn't work in Mutter
- uint32 xid = (uint32)window.get_x_window ();
- if (Utils.window_is_decorated (xid) == false)
- window.set_data (UNDECORATED_HINT, "%s".printf ("true"));
- */
+ unowned Mutter.MetaWindow win = window.get_meta_window ();
+
+ if (window.get_window_type () == Mutter.MetaCompWindowType.NORMAL)
+ {
+ Idle.add (() => {
+ if (win is Object)
+ {
+ if (Utils.window_is_decorated (Mutter.MetaWindow.get_xwindow (win)) == false && Mutter.MetaWindow.is_maximized (win) == false)
+ {
+ window.set_data (UNDECORATED_HINT, "%s".printf ("true"));
+ }
+ else
+ {
+ if (Mutter.MetaWindow.is_maximized (win))
+ {
+ Utils.window_set_decorations (Mutter.MetaWindow.get_xwindow (win), 0);
+ }
+ }
+ }
+
+ return false;
+ });
+ }
+
this.maximus.process_window (window);
this.window_mapped (this, window);
diff --git a/targets/mutter/spaces-manager.vala b/targets/mutter/spaces-manager.vala
index fff8b005b..e72874a4d 100644
--- a/targets/mutter/spaces-manager.vala
+++ b/targets/mutter/spaces-manager.vala
@@ -31,7 +31,7 @@ namespace Unity {
this.parent = _parent;
parent.notify["showing"].connect (on_notify_showing);
- name = "Workspace Overview";
+ name = _("Workspaces");
load_icon_from_icon_name ("workspace-switcher");
}
@@ -52,10 +52,80 @@ namespace Unity {
else
parent.show_spaces_picker ();
}
+ public override QuicklistController? get_menu_controller ()
+ {
+ return new ApplicationQuicklistController (this);
+ }
+
+ public override void get_menu_actions (ScrollerChildController.menu_cb callback)
+ {
+ callback (null);
+ }
+
+ public override void get_menu_navigation (ScrollerChildController.menu_cb callback)
+ {
+ callback (null);
+ }
+
+ public override bool can_drag ()
+ {
+ return true;
+ }
+
+ }
+
+ public class WorkspaceClone : Clutter.Group
+ {
+ bool gridded;
+ Unity.Plugin plugin;
+ public unowned Mutter.MetaWorkspace workspace { get; private set; }
+
+ public WorkspaceClone (Mutter.MetaWorkspace wsp, Unity.Plugin plugin)
+ {
+ workspace = wsp;
+ this.plugin = plugin;
+
+ actor_added.connect (() => {
+ if (gridded)
+ grid ();
+ });
+
+ actor_removed.connect (() => {
+ if (gridded)
+ grid ();
+ });
+ }
+
+ private List<Clutter.Actor> toplevel_windows ()
+ {
+ List<Clutter.Actor> windows = new List<Clutter.Actor> ();
+
+ foreach (Clutter.Actor actor in get_children ())
+ if (actor is ExposeClone && (actor as ExposeClone).source is Mutter.Window)
+ windows.prepend (actor);
+
+ return windows;
+ }
+
+ public void grid ()
+ {
+ gridded = true;
+ plugin.expose_manager.position_windows_on_grid (toplevel_windows (), 50, 50, 50, 50);
+ }
+
+ public void ungrid ()
+ {
+ gridded = false;
+ int active_workspace = Mutter.MetaScreen.get_active_workspace_index (plugin.plugin.get_screen ());
+ foreach (Clutter.Actor actor in toplevel_windows ())
+ if (actor is ExposeClone)
+ (actor as ExposeClone).restore_window_position (active_workspace);
+ }
}
public class SpacesManager : GLib.Object
{
+ Clutter.Group selector_group;
Clutter.Actor background;
List<Clutter.Actor> clones;
Plugin plugin;
@@ -118,10 +188,17 @@ namespace Unity {
showing = true;
plugin.add_fullscreen_request (this);
+ global_shell.get_stage ().captured_event.connect (on_stage_capture_event);
+
if (background is Clutter.Actor)
background.destroy ();
+
+ if (selector_group is Clutter.Actor)
+ selector_group.destroy ();
background = new Clutter.Rectangle.with_color ({0, 0, 0, 255});
+ selector_group = new Clutter.Group ();
+
unowned Mutter.MetaScreen screen = plugin.plugin.get_screen ();
unowned GLib.List<Mutter.MetaWorkspace> workspaces = Mutter.MetaScreen.get_workspaces (screen);
unowned Clutter.Container window_group = plugin.plugin.get_normal_window_group() as Clutter.Container;
@@ -130,23 +207,42 @@ namespace Unity {
Mutter.MetaScreen.get_monitor_geometry (screen, 0, rect);
background.set_size (rect.width, rect.height);
- window_group.add_actor (background);
+ selector_group.add_actor (background);
background.raise_top ();
+ background.reactive = true;
foreach (unowned Mutter.MetaWorkspace workspace in workspaces)
{
Clutter.Actor clone = workspace_clone (workspace);
clones.append (clone);
- window_group.add_actor (clone);
+ selector_group.add_actor (clone);
clone.reactive = true;
clone.raise_top ();
clone.show ();
-
+ clone.opacity = 200;
+
unowned Mutter.MetaWorkspace cpy = workspace;
- clone.button_release_event.connect (() => { select_workspace (cpy); return true; });
+ clone.button_release_event.connect (() => {
+ select_workspace (cpy);
+ return true;
+ });
+
+ clone.enter_event.connect (() => {
+ clone.opacity = 255;
+ clone.raise_top ();
+ return true;
+ });
+
+ clone.leave_event.connect (() => {
+ clone.opacity = 200;
+ return true;
+ });
}
+ window_group.add_actor (selector_group);
+ selector_group.raise_top ();
+
layout_workspaces (clones, screen);
unowned GLib.List<Mutter.Window> windows = plugin.plugin.get_windows ();
@@ -156,6 +252,20 @@ namespace Unity {
}
}
+ private bool on_stage_capture_event (Clutter.Event event)
+ {
+ if (event.type == Clutter.EventType.BUTTON_PRESS)
+ {
+ if (event.button.y <= global_shell.get_panel_height_foobar () ||
+ event.button.x <= global_shell.get_launcher_width_foobar ())
+ {
+ select_workspace (null);
+ }
+ }
+
+ return false;
+ }
+
private void select_workspace (Mutter.MetaWorkspace? workspace) {
if (workspace == null)
{
@@ -169,16 +279,17 @@ namespace Unity {
Mutter.MetaWorkspace.activate (workspace, time_);
plugin.remove_fullscreen_request (this);
showing = false;
- }
+ global_shell.get_stage ().captured_event.disconnect (on_stage_capture_event);
+ }
+
private Clutter.Actor workspace_clone (Mutter.MetaWorkspace workspace) {
- Clutter.Group wsp;
+ WorkspaceClone wsp;
unowned GLib.List<Mutter.Window> windows;
windows = plugin.plugin.get_windows ();
- wsp = new Clutter.Group ();
-
List<Clutter.Actor> toplevel_windows = new List<Clutter.Actor> ();
+ wsp = new WorkspaceClone (workspace, plugin);
foreach (Mutter.Window window in windows)
{
@@ -194,12 +305,58 @@ namespace Unity {
ExposeClone clone = new ExposeClone (window);
clone.fade_on_close = false;
+ clone.reactive = true;
+ clone.darken = 25;
+ clone.enable_dnd = true;
+
+ clone.drag_dropped.connect ((t) => {
+ WorkspaceClone new_parent = clone.pre_drag_parent as WorkspaceClone;
+
+ while (!(t is Clutter.Stage))
+ {
+ if (t is WorkspaceClone)
+ {
+ new_parent = t as WorkspaceClone;
+ break;
+ }
+ t = t.get_parent ();
+ }
+
+ float x, y;
+
+ clone.move_anchor_point_from_gravity (Clutter.Gravity.CENTER);
+ new_parent.transform_stage_point (clone.x, clone.y, out x, out y);
+
+ clone.set_scale (clone.pre_drag_scale_x, clone.pre_drag_scale_y);
+ clone.set_position (x, y);
+
+ clone.move_anchor_point_from_gravity (Clutter.Gravity.NORTH_WEST);
+
+ clone.reparent (new_parent);
+
+ Mutter.MetaWindow.change_workspace_by_index ((clone.source as Mutter.Window).get_meta_window (),
+ Mutter.MetaWorkspace.index (new_parent.workspace),
+ true,
+ plugin.get_current_time ());
+ });
wsp.add_actor (clone);
- toplevel_windows.prepend (clone);
clone.set_size (window.width, window.height);
clone.set_position (window.x, window.y);
+
+ clone.button_release_event.connect (() => {
+ uint32 time_;
+
+ clone.raise_top ();
+ unowned Mutter.MetaWindow meta = (clone.source as Mutter.Window).get_meta_window ();
+
+ time_ = Mutter.MetaDisplay.get_current_time (Mutter.MetaWindow.get_display (meta));
+ Mutter.MetaWorkspace.activate (Mutter.MetaWindow.get_workspace (meta), time_);
+ Mutter.MetaWindow.activate (meta, time_);
+
+ return false;
+ });
clone.show ();
}
@@ -211,8 +368,10 @@ namespace Unity {
wsp.add_actor (background_clone);
background_clone.lower_bottom ();
background_clone.show ();
-
- plugin.expose_manager.position_windows_on_grid (toplevel_windows, 50, 50, 50, 50);
+
+ wsp.grid ();
+
+ wsp.set_size (background_clone.width, background_clone.height);
return wsp;
}
@@ -242,11 +401,8 @@ namespace Unity {
"y", (float) yoffset,
"scale-x", 1.0f,
"scale-y", 1.0f);
-
- int active_workspace = Mutter.MetaScreen.get_active_workspace_index (plugin.plugin.get_screen ());
- foreach (Clutter.Actor actor in (clone as Clutter.Group).get_children ())
- if (actor is ExposeClone)
- (actor as ExposeClone).restore_window_position (active_workspace);
+
+ (clone as WorkspaceClone).ungrid ();
anim.completed.connect (() => {
clone.destroy ();
diff --git a/tests/ui/test-home-button.vala b/tests/ui/test-home-button.vala
index e957b13b0..95692883b 100644
--- a/tests/ui/test-home-button.vala
+++ b/tests/ui/test-home-button.vala
@@ -34,6 +34,7 @@ namespace Unity.Tests.UI
Clutter.Stage? stage;
Unity.Testing.Director director;
Unity.Panel.HomeButton home_button;
+ public bool super_key_active {get; set;}
public HomeButtonSuite ()
{
diff --git a/tests/unit/test-appinfo-manager.vala b/tests/unit/test-appinfo-manager.vala
index 28c4572bd..f008d054c 100644
--- a/tests/unit/test-appinfo-manager.vala
+++ b/tests/unit/test-appinfo-manager.vala
@@ -91,12 +91,20 @@ namespace Unity.Tests.Unit
string old_datadir = Environment.get_user_data_dir ();
var manager = AppInfoManager.get_instance();
- Environment.set_variable ("XDG_DATA_HOME", Config.TESTUNITDIR, true);
+ Environment.set_variable ("XDG_DATA_HOME", Config.TESTUNITDIR+"/data", true);
+ debug ("XDG %s", Config.TESTUNITDIR+"/data");
var info = manager.lookup ("ubuntu-about.desktop");
+ assert (info != null);
assert (info is AppInfo);
assert ("About Ubuntu" == info.get_name ());
+ Gee.List<string> categories = manager.get_categories ("ubuntu-about.desktop");
+ assert (categories != null);
+ assert (categories[0] == "GNOME");
+ assert (categories[1] == "Application");
+ assert (categories[2] == "Core");
+
/* Reset the environment like a good citizen */
Environment.set_variable ("XDG_DATA_HOME", old_datadir, true);
}
@@ -113,7 +121,7 @@ namespace Unity.Tests.Unit
string old_datadir = Environment.get_user_data_dir ();
var manager = AppInfoManager.get_instance();
- Environment.set_variable ("XDG_DATA_HOME", Config.TESTUNITDIR, true);
+ Environment.set_variable ("XDG_DATA_HOME", Config.TESTUNITDIR+"/data", true);
try{
var info = yield manager.lookup_async ("ubuntu-about.desktop");
@@ -123,6 +131,12 @@ namespace Unity.Tests.Unit
error ("Error reading desktop file: %s", e.message);
}
+ Gee.List<string> categories = manager.get_categories ("ubuntu-about.desktop");
+ assert (categories != null);
+ assert (categories[0] == "GNOME");
+ assert (categories[1] == "Application");
+ assert (categories[2] == "Core");
+
/* Reset the environment like a good citizen */
Environment.set_variable ("XDG_DATA_HOME", old_datadir, true);
diff --git a/unity-private/Makefile.am b/unity-private/Makefile.am
index 38b98be75..0637e5eb0 100644
--- a/unity-private/Makefile.am
+++ b/unity-private/Makefile.am
@@ -38,6 +38,7 @@ libunity_private_la_VALAFLAGS = \
--library unity-private \
--vapidir=$(top_srcdir)/vapi/ \
--vapidir=$(top_srcdir)/unity/ \
+ --pkg Bamf-0.2 \
--pkg clutk-0.3 \
--pkg clutter-1.0 \
--pkg clutter-gtk-0.10 \
@@ -54,8 +55,8 @@ libunity_private_la_VALAFLAGS = \
--pkg gtk+-2.0 \
--pkg gnome-bg-2.0 \
--pkg indicator \
- --pkg Bamf-0.2 \
--pkg libwnck-1.0 \
+ --pkg pango \
--pkg unity \
--pkg unity-const \
--pkg unity-misc \
@@ -97,6 +98,7 @@ places_sources = \
places/places-place-entry-view.vala \
places/places-place-entry.vala \
places/places-place-home.vala \
+ places/places-place-home-renderer.vala \
places/places-place-model.vala \
places/places-place-view.vala \
places/places-place.vala \
@@ -105,7 +107,9 @@ places_sources = \
places/places-place-search-navigation.vala \
places/places-place-search-sections-bar.vala \
places/places-trash-controller.vala \
- places/places-view.vala
+ places/places-view.vala \
+ places/places-volume-controller.vala \
+ places/places-volume-child-controller.vala
launcher_sources = \
launcher/application-controller.vala \
diff --git a/unity-private/launcher/quicklist-check-menu-item.vala b/unity-private/launcher/quicklist-check-menu-item.vala
index 804958e9e..e503cad05 100644
--- a/unity-private/launcher/quicklist-check-menu-item.vala
+++ b/unity-private/launcher/quicklist-check-menu-item.vala
@@ -55,7 +55,9 @@ namespace Unity.Launcher
this.label,
out width,
out height);
- min_width_p = (float) width + (float) Ctk.em_to_pixel (2 * MARGIN) + 30.0f;
+ min_width_p = (float) width +
+ (float) Ctk.em_to_pixel (2 * MARGIN) +
+ ITEM_INDENT_ABS;
natural_width_p = min_width_p;
}
diff --git a/unity-private/launcher/quicklist-image-menu-item.vala b/unity-private/launcher/quicklist-image-menu-item.vala
index feb71f975..806f071b0 100644
--- a/unity-private/launcher/quicklist-image-menu-item.vala
+++ b/unity-private/launcher/quicklist-image-menu-item.vala
@@ -56,7 +56,9 @@ namespace Unity.Launcher
this.label,
out width,
out height);
- min_width_p = (float) width + (float) Ctk.em_to_pixel (2 * MARGIN);
+ min_width_p = (float) width +
+ (float) Ctk.em_to_pixel (2 * MARGIN) +
+ ITEM_INDENT_ABS;
natural_width_p = min_width_p;
}
diff --git a/unity-private/launcher/quicklist-menu-item.vala b/unity-private/launcher/quicklist-menu-item.vala
index 1c3b61ebf..0a6b62ee6 100644
--- a/unity-private/launcher/quicklist-menu-item.vala
+++ b/unity-private/launcher/quicklist-menu-item.vala
@@ -57,7 +57,9 @@ namespace Unity.Launcher
this.label,
out width,
out height);
- min_width_p = (float) width + (float) Ctk.em_to_pixel (2 * MARGIN);
+ min_width_p = (float) width +
+ (float) Ctk.em_to_pixel (2 * MARGIN) +
+ 2 * ITEM_INDENT_ABS;
natural_width_p = min_width_p;
}
diff --git a/unity-private/launcher/quicklist-radio-menu-item.vala b/unity-private/launcher/quicklist-radio-menu-item.vala
index 5a49319ba..e9b826c31 100644
--- a/unity-private/launcher/quicklist-radio-menu-item.vala
+++ b/unity-private/launcher/quicklist-radio-menu-item.vala
@@ -55,7 +55,9 @@ namespace Unity.Launcher
this.label,
out width,
out height);
- min_width_p = (float) width + (float) Ctk.em_to_pixel (2 * MARGIN) + 30.0f;
+ min_width_p = (float) width +
+ (float) Ctk.em_to_pixel (2 * MARGIN) +
+ ITEM_INDENT_ABS;
natural_width_p = min_width_p;
}
diff --git a/unity-private/launcher/quicklist-view.vala b/unity-private/launcher/quicklist-view.vala
index c2fa933a2..ce0675cfc 100644
--- a/unity-private/launcher/quicklist-view.vala
+++ b/unity-private/launcher/quicklist-view.vala
@@ -34,6 +34,7 @@ namespace Unity.Launcher
const float ITEM_HEIGHT = 2.0f;
const float ITEM_CORNER_RADIUS = 0.3f;
const float ITEM_CORNER_RADIUS_ABS = 4.0f;
+ const float ITEM_INDENT_ABS = 20.0f;
const float ANCHOR_HEIGHT = 1.5f;
const float ANCHOR_HEIGHT_ABS = 18.0f;
const float ANCHOR_WIDTH = 0.75f;
@@ -71,7 +72,7 @@ namespace Unity.Launcher
new_width = (int) (box.x2 - box.x1);
new_height = (int) (box.y2 - box.y1);
-
+
// exit early if the allocation-width/height didn't change, this is needed
// because clutter triggers calling allocate even if nothing changed
if ((this.last_width == new_width) && (this.last_height == new_height))
@@ -81,23 +82,23 @@ namespace Unity.Launcher
this.last_width = new_width;
this.last_height = new_height;
- debug ("Num Items in Menu %d \n", get_num_items ());
-
+ //debug ("Num Items in Menu %d \n", get_num_items ());
+
base.allocate (box, flags);
-
+
// float x;
// float y;
// this.get_position(out x, out y);
// this.compute_style_textures ();
// this.set_expansion_size_factor (0.0f);
// this.set_anchor_position ((int)60 + 60, (int)100+48, 25);
-//
+//
// if(get_num_items () > 1)
// this.animate (Clutter.AnimationMode.LINEAR,
// 100,
// "expansion-size-factor", 1.0f);
-
-
+
+
}
construct
diff --git a/unity-private/launcher/scroller-controller.vala b/unity-private/launcher/scroller-controller.vala
index 02fa113b0..cdd3e2ccc 100644
--- a/unity-private/launcher/scroller-controller.vala
+++ b/unity-private/launcher/scroller-controller.vala
@@ -66,6 +66,41 @@ namespace Unity.Launcher
// hook up to the drag controller
var drag_controller = Drag.Controller.get_default ();
drag_controller.drag_start.connect (on_unity_drag_start);
+
+ Unity.global_shell.notify["super-key-active"].connect (on_super_key_active);
+ Unity.global_shell.super_key_modifier_release.connect (on_super_key_modifier_release);
+ }
+
+ private void on_super_key_modifier_release (uint keycode)
+ {
+ if (!Unity.global_shell.super_key_active) return;
+ int index = (int)keycode - 10;
+ index = int.min (index, model.size - 1);
+ if (index < 0 || index > 9) return;
+
+ Unity.global_shell.super_key_active = false;
+
+ var childcontroller = get_controller_for_view (model[index]);
+ childcontroller.activate ();
+ }
+
+ uint super_key_source = 0;
+ private void on_super_key_active ()
+ {
+ if (Unity.global_shell.super_key_active && super_key_source == 0)
+ super_key_source = Timeout.add (300, () => {
+ view.enable_keyboard_selection_mode (Unity.global_shell.super_key_active);
+ return false;
+ });
+ else
+ {
+ if (super_key_source != 0)
+ {
+ Source.remove (super_key_source);
+ super_key_source = 0;
+ }
+ view.enable_keyboard_selection_mode (false);
+ }
}
private void handle_bamf_view_opened (Object object)
@@ -317,7 +352,7 @@ namespace Unity.Launcher
}
ScrollerChildController model_controller = drag_controller.get_drag_model () as ScrollerChildController;
ScrollerChild retcont = model_controller.child;
-
+
if (retcont.group_type == ScrollerChild.GroupType.PLACE ||
retcont.group_type == ScrollerChild.GroupType.SYSTEM)
{
@@ -331,9 +366,12 @@ namespace Unity.Launcher
(retcont.controller as ApplicationController).set_sticky (false);
(retcont.controller as ApplicationController).close_windows ();
}
- if (retcont in model)
- model.remove (retcont);
-
+ if (retcont in model ||
+ retcont.group_type == ScrollerChild.GroupType.DEVICE)
+ {
+ retcont.drag_removed ();
+ model.remove (retcont);
+ }
if (model_controller is ApplicationController)
{
(model_controller as ApplicationController).set_sticky (false);
diff --git a/unity-private/launcher/scroller-view.vala b/unity-private/launcher/scroller-view.vala
index a13bd7db3..c2a144887 100644
--- a/unity-private/launcher/scroller-view.vala
+++ b/unity-private/launcher/scroller-view.vala
@@ -73,6 +73,8 @@ namespace Unity.Launcher
private ScrollerPhase current_phase = ScrollerPhase.SETTLING;
private uint last_motion_event_time = 0;
private ScrollerViewType view_type = ScrollerViewType.CONTRACTED;
+ private float last_known_pointer_x = 0.0f;
+
/*
* scrolling variables
*/
@@ -91,13 +93,17 @@ namespace Unity.Launcher
private uint stored_delta = 0;
private float scroll_speed = 0.0f; // the current speed (pixels/per second) that we are scrolling
- private float contract_icon_degrees = 30.0f;
+ private float contract_icon_degrees = 70.0f;
+ private float contract_icon_partial_degrees = 30.0f;
private int focused_launcher = 0;
/* helps out with draw order */
private Gee.ArrayList<ScrollerChild> draw_ftb;
private Gee.ArrayList<ScrollerChild> draw_btf;
+ /* Key binding indicators */
+ private Gee.ArrayList<Clutter.CairoTexture> keyboard_indicators;
+
/*
* Refrence holders
*/
@@ -124,6 +130,7 @@ namespace Unity.Launcher
this.padding = mypadding;
+ keyboard_indicators = new Gee.ArrayList <Clutter.CairoTexture> ();
load_textures ();
model.child_added.connect (model_child_added);
model.child_removed.connect (model_child_removed);
@@ -141,9 +148,11 @@ namespace Unity.Launcher
button_release_event.connect (on_button_release_event);
motion_event.connect (on_motion_event);
enter_event.connect (on_enter_event);
+
leave_event.connect (on_leave_event);
notify["is-autoscrolling"].connect (on_auto_scrolling_state_change);
Unity.Drag.Controller.get_default ().drag_motion.connect (on_drag_motion_event);
+
// set a timeline for our fling animation
fling_timeline = new Clutter.Timeline (1000);
fling_timeline.loop = true;
@@ -258,6 +267,7 @@ namespace Unity.Launcher
{
var drag_controller = Drag.Controller.get_default ();
if (drag_controller.is_dragging) return false;
+ if (is_scrolling) return false;
enter_event.disconnect (on_enter_event);
leave_event.disconnect (on_leave_event);
motion_event.disconnect (on_motion_event);
@@ -278,6 +288,7 @@ namespace Unity.Launcher
{
var drag_controller = Drag.Controller.get_default ();
if (drag_controller.is_dragging) return false;
+ if (is_scrolling) return false;
enter_event.disconnect (on_enter_event);
leave_event.disconnect (on_leave_event);
@@ -296,6 +307,8 @@ namespace Unity.Launcher
{
var drag_controller = Drag.Controller.get_default ();
if (drag_controller.is_dragging) return false;
+ if (is_scrolling) return false;
+
enter_event.disconnect (on_enter_event);
leave_event.disconnect (on_leave_event);
button_release_event.disconnect (passthrough_button_release_event);
@@ -309,6 +322,52 @@ namespace Unity.Launcher
return false;
}
+ private float last_scroll_position = 0.0f;
+ public void enable_keyboard_selection_mode (bool choice)
+ {
+ if (choice)
+ last_scroll_position = scroll_position;
+
+ uint8 new_opacity = (choice) ? 0xff : 0x00;
+
+ int index = 1;
+ foreach (Clutter.CairoTexture kb_ind in keyboard_indicators)
+ {
+ kb_ind.animate (Clutter.AnimationMode.EASE_OUT_SINE, 150,
+ "opacity", new_opacity);
+ if (model.size <= index) new_opacity = 0x00;
+ index++;
+ }
+
+
+ if (!choice)
+ {
+ if (view_type != ScrollerViewType.CONTRACTED &&
+ last_known_pointer_x >= get_width ())
+ {
+ foreach (ScrollerChild child in model)
+ {
+ if (child.active)
+ {
+ focused_launcher = model.index_of (child);
+ break;
+ }
+ }
+ contract_launcher ();
+ }
+ else if (last_known_pointer_x < get_width ())
+ {
+ move_scroll_position (last_scroll_position - scroll_position);
+ }
+ }
+ else
+ {
+ expand_launcher (0);
+ }
+
+
+ }
+
public int get_model_index_at_y_pos_no_anim (float y, bool return_minus_if_fail=false)
{
SList<float?> positions = new SList<float?> ();
@@ -387,6 +446,57 @@ namespace Unity.Launcher
return ret_val;
}
+ private void draw_keyboard_indicator_cairo (Cairo.Context cr, string text)
+ {
+ double x = 0;
+ double y = 0;
+ double w = 10;
+ double h = 10;
+ double r = Ctk.em_to_pixel (1);
+
+ Gtk.Settings settings = Gtk.Settings.get_default ();
+ Pango.FontDescription desc = Pango.FontDescription.from_string (settings.gtk_font_name);
+
+ cr.select_font_face (desc.get_family (),
+ Cairo.FontSlant.NORMAL,
+ Cairo.FontWeight.NORMAL);
+ double size;
+ size = Ctk.em_to_pixel (1) * 0.9;
+ cr.set_font_size (size);
+
+
+ Cairo.TextExtents extents = Cairo.TextExtents ();
+ cr.text_extents ("2", out extents);
+
+ Cairo.TextExtents real_extents = Cairo.TextExtents ();
+ cr.text_extents (text, out extents);
+
+ double w_diff = extents.width - real_extents.width;
+ double h_diff = extents.height - real_extents.height;
+
+ w += extents.width;
+ h += extents.height;
+ cr.set_source_rgba (0.07, 0.07, 0.07, 0.8);
+
+ cr.move_to(x+r,y); // Move to A
+ cr.line_to(x+w-r,y); // Straight line to B
+ cr.curve_to(x+w,y,x+w,y,x+w,y+r); // Curve to C, Control points are both at Q
+ cr.line_to(x+w,y+h-r); // Move to D
+ cr.curve_to(x+w,y+h,x+w,y+h,x+w-r,y+h); // Curve to E
+ cr.line_to(x+r,y+h); // Line to F
+ cr.curve_to(x,y+h,x,y+h,x,y+h-r); // Curve to G
+ cr.line_to(x,y+r); // Line to H
+ cr.curve_to(x,y,x,y,x+r,y); // Curve to
+
+ cr.fill ();
+
+ //x = (extents.width - real_extents.width) / 2.0;
+ y = 0;//(extents.height - real_extents.height) / 2.0;
+ cr.set_source_rgba (1, 1, 1, 1);
+ cr.move_to (x + 5 - (real_extents.width * 0.5), y+5+extents.height);
+ cr.show_text (text);
+ }
+
/*
* private methods
*/
@@ -399,6 +509,47 @@ namespace Unity.Launcher
top_shadow = new ThemeImage ("overflow_top");
top_shadow.set_repeat (true, false);
top_shadow.set_parent (this);
+
+ var color = Clutter.Color () {
+ red = 0xff,
+ green = 0xff,
+ blue = 0xff,
+ alpha = 0xff
+ };
+
+ //!!FIXME!! these are positioned wrong, needs to know the absolute
+ // size of the resulting cario surface before creating it =\
+ int index = 1;
+ // indicator size find out activate!
+ int key_indicator_w, key_indicator_h;
+ Gtk.Settings settings = Gtk.Settings.get_default ();
+
+ Unity.QuicklistRendering.get_text_extents (settings.gtk_font_name, "2",
+ out key_indicator_w, out key_indicator_h);
+
+ key_indicator_w += 10;
+ key_indicator_h += 10;
+
+ for (; index <= 10; index++)
+ {
+ var keyboard_indicator = new Clutter.CairoTexture (key_indicator_w, key_indicator_h);
+ keyboard_indicator.set_parent (this);
+ keyboard_indicator.opacity = 0x00;
+
+ keyboard_indicator.set_surface_size (key_indicator_w, key_indicator_h);
+ keyboard_indicator.set_size (key_indicator_w, key_indicator_h);
+ keyboard_indicator.clear ();
+ {
+ Cairo.Context cr = keyboard_indicator.create ();
+
+ string ind_str = index.to_string ();
+ if (index == 10)
+ ind_str = "0";
+
+ draw_keyboard_indicator_cairo (cr, ind_str);
+ }
+ keyboard_indicators.add (keyboard_indicator);
+ }
}
// will move the scroller by the given pixels
@@ -441,6 +592,58 @@ namespace Unity.Launcher
}
+ private void expand_launcher (float absolute_y)
+ {
+ if (view_type == ScrollerViewType.EXPANDED) return;
+ view_type = ScrollerViewType.EXPANDED;
+
+ // we need to set a new scroll position
+ // get the index of the icon we are hovering over
+ if (get_total_children_height () > get_available_height ())
+ {
+ int index = get_model_index_at_y_pos (absolute_y);
+
+ // set our state to what we will end up being so we can find the correct
+ //place to be.
+ float contracted_position = model[index].position;
+ var old_scroll_position = scroll_position;
+ scroll_position = 0;
+ order_children (true);
+
+ float new_scroll_position = -(model[index].position - contracted_position);
+
+ //reset our view so that we animate cleanly to the new view
+ view_type = ScrollerViewType.CONTRACTED;
+ scroll_position = old_scroll_position;
+ order_children (true);
+
+ // and finally animate to the new view
+ view_type = ScrollerViewType.EXPANDED;
+
+ scroll_position = new_scroll_position;
+ order_children (false); // have to order twice, boo
+
+ queue_relayout ();
+ }
+ }
+
+
+ private void contract_launcher ()
+ {
+ if (view_type == ScrollerViewType.CONTRACTED) return;
+
+ foreach (ScrollerChild child in model)
+ {
+ if (child.active)
+ focused_launcher = model.index_of (child);
+ }
+
+ view_type = ScrollerViewType.CONTRACTED;
+ order_children (false);
+ queue_relayout ();
+ is_autoscrolling = false;
+ }
+
/*
* model signal connections
*/
@@ -556,60 +759,46 @@ namespace Unity.Launcher
return false;
}
+
+ uint queue_contract_launcher = 0;
private bool on_enter_event (Clutter.Event event)
{
- if (view_type == ScrollerViewType.EXPANDED) return false;
- view_type = ScrollerViewType.EXPANDED;
-
- // we need to set a new scroll position
- // get the index of the icon we are hovering over
- if (get_total_children_height () > get_available_height ())
+ if (queue_contract_launcher != 0)
{
- int index = get_model_index_at_y_pos (event.crossing.y);
-
- // set our state to what we will end up being so we can find the correct
- //place to be.
- float contracted_position = model[index].position;
- var old_scroll_position = scroll_position;
- scroll_position = 0;
- order_children (true);
-
- float new_scroll_position = -(model[index].position - contracted_position);
-
- //reset our view so that we animate cleanly to the new view
- view_type = ScrollerViewType.CONTRACTED;
- scroll_position = old_scroll_position;
- order_children (true);
-
- // and finally animate to the new view
- view_type = ScrollerViewType.EXPANDED;
+ Source.remove (queue_contract_launcher);
+ queue_contract_launcher = 0;
+ }
- scroll_position = new_scroll_position;
- order_children (false); // have to order twice, boo
+ expand_launcher (event.crossing.y);
+ return false;
+ }
- queue_relayout ();
- }
+ private bool on_queue_contract_launcher ()
+ {
+ if (queue_contract_launcher != 0)
+ contract_launcher ();
+ queue_contract_launcher = 0;
+ return false;
+ }
+ private bool do_queue_contract_launcher ()
+ {
+ queue_contract_launcher = Timeout.add (250, on_queue_contract_launcher);
return false;
}
private bool on_leave_event (Clutter.Event event)
{
- if (view_type == ScrollerViewType.CONTRACTED) return false;
+ last_known_pointer_x = 200;
+ if (is_scrolling) return false;
+ do_queue_contract_launcher ();
- foreach (ScrollerChild child in model)
+ if (last_picked_actor is Clutter.Actor &&
+ last_picked_actor != this)
{
- if (child.active)
- focused_launcher = model.index_of (child);
+ last_picked_actor.do_event (event, false);
+ last_picked_actor = null;
}
-
- view_type = ScrollerViewType.CONTRACTED;
- order_children (false);
- queue_relayout ();
- is_autoscrolling = false;
-
- if (last_picked_actor is Clutter.Actor)
- last_picked_actor.do_event (event, false);
return false;
}
@@ -948,7 +1137,7 @@ namespace Unity.Launcher
child.rotation = transitions[index].rotation;
if (do_new_position)
- child.animate (Clutter.AnimationMode.EASE_IN_OUT_QUAD,
+ child.animate (Clutter.AnimationMode.EASE_OUT_QUAD,
300,
"position", transitions[index].position
);
@@ -964,6 +1153,8 @@ namespace Unity.Launcher
float min_height, nat_height;
if (!(draw_ftb is Gee.ArrayList))
draw_ftb = new Gee.ArrayList<ScrollerChild> ();
+
+ if (!(draw_ftb is Gee.ArrayList))
draw_btf = new Gee.ArrayList<ScrollerChild> ();
foreach (ScrollerChild child in model)
@@ -973,8 +1164,8 @@ namespace Unity.Launcher
transition.position = h + scroll_position;
transition.rotation = 0.0f;
ret_transitions.add (transition);
- if (!(child in draw_ftb || child in draw_ftb))
- draw_ftb.add (child);
+ //if (!(child in draw_ftb || child in draw_ftb))
+ //draw_ftb.add (child);
h += nat_height + spacing;
}
return ret_transitions;
@@ -1037,10 +1228,9 @@ namespace Unity.Launcher
{
ScrollerChild child = model[index];
var transition = new ChildTransition ();
+ child.get_preferred_height (get_width (), out min_height, out nat_height);
if (index >= index_start_flat && index < index_end_flat)
{
-
- child.get_preferred_height (get_width (), out min_height, out nat_height);
transition.position = h;
h += nat_height + spacing;
num_children_handled++;
@@ -1054,20 +1244,38 @@ namespace Unity.Launcher
else
{
// contracted launcher
- if (index == index_end_flat) h -= spacing * 2;
+ if (index == index_end_flat) h -= nat_height * 0.3333f - spacing;//spacing * 2;
- transition.position = h;
- h += 8 + spacing;
if (num_children_handled < index_start_flat)
{
- transition.rotation = -contract_icon_degrees;
+ if (num_children_handled == index_start_flat - 1)
+ {
+ transition.rotation = -contract_icon_partial_degrees;
+ h += spacing;
+ }
+ else
+ {
+ transition.rotation = -contract_icon_degrees;
+ }
+ transition.position = h;
draw_ftb.add (child);
}
else
{
- transition.rotation = contract_icon_degrees;
+ transition.position = h;
+ if (index == index_end_flat)
+ {
+ transition.rotation = contract_icon_partial_degrees;
+ h += spacing;
+ }
+ else
+ {
+ transition.rotation = contract_icon_degrees;
+ }
draw_btf.add (child);
}
+
+ h += 8 + spacing;
num_children_handled++;
if (index +1 == index_start_flat) h += 30;
@@ -1108,6 +1316,7 @@ namespace Unity.Launcher
float available_width = box.get_width () - padding.right;
total_child_height = 0.0f;
+ uint index = 0;
foreach (ScrollerChild child in model)
{
@@ -1133,7 +1342,26 @@ namespace Unity.Launcher
total_child_height += child_height + spacing;
+
+ if (index >= 0 && index <= 9)
+ {
+ Clutter.CairoTexture? keyboard_indicator = null;
+ keyboard_indicator = keyboard_indicators[(int)index];
+
+ if (keyboard_indicator is Clutter.Actor)
+ {
+ uint surface_width, surface_height;
+ keyboard_indicator.get_surface_size (out surface_width, out surface_height);
+ child_box.x1 = box.get_width () - padding.right - surface_width - 6;
+ child_box.x2 = child_box.x1 + keyboard_indicator.get_width ();
+ child_box.y1 = child.position + padding.top + ((child_box.get_height ()*0.5f) - (surface_height*0.5f));
+ child_box.y2 = child_box.y1 + keyboard_indicator.get_height ();
+ keyboard_indicator.allocate (child_box, flags);
+ }
+
+ index += 1;
}
+ }
child_box.x1 = 0;
child_box.x2 = box.get_width ();
@@ -1202,11 +1430,28 @@ namespace Unity.Launcher
}
}
+ foreach (ScrollerChild child in model)
+ {
+ if ((child in draw_ftb) || (child in draw_btf))
+ continue;
+
+ if (child is ScrollerChild && child.opacity > 0)
+ {
+ (child as ScrollerChild).paint ();
+ }
+ }
+
+
foreach (ScrollerChild child in child_refs)
{
child.paint ();
}
+ foreach (Clutter.CairoTexture kb_ind in keyboard_indicators)
+ {
+ kb_ind.paint ();
+ }
+
top_shadow.paint ();
}
@@ -1215,10 +1460,16 @@ namespace Unity.Launcher
base.map ();
bgtex.map ();
top_shadow.map ();
+ foreach (Clutter.CairoTexture kb_ind in keyboard_indicators)
+ {
+ kb_ind.map ();
+ }
+
foreach (ScrollerChild child in model)
{
child.map ();
}
+
}
public override void unmap ()
@@ -1226,6 +1477,11 @@ namespace Unity.Launcher
base.unmap ();
bgtex.map ();
top_shadow.map ();
+ foreach (Clutter.CairoTexture kb_ind in keyboard_indicators)
+ {
+ kb_ind.paint ();
+ }
+
foreach (ScrollerChild child in model)
{
child.unmap ();
diff --git a/unity-private/launcher/scrollerchild.vala b/unity-private/launcher/scrollerchild.vala
index cc4995cca..62a6288f7 100644
--- a/unity-private/launcher/scrollerchild.vala
+++ b/unity-private/launcher/scrollerchild.vala
@@ -92,13 +92,13 @@ namespace Unity.Launcher
private Clutter.Animation running_indicator_anim;
private Clutter.Timeline wiggle_timeline;
private Clutter.Timeline glow_timeline;
- private Clutter.Timeline rotate_timeline;
private AnimState glow_state;
private AnimState wiggle_state;
- private AnimState rotate_state;
private float old_rotate_value = 0.0f;
+ public signal void drag_removed ();
+
public ScrollerChild ()
{
Object (group_type:GroupType.APPLICATION);
@@ -112,11 +112,9 @@ namespace Unity.Launcher
//icon glow
glow_timeline = new Clutter.Timeline (1);
wiggle_timeline = new Clutter.Timeline (1);
- rotate_timeline = new Clutter.Timeline (1);
glow_timeline.new_frame.connect (on_glow_timeline_new_frame);
wiggle_timeline.new_frame.connect (on_wiggle_timeline_new_frame);
- rotate_timeline.new_frame.connect (on_rotate_timeline_new_frame);
notify["rotation"].connect (on_rotation_changed);
}
@@ -184,42 +182,13 @@ namespace Unity.Launcher
}
/* animation callbacks */
- private void on_rotate_timeline_new_frame ()
- {
- float progress = (float)rotate_timeline.get_progress ();
- switch (rotate_state)
- {
- case AnimState.RISING:
- rotate_anim_rising (progress);
- break;
-
- case AnimState.STOPPED:
- rotate_timeline.stop ();
- break;
- }
- processed_icon.do_queue_redraw ();
- }
-
- private void rotate_anim_rising (float progress)
- {
- progress = get_ease_out_sine (progress);
- var diff = rotation - old_rotate_value;
- float rotate_val = old_rotate_value + (progress * diff);
-
- processed_icon.rotation = rotate_val;
- if (progress >= 1.0)
- {
- rotate_state = AnimState.STOPPED;
- rotate_timeline.stop ();
- }
- }
-
public void force_rotation_jump (float degrees)
{
+ if (processed_icon.get_animation () is Clutter.Animation)
+ processed_icon.get_animation ().completed ();
+
processed_icon.rotation = degrees;
rotation = degrees;
- rotate_state = AnimState.STOPPED;
- rotate_timeline.stop ();
do_queue_redraw ();
}
@@ -455,18 +424,12 @@ namespace Unity.Launcher
{
old_rotate_value = processed_icon.rotation;
- if (rotate_timeline is Clutter.Timeline == false)
- return;
-
- if (rotate_timeline.is_playing ())
- {
- rotate_timeline.stop ();
- processed_icon.rotation = old_rotate_value;
- }
+ if (processed_icon.get_animation () is Clutter.Animation)
+ processed_icon.get_animation ().completed ();
- rotate_timeline.set_duration (300);
- rotate_state = AnimState.RISING;
- rotate_timeline.start ();
+ processed_icon.rotation = old_rotate_value;
+ processed_icon.animate (Clutter.AnimationMode.EASE_OUT_QUINT, 300,
+ "rotation", rotation);
}
private void on_activating_changed ()
@@ -487,7 +450,6 @@ namespace Unity.Launcher
blue = 255,
alpha = 255
};
- effect_icon_glow.set_background_texture (honeycomb_mask);
effect_icon_glow.set_color (c);
effect_icon_glow.set_opacity (1.0f);
processed_icon.add_effect (effect_icon_glow);
diff --git a/unity-private/panel/panel-home-button.vala b/unity-private/panel/panel-home-button.vala
index 3bb08298b..d36abb29d 100644
--- a/unity-private/panel/panel-home-button.vala
+++ b/unity-private/panel/panel-home-button.vala
@@ -95,8 +95,8 @@ namespace Unity.Panel
warning ("Could not load active-state bg-texture: %s", e.message);
}
- //set_background_for_state (Ctk.ActorState.STATE_NORMAL, bfb_bg_normal);
- //set_background_for_state (Ctk.ActorState.STATE_PRELIGHT, bfb_bg_prelight);
+ set_background_for_state (Ctk.ActorState.STATE_NORMAL, bfb_bg_normal);
+ set_background_for_state (Ctk.ActorState.STATE_PRELIGHT, bfb_bg_prelight);
set_background_for_state (Ctk.ActorState.STATE_ACTIVE, bfb_bg_active);
search_shown = false;
@@ -186,8 +186,8 @@ namespace Unity.Panel
{
if (mode == ShellMode.MINIMIZED)
{
- //set_background_for_state (Ctk.ActorState.STATE_NORMAL, bfb_bg_normal);
- //set_background_for_state (Ctk.ActorState.STATE_PRELIGHT, bfb_bg_prelight);
+ set_background_for_state (Ctk.ActorState.STATE_NORMAL, bfb_bg_normal);
+ set_background_for_state (Ctk.ActorState.STATE_PRELIGHT, bfb_bg_prelight);
set_background_for_state (Ctk.ActorState.STATE_ACTIVE, bfb_bg_active);
search_shown = false;
}
diff --git a/unity-private/panel/panel-indicator-object-entry-view.vala b/unity-private/panel/panel-indicator-object-entry-view.vala
index 35d2f9fc3..f24ce0a3b 100644
--- a/unity-private/panel/panel-indicator-object-entry-view.vala
+++ b/unity-private/panel/panel-indicator-object-entry-view.vala
@@ -82,6 +82,12 @@ namespace Unity.Panel.Indicators
image.size = entry.image.pixbuf.width;
}
+ if (entry.image.gicon is GLib.Icon)
+ {
+ image.gicon = entry.image.gicon;
+ image.size = 22;
+ }
+
if ((entry.image.get_flags () & Gtk.WidgetFlags.VISIBLE) != 0)
{
image.show ();
@@ -125,6 +131,15 @@ namespace Unity.Panel.Indicators
}
});
+ entry.image.notify["gicon"].connect (() =>
+ {
+ if (image.gicon is GLib.Icon)
+ {
+ image.gicon = entry.image.gicon;
+ image.size = 22;
+ }
+ });
+
unowned Gtk.IconTheme theme = Gtk.IconTheme.get_default ();
theme.changed.connect (() =>
{
@@ -138,11 +153,12 @@ namespace Unity.Panel.Indicators
text.color = { 233, 216, 200, 255 };
add_actor (text);
- text.text = entry.label.label;
+ /* FIXME: What about the __ case? Well, should that me in a menu? */
+ text.text = entry.label.label.replace ("_", "");
entry.label.notify["label"].connect (() =>
{
- text.text = entry.label.label;
+ text.text = entry.label.label.replace ("_", "");
});
if ((entry.label.get_flags () & Gtk.WidgetFlags.VISIBLE) != 0)
diff --git a/unity-private/panel/panel-tray.vala b/unity-private/panel/panel-tray.vala
index 41a727fd8..c3a6a9ae0 100644
--- a/unity-private/panel/panel-tray.vala
+++ b/unity-private/panel/panel-tray.vala
@@ -57,7 +57,19 @@ namespace Unity.Panel
string? disable_tray = Environment.get_variable ("UNITY_DISABLE_TRAY");
if (disable_tray == null)
- this.manager.manage_stage (this.stage);
+ {
+ Gdk.error_trap_push ();
+
+ this.manager.manage_stage (this.stage);
+ Gdk.flush ();
+
+ int err = 0;
+ if ((err = Gdk.error_trap_pop ()) != 0)
+ {
+ warning ("Unable to connect to the system tray: Error code: %d",
+ err);
+ }
+ }
return false;
}
diff --git a/unity-private/panel/panel-window-buttons.vala b/unity-private/panel/panel-window-buttons.vala
index 053bd941f..0f399409d 100644
--- a/unity-private/panel/panel-window-buttons.vala
+++ b/unity-private/panel/panel-window-buttons.vala
@@ -25,7 +25,6 @@ namespace Unity.Panel
private Ctk.Text appname;
private WindowButton close;
private WindowButton minimize;
- private WindowButton maximize;
private WindowButton unmaximize;
private unowned Bamf.Matcher matcher;
@@ -47,28 +46,21 @@ namespace Unity.Panel
appname.max_length = 9;
pack (appname, true, true);
- close = new WindowButton ("close.png");
+ close = new WindowButton ("close");
pack (close, false, false);
close.clicked.connect (() => {
if (last_xid > 0)
global_shell.do_window_action (last_xid, WindowAction.CLOSE);
});
- minimize = new WindowButton ("minimize.png");
+ minimize = new WindowButton ("minimize");
pack (minimize, false, false);
minimize.clicked.connect (() => {
if (last_xid > 0)
global_shell.do_window_action (last_xid, WindowAction.MINIMIZE);
});
- maximize = new WindowButton ("maximize.png");
- pack (maximize, false, false);
- maximize.clicked.connect (() => {
- if (last_xid > 0)
- global_shell.do_window_action (last_xid, WindowAction.MAXIMIZE);
- });
-
- unmaximize = new WindowButton ("unmaximize.png");
+ unmaximize = new WindowButton ("unmaximize");
pack (unmaximize, false, false);
unmaximize.clicked.connect (() => {
if (last_xid > 0)
@@ -91,6 +83,13 @@ namespace Unity.Panel
return false;
});
});
+
+ Idle.add (() => {
+ unowned Bamf.Window? win = matcher.get_active_window ();
+ on_active_window_changed (null, win as GLib.Object);
+
+ return false;
+ });
}
private void on_active_window_changed (GLib.Object? object,
@@ -98,6 +97,13 @@ namespace Unity.Panel
{
unowned Bamf.View? new_view = object1 as Bamf.View;
+ appname.set_markup ("");
+ appname.hide ();
+ close.hide ();
+ minimize.hide ();
+ unmaximize.hide ();
+ last_xid = 0;
+
if (new_view is Bamf.Window)
{
unowned Bamf.Window win = new_view as Bamf.Window;
@@ -113,7 +119,6 @@ namespace Unity.Panel
appname.hide ();
close.show ();
minimize.show ();
- maximize.hide ();
unmaximize.show ();
}
else
@@ -121,7 +126,6 @@ namespace Unity.Panel
appname.show ();
close.hide ();
minimize.hide ();
- maximize.hide ();
unmaximize.hide ();
}
@@ -136,7 +140,11 @@ namespace Unity.Panel
AppInfo? info = appinfo.lookup (app.get_desktop_file ());
if (info != null)
- appname.set_markup (FORMAT.printf (info.get_display_name ()));
+ {
+ string display_name = info.get_display_name ();
+ display_name = display_name.split (" ")[0];
+ appname.set_markup (FORMAT.printf (display_name));
+ }
else
appname.set_markup (FORMAT.printf (win.get_name ()));
}
@@ -145,15 +153,6 @@ namespace Unity.Panel
appname.set_markup (FORMAT.printf (win.get_name ()));
}
}
- else
- {
- appname.hide ();
- close.hide ();
- minimize.hide ();
- maximize.hide ();
- unmaximize.hide ();
- last_xid = 0;
- }
}
private override void get_preferred_width (float for_height,
@@ -168,10 +167,15 @@ namespace Unity.Panel
public class WindowButton : Ctk.Button
{
public static const string AMBIANCE = "/usr/share/themes/Ambiance/metacity-1";
+ public static const string AMBIANCE_BETA = "/usr/share/themes/Ambiance-maverick-beta/metacity-1";
public string filename { get; construct; }
public Clutter.Actor bg;
+ private bool using_beta = false;
+ private int icon_size = 18;
+ private string directory = AMBIANCE;
+
public WindowButton (string filename)
{
Object (filename:filename);
@@ -179,40 +183,46 @@ namespace Unity.Panel
construct
{
+ if (using_beta = FileUtils.test (AMBIANCE_BETA, FileTest.EXISTS))
+ {
+ icon_size = 19;
+ directory = AMBIANCE_BETA;
+ }
try {
+ bg = new Ctk.Image.from_filename (icon_size,
+ directory +
+ "/" +
+ filename +
+ ".png");
+ set_background_for_state (Ctk.ActorState.STATE_NORMAL, bg);
+ bg.show ();
- bg = new Ctk.Image.from_filename (20, AMBIANCE + "/" + filename);
- add_actor (bg);
+ bg = new Ctk.Image.from_filename (icon_size,
+ directory +
+ "/" +
+ filename +
+ "_focused_prelight.png");
+ set_background_for_state (Ctk.ActorState.STATE_PRELIGHT, bg);
+ bg.show ();
+
+ bg = new Ctk.Image.from_filename (icon_size,
+ directory +
+ "/" +
+ filename +
+ "_focused_pressed.png");
+ set_background_for_state (Ctk.ActorState.STATE_ACTIVE, bg);
bg.show ();
} catch (Error e) {
warning (@"Unable to load window button theme: You need Ambiance installed: $(e.message)");
}
-
- notify["state"].connect (() => {
- switch (state)
- {
- case Ctk.ActorState.STATE_NORMAL:
- bg.opacity = 255;
- break;
-
- case Ctk.ActorState.STATE_PRELIGHT:
- bg.opacity = 120;
- break;
-
- case Ctk.ActorState.STATE_ACTIVE:
- default:
- bg.opacity = 50;
- break;
- }
- });
}
private override void get_preferred_width (float for_height,
out float min_width,
out float nat_width)
{
- min_width = 20.0f;
+ min_width = icon_size;
nat_width = min_width;
}
@@ -220,7 +230,7 @@ namespace Unity.Panel
out float min_height,
out float nat_height)
{
- min_height = 18.0f;
+ min_height = icon_size;
nat_height = min_height;
}
}
diff --git a/unity-private/places/places-controller.vala b/unity-private/places/places-controller.vala
index 650c3f29f..415fb90b9 100644
--- a/unity-private/places/places-controller.vala
+++ b/unity-private/places/places-controller.vala
@@ -29,8 +29,9 @@ namespace Unity.Places
* This class takes care of reading in the places, creating the view and
* keeping it up-to-date
**/
- public Shell shell { get; construct; }
- public PlaceModel model { get; set; }
+ public Shell shell { get; construct; }
+ public PlaceModel model { get; set; }
+ public VolumeController volumes { get; set; }
private View view;
@@ -49,6 +50,8 @@ namespace Unity.Places
on_entry_added (e);
});
+ volumes = new VolumeController ();
+
ScrollerModel s = ObjectRegistry.get_default ().lookup ("UnityScrollerModel")[0] as ScrollerModel;
/* Add the Trash launcher icon */
@@ -63,7 +66,7 @@ namespace Unity.Places
return view;
}
- public void activate_entry (string entry_name)
+ public void activate_entry (string entry_name, int section_id = 0)
{
foreach (Place place in model)
{
@@ -71,13 +74,33 @@ namespace Unity.Places
{
if (entry.name == entry_name)
{
- view.on_entry_view_activated (entry, 0);
+ view.on_entry_view_activated (entry, section_id);
break;
}
}
}
}
+ public void activate_entry_by_dbus_path (string entry_path,
+ int section_id = 0)
+ {
+ foreach (Place place in model)
+ {
+ foreach (PlaceEntry ent in place.get_entries ())
+ {
+ if (ent is PlaceEntryDbus)
+ {
+ unowned PlaceEntryDbus entry = ent as PlaceEntryDbus;
+ if (entry.dbus_path == entry_path)
+ {
+ view.on_entry_view_activated (entry, section_id);
+ break;
+ }
+ }
+ }
+ }
+ }
+
private void on_entry_added (PlaceEntry entry)
{
ScrollerModel s = ObjectRegistry.get_default ().lookup ("UnityScrollerModel")[0] as ScrollerModel;
diff --git a/unity-private/places/places-default-renderer-group.vala b/unity-private/places/places-default-renderer-group.vala
index 3ad8ce78d..f757a82ba 100644
--- a/unity-private/places/places-default-renderer-group.vala
+++ b/unity-private/places/places-default-renderer-group.vala
@@ -32,11 +32,12 @@ namespace Unity.Places
public Dee.Model results { get; construct; }
private Ctk.VBox vbox;
+ private Ctk.Button title_button;
private Ctk.HBox title_box;
private Ctk.Image icon;
private Ctk.Text text;
- private Ctk.Image expander;
- private Clutter.Actor sep;
+ private Expander expander;
+ private Ctk.Button sep;
private Ctk.IconView renderer;
private MoreResultsButton? more_results_button;
@@ -77,11 +78,32 @@ namespace Unity.Places
vbox.homogeneous = false;
add_actor (vbox);
vbox.show ();
+
+ title_button = new Ctk.Button (Ctk.Orientation.HORIZONTAL);
+ title_button.padding = { 4.0f, 6.0f, 4.0f, 6.0f };
+ vbox.pack (title_button, false, false);
+ title_button.show ();
+ var title_bg = new StripeTexture (null);
+ title_button.set_background_for_state (Ctk.ActorState.STATE_PRELIGHT,
+ title_bg);
+ title_button.notify["state"].connect (() => {
+ if (title_button.state == Ctk.ActorState.STATE_PRELIGHT)
+ sep.opacity = 0;
+ else
+ sep.opacity = 255;
+ unowned GLib.SList<unowned Ctk.Effect> effects = title_button.get_effects ();
+ foreach (unowned Ctk.Effect effect in effects)
+ effect.set_invalidate_effect_cache (true);
+ });
+ var glow = new Ctk.EffectGlow ();
+ glow.set_factor (1.0f);
+ glow.set_margin (3);
+ //title_button.add_effect (glow);
+
title_box = new Ctk.HBox (5);
- vbox.pack (title_box, false, false);
+ title_button.add_actor (title_box);
title_box.show ();
- title_box.reactive = true;
icon = new Ctk.Image (22);
icon.set_from_filename (Config.PKGDATADIR + "/favourites.png");
@@ -89,37 +111,42 @@ namespace Unity.Places
icon.show ();
text = new Ctk.Text (display_name);
- title_box.pack (text, true, true);
+ text.set_markup ("<big>" + display_name + "</big>");
+ title_box.pack (text, false, false);
text.show ();
- expander = new Ctk.Image (22);
- expander.set_from_filename (Config.PKGDATADIR + "/maximize_up.png");
+ expander = new Expander ();
expander.opacity = 0;
title_box.pack (expander, false, true);
expander.show ();
- sep = new Clutter.Rectangle.with_color ({ 255, 255, 255, 255 });
- sep.height = 1;
+ sep = new Ctk.Button (Ctk.Orientation.HORIZONTAL);
+ var rect = new Clutter.Rectangle.with_color ({ 255, 255, 255, 100 });
+ sep.add_actor (rect);
+ rect.height = 1.0f;
vbox.pack (sep, false, false);
sep.show ();
+ glow = new Ctk.EffectGlow ();
+ glow.set_factor (1.0f);
+ glow.set_margin (5);
+ //sep.add_effect (glow);
- title_box.button_release_event.connect (() => {
+ title_button.clicked.connect (() => {
if (n_results <= renderer.get_n_cols () || allow_expand == false)
- return true;
+ return;
if (bin_state == ExpandingBinState.UNEXPANDED)
{
bin_state = ExpandingBinState.EXPANDED;
- expander.set_from_filename (Config.PKGDATADIR + "/minimize_up.png");
+ expander.expanding_state = Expander.State.EXPANDED;
}
else
{
bin_state = ExpandingBinState.UNEXPANDED;
- expander.set_from_filename (Config.PKGDATADIR + "/maximize_up.png");
+ expander.expanding_state = Expander.State.UNEXPANDED;
}
- return true;
});
- title_box.motion_event.connect (() => {
+ title_button.motion_event.connect (() => {
if (dirty && allow_expand)
{
var children = renderer.get_children ();
@@ -130,6 +157,8 @@ namespace Unity.Places
}
dirty = false;
}
+
+ return false;
});
renderer = new Ctk.IconView ();
@@ -172,7 +201,7 @@ namespace Unity.Places
}
else if (group_renderer == "UnityFolderGroupRenderer")
{
- title_box.hide ();
+ title_button.hide ();
sep.hide ();
bin_state = ExpandingBinState.EXPANDED;
}
@@ -207,7 +236,7 @@ namespace Unity.Places
child.height != unexpanded_height)
{
var h = more_results_button != null ? more_results_button.height : 0;
- unexpanded_height = title_box.height + 1.0f + child.height + h;
+ unexpanded_height = title_button.height + 1.0f + child.height + h;
}
}
@@ -344,6 +373,104 @@ namespace Unity.Places
}
}
+ public class Expander : Ctk.Bin
+ {
+ public enum State
+ {
+ EXPANDED,
+ UNEXPANDED
+ }
+
+ private float arrow_size = 12.0f;
+ private float arrow_quart = 3.0f;
+
+ private CairoCanvas arrow;
+
+ public State expanding_state {
+ get { return _state; }
+ set {
+ if (_state != value)
+ {
+ _state = value;
+ arrow.update ();
+ }
+ }
+ }
+
+ private State _state = State.UNEXPANDED;
+
+ public Expander ()
+ {
+ Object ();
+ }
+
+ construct
+ {
+ arrow = new CairoCanvas (paint_arrow);
+ add_actor (arrow);
+ arrow.show ();
+ }
+
+ private override void allocate (Clutter.ActorBox box,
+ Clutter.AllocationFlags flags)
+ {
+ Clutter.ActorBox child_box = Clutter.ActorBox ();
+
+ base.allocate (box, flags);
+
+ child_box.x1 = ((box.x2 - box.x1)/2.0f) - arrow_quart *2;
+ child_box.x2 = child_box.x1 + arrow_size;
+ child_box.y1 = ((box.y2 - box.y1)/2.0f) - arrow_quart *2;
+ child_box.y2 = child_box.y1 + arrow_size;
+
+ arrow.allocate (child_box, flags);
+ }
+
+ private override void get_preferred_height (float for_width,
+ out float mheight,
+ out float nheight)
+ {
+ mheight = arrow_size;
+ nheight = arrow_size;
+ }
+
+ private override void get_preferred_width (float for_height,
+ out float mwidth,
+ out float nwidth)
+ {
+ mwidth = arrow_size;
+ nwidth = arrow_size;
+ }
+
+ private void paint_arrow (Cairo.Context cr, int width, int height)
+ {
+ cr.set_operator (Cairo.Operator.CLEAR);
+ cr.paint ();
+
+ cr.set_operator (Cairo.Operator.OVER);
+ cr.set_line_width (1.0f);
+ cr.translate (-0.5, -0.5);
+ cr.set_source_rgba (1.0f, 1.0f, 1.0f, 1.0f);
+
+ if (_state == State.UNEXPANDED)
+ {
+ cr.move_to (arrow_quart, arrow_quart);
+ cr.line_to (arrow_size - arrow_quart, arrow_size/2.0f);
+ cr.line_to (arrow_quart, arrow_size - arrow_quart);
+ cr.close_path ();
+ }
+ else
+ {
+ cr.move_to (arrow_quart, arrow_quart);
+ cr.line_to (arrow_size - arrow_quart, arrow_quart);
+ cr.line_to (arrow_size /2.0f, arrow_size - arrow_quart);
+ cr.close_path ();
+ }
+
+ cr.fill ();
+ }
+ }
+
public class MoreResultsButton : Ctk.Button
{
public uint count {
@@ -367,7 +494,7 @@ namespace Unity.Places
construct
{
- var bg = new CairoCanvas (paint_bg);
+ var bg = new StripeTexture (paint_bg);
set_background (bg);
text = new Ctk.Text ("");
@@ -398,17 +525,10 @@ namespace Unity.Places
float nwidth;
text.get_preferred_width (height, null, out nwidth);
- cr.translate (0.5, 0.5);
cr.rectangle (0.0,
vpad,
hpad + nwidth + hpad,
height - vpad - vpad);
- cr.set_source_rgba (1.0, 1.0, 1.0, 0.2);
- cr.fill_preserve ();
-
- cr.set_line_width (1.5);
- cr.set_source_rgba (1.0, 1.0, 1.0, 0.5);
- cr.stroke ();
}
}
diff --git a/unity-private/places/places-default-renderer.vala b/unity-private/places/places-default-renderer.vala
index ecbd9fb25..77fa0bdea 100644
--- a/unity-private/places/places-default-renderer.vala
+++ b/unity-private/places/places-default-renderer.vala
@@ -67,14 +67,33 @@ namespace Unity.Places
private void on_group_added (Dee.Model model, Dee.ModelIter iter)
{
- var group = new DefaultRendererGroup (model.get_position (iter),
- model.get_string (iter, 0),
- model.get_string (iter, 1),
- model.get_string (iter, 2),
+ string renderer = model.get_string (iter, 0);
+
+ if (renderer == "UnityEmptySearchRenderer")
+ {
+ var group = new EmptySearchGroup (model.get_position (iter),
results_model);
- group.activated.connect ((u, m) => { activated (u, m); } );
- group.set_data<unowned Dee.ModelIter> ("model-iter", iter);
- box.pack (group, false, true);
+ box.pack (group, false, true);
+ group.activated.connect ((u, m) => { activated (u, m); } );
+
+ }
+ else if (renderer == "UnityEmptySectionRenderer")
+ {
+ var group = new EmptrySectionGroup (model.get_position (iter),
+ results_model);
+ box.pack (group, false, true);
+ }
+ else
+ {
+ var group = new DefaultRendererGroup (model.get_position (iter),
+ model.get_string (iter, 0),
+ model.get_string (iter, 1),
+ model.get_string (iter, 2),
+ results_model);
+ group.activated.connect ((u, m) => { activated (u, m); } );
+ group.set_data<unowned Dee.ModelIter> ("model-iter", iter);
+ box.pack (group, false, true);
+ }
}
private void on_group_removed (Dee.Model model, Dee.ModelIter iter)
@@ -91,5 +110,147 @@ namespace Unity.Places
}
}
}
+
+ public class EmptySearchGroup : ExpandingBin
+ {
+ public uint group_id { get; construct set; }
+
+ public Dee.Model results { get; construct set; }
+
+ public signal void activated (string uri, string mimetype);
+
+ private Ctk.VBox box;
+
+ public EmptySearchGroup (uint group_id, Dee.Model results)
+ {
+ Object (group_id:group_id, results:results);
+ }
+
+ construct
+ {
+ bin_state = ExpandingBinState.CLOSED;
+ unexpanded_height = 0.0f;
+
+ var hbox = new Ctk.HBox (0);
+ add_actor (hbox);
+ hbox.show ();
+
+ box = new Ctk.VBox (12);
+ hbox.pack (box, false, false);
+ box.show ();
+
+ results.row_added.connect (on_result_added);
+ results.row_removed.connect (on_result_removed);
+
+ opacity = 0;
+ }
+
+ private void on_result_added (Dee.ModelIter iter)
+ {
+ if (!interesting (iter))
+ return;
+
+ bin_state = ExpandingBinState.EXPANDED;
+
+ string mes = results.get_string (iter, 4);
+
+ var button = new Ctk.Button (Ctk.Orientation.HORIZONTAL);
+ button.padding = { 12.0f, 12.0f, 12.0f, 12.0f };
+ var text = new Ctk.Text ("");
+ text.set_markup ("<big>" + mes + "</big>");
+ button.add_actor (text);
+
+ box.pack (button, false, false);
+
+ if (box.get_children ().length () >= 2)
+ {
+ var bg = new StripeTexture (null);
+ button.set_background (bg);
+
+ string uri = results.get_string (iter, 0);
+ string mimetype = results.get_string (iter, 3);
+
+ button.clicked.connect (() => { activated (uri, mimetype); });
+ }
+ }
+
+ private void on_result_removed (Dee.ModelIter iter)
+ {
+ if (!interesting (iter))
+ return;
+
+ var children = box.get_children ();
+ foreach (Clutter.Actor child in children)
+ {
+ box.remove_actor (child);
+ }
+
+ bin_state = ExpandingBinState.CLOSED;
+ }
+
+ private bool interesting (Dee.ModelIter iter)
+ {
+ return (results.get_uint (iter, 2) == group_id);
+ }
+ }
+
+
+ public class EmptrySectionGroup : ExpandingBin
+ {
+ public uint group_id { get; construct set; }
+
+ private Ctk.Text text;
+ public Dee.Model results { get; construct set; }
+
+ public signal void activated (string uri, string mimetype);
+
+ public EmptrySectionGroup (uint group_id, Dee.Model results)
+ {
+ Object (group_id:group_id, results:results);
+ }
+
+ construct
+ {
+ bin_state = ExpandingBinState.CLOSED;
+ unexpanded_height = 0.0f;
+
+ padding = { 100.0f, 0.0f, 0.0f, 0.0f };
+
+ text = new Ctk.Text ("");
+ text.set_alignment (Pango.Alignment.CENTER);
+
+ add_actor (text);
+ text.show ();
+
+ results.row_added.connect (on_result_added);
+ results.row_removed.connect (on_result_removed);
+
+ opacity = 0;
+ }
+
+ private void on_result_added (Dee.ModelIter iter)
+ {
+ if (!interesting (iter))
+ return;
+
+ bin_state = ExpandingBinState.EXPANDED;
+
+ string mes = results.get_string (iter, 4);
+ text.set_markup ("<big>" + mes + "</big>");
+ }
+
+ private void on_result_removed (Dee.ModelIter iter)
+ {
+ if (!interesting (iter))
+ return;
+
+ bin_state = ExpandingBinState.CLOSED;
+ }
+
+ private bool interesting (Dee.ModelIter iter)
+ {
+ return (results.get_uint (iter, 2) == group_id);
+ }
+ }
}
diff --git a/unity-private/places/places-place-home-renderer.vala b/unity-private/places/places-place-home-renderer.vala
new file mode 100644
index 000000000..360a5e269
--- /dev/null
+++ b/unity-private/places/places-place-home-renderer.vala
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2010 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+namespace Unity.Places
+{
+ public class HomeRenderer : Ctk.Bin, Unity.Place.Renderer
+ {
+ static const int SPACING = 60;
+ static const string FILES_PLACE = "/com/canonical/unity/filesplace/files";
+ static const string APPS_PLACE = "/com/canonical/unity/applicationsplace/applications";
+
+ private Gtk.IconTheme? theme = null;
+ private Ctk.IconView icon_view;
+
+ public HomeRenderer ()
+ {
+ Object ();
+ }
+
+ construct
+ {
+ padding = { 0.0f, 0.0f, 0.0f, 0.0f };
+ icon_view = new Ctk.IconView ();
+ icon_view.spacing = SPACING;
+ add_actor (icon_view);
+ icon_view.show ();
+
+ /* Load up the world */
+ var icon = new HomeButton (_("Web"), filename_for_icon ("web"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ var client = GConf.Client.get_default ();
+ try {
+ var exec = client.get_string ("/desktop/gnome/applications/browser/exec");
+ if (exec != null)
+ Process.spawn_command_line_async (exec);
+ } catch (Error e) {
+ warning (@"Unable to start web browser: $(e.message)");
+ }
+
+ global_shell.hide_unity ();
+
+ });
+
+ icon = new HomeButton (_("Music"), filename_for_icon ("music"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ activate_place (APPS_PLACE, 4);
+ });
+
+ icon = new HomeButton (_("Photos & Videos"), filename_for_icon ("photos"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ activate_place (APPS_PLACE, 4);
+ });
+
+ icon = new HomeButton (_("Games"), filename_for_icon ("games"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ activate_place (APPS_PLACE, 2);
+ });
+
+ icon = new HomeButton (_("Email & Chat"), filename_for_icon ("email_and_chat"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ activate_place (APPS_PLACE, 3);
+ });
+
+ icon = new HomeButton (_("Office"), filename_for_icon ("work"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ activate_place (APPS_PLACE, 5);
+ });
+
+ icon = new HomeButton (_("Files & Folders"), filename_for_icon ("work"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ activate_place (FILES_PLACE, 0);
+ });
+
+ icon = new HomeButton (_("Get New Apps"), filename_for_icon ("softwarecentre"), "");
+ icon_view.add_actor (icon);
+ icon.show ();
+ icon.clicked.connect (() => {
+ try {
+ Process.spawn_command_line_async ("software-center");
+ } catch (Error e) {
+ warning (@"Unable to start software centre: $(e.message)");
+ }
+ global_shell.hide_unity ();
+
+ });
+
+ }
+
+ public void set_models (Dee.Model groups,
+ Dee.Model results,
+ Gee.HashMap<string, string> hints)
+ {
+
+ }
+
+ /*
+ * Private Methods
+ */
+ private void activate_place (string place_path, int section_id)
+ {
+ /* FIXME:!!!
+ * This is not the way we'll end up doing this. This is a stop-gap
+ * until we have better support for signalling things through
+ * a place
+ */
+ Controller cont = Testing.ObjectRegistry.get_default ().lookup ("UnityPlacesController")[0] as Controller;
+
+ if (cont is Controller)
+ {
+ cont.activate_entry_by_dbus_path (place_path, section_id);
+ }
+ }
+
+ private override void allocate (Clutter.ActorBox box,
+ Clutter.AllocationFlags flags)
+ {
+ base.allocate (box, flags);
+ float icon_width;
+ float icon_height;
+
+ var children = icon_view.get_children ();
+ var child = children.nth_data (0) as Clutter.Actor;
+ child.get_preferred_size (out icon_width, null,
+ out icon_height, null);
+
+ float left = (box.x2 - box.x1 - (3 * SPACING) - (4 * icon_width))/2.0f;
+ float top = (box.y2 - box.y1 - (1 * SPACING) - (2 * icon_height))/2.0f;
+ top -= SPACING /2.0f;
+
+ Clutter.ActorBox child_box = Clutter.ActorBox ();
+ child_box.x1 = left;
+ child_box.x2 = box.x2 - box.x1;
+ child_box.y1 = top;
+ child_box.y2 = box.y2 - box.y1;
+
+ icon_view.allocate (child_box, flags);
+ }
+
+ private string filename_for_icon (string icon)
+ {
+ if (theme == null)
+ {
+ theme = new Gtk.IconTheme ();
+ theme.set_custom_theme ("unity-icon-theme");
+ }
+
+ string icon_file = "";
+ if (theme.has_icon (icon))
+ {
+ var info = theme.lookup_icon (icon, 128, 0);
+ if (info != null)
+ {
+ var filename = info.get_filename ();
+ if (FileUtils.test(filename, FileTest.IS_REGULAR))
+ {
+ icon_file = filename;
+ }
+ }
+
+ }
+
+ return icon_file;
+ }
+ }
+
+ public class HomeButton : Ctk.Button
+ {
+ static const int ICON_SIZE = 128;
+
+ public new string name { get; construct; }
+ public string icon { get; construct; }
+ public string exec { get; construct; }
+
+ public HomeButton (string name, string icon, string exec)
+ {
+ Object (name:name,
+ icon:icon,
+ exec:exec,
+ orientation:Ctk.Orientation.VERTICAL);
+ }
+
+ construct
+ {
+ get_image ().size = 128;
+ get_image ().filename = icon;
+ get_text ().text = name;
+ }
+
+
+ private override void get_preferred_width (float for_height,
+ out float mwidth,
+ out float nwidth)
+ {
+ mwidth = ICON_SIZE;
+ nwidth = ICON_SIZE;
+ }
+/*
+ private override void get_preferred_width (float for_width,
+ out float mheight,
+ out float nheight)
+ {
+
+ }*/
+ }
+}
diff --git a/unity-private/places/places-place-home.vala b/unity-private/places/places-place-home.vala
index b29f13a6e..a73c49049 100644
--- a/unity-private/places/places-place-home.vala
+++ b/unity-private/places/places-place-home.vala
@@ -153,14 +153,30 @@ namespace Unity.Places
public void set_search (string search, HashTable<string, string> hints)
{
- debug ("Global search %s", search);
+ var old_renderer = entry_renderer_name;
- foreach (Gee.Map.Entry<PlaceEntry, uint> e in entry_group_map.entries)
+ if (search == "" || search == null)
{
- PlaceEntry? entry = e.key;
+ entry_renderer_name = "UnityHomeScreen";
+ }
+ else
+ {
+ entry_renderer_name = "UnityDefaultRenderer";
+
+ foreach (Gee.Map.Entry<PlaceEntry, uint> e in entry_group_map.entries)
+ {
+ PlaceEntry? entry = e.key;
- if (entry != null)
- entry.set_global_search (search, hints);
+ if (entry != null)
+ entry.set_global_search (search, hints);
+ }
+ }
+
+ debug (@"$entry_renderer_name, $search");
+ if (old_renderer != entry_renderer_name)
+ {
+ updated ();
+ renderer_info_changed ();
}
}
diff --git a/unity-private/places/places-place-model.vala b/unity-private/places/places-place-model.vala
index 9e4c47dc0..250dde3df 100644
--- a/unity-private/places/places-place-model.vala
+++ b/unity-private/places/places-place-model.vala
@@ -25,7 +25,7 @@ namespace Unity.Places
* Contains the loaded Place objects. Abstract class so views can be
* tested with fake model
**/
- public abstract class PlaceModel : Gee.ArrayList<Place>
+ public abstract class PlaceModel : Gee.ArrayList<unowned Place>
{
public signal void place_added (Place place);
}
diff --git a/unity-private/places/places-place-search-bar.vala b/unity-private/places/places-place-search-bar.vala
index 1d127cf19..3addbf12b 100644
--- a/unity-private/places/places-place-search-bar.vala
+++ b/unity-private/places/places-place-search-bar.vala
@@ -21,7 +21,7 @@ namespace Unity.Places
{
public class PlaceSearchBar : Ctk.Box
{
- static const int SPACING = 10;
+ static const int SPACING = 12;
static const int RANDOM_TEXT_WIDTH = 400;
/* Properties */
@@ -136,7 +136,12 @@ namespace Unity.Places
bg.entry_position = x;
sections.set_active_entry (entry);
if (section != 0)
- sections.set_active_section (section);
+ {
+ Idle.add (() => {
+ sections.set_active_section (section);
+ return false;
+ });
+ }
navigation.set_active_entry (entry);
this.entry.text.grab_key_focus ();
diff --git a/unity-private/places/places-place-search-sections-bar.vala b/unity-private/places/places-place-search-sections-bar.vala
index fa0f0e694..a7f4b6f69 100644
--- a/unity-private/places/places-place-search-sections-bar.vala
+++ b/unity-private/places/places-place-search-sections-bar.vala
@@ -235,6 +235,7 @@ namespace Unity.Places
var pos = active_section.model.get_position (active_section.iter);
active_entry.set_active_section (pos);
+ bg.update ();
}
private bool on_section_clicked (Clutter.Actor actor, Clutter.Event e)
@@ -254,9 +255,6 @@ namespace Unity.Places
private void paint_bg (Cairo.Context cr, int width, int height)
{
- if (_style != SectionStyle.BREADCRUMB)
- return;
-
cr.set_operator (Cairo.Operator.CLEAR);
cr.paint ();
@@ -269,45 +267,85 @@ namespace Unity.Places
width -= 1;
height -= 1;
var radius = 5;
-
- cr.line_to (x, y + radius);
- cr.curve_to (x, y,
- x, y,
- x + radius, y);
- cr.line_to (width - radius, y);
- cr.curve_to (width, y,
- width, y,
- width, y + radius);
- cr.line_to (width, height - radius);
- cr.curve_to (width, height,
- width, height,
- width - radius, height);
- cr.line_to (x + radius, height);
- cr.curve_to (x, height,
- x, height,
- x, height - radius);
- cr.close_path ();
-
- cr.set_source_rgba (1.0, 1.0, 1.0, 0.5);
- cr.fill_preserve ();
- cr.stroke ();
-
- var chevron = 5;
var point = x;
- var children = get_children ();
- foreach (Clutter.Actor child in children)
+
+ if (_style != SectionStyle.BREADCRUMB)
{
- point += (int)(child.width) + SPACING/2;
+ var children = get_children ();
+ unowned Section? last_sec = null;
+
+ point -= SPACING/2;
+
+ foreach (Clutter.Actor child in children)
+ {
+ unowned Section sec = child as Section;
+
+ if (point < width - SPACING
+ && (last_sec == null || last_sec.active == false)
+ && sec.active != true)
+ {
+ cr.rectangle (point, y, 0.5, height);
+ var pat = new Cairo.Pattern.linear (x, y, x, y + height);
+ pat.add_color_stop_rgba (0.0, 0.0, 0.0, 0.0, 0.0);
+ pat.add_color_stop_rgba (0.5, 0.0, 0.0, 0.0, 0.5);
+ pat.add_color_stop_rgba (1.0, 0.0, 0.0, 0.0, 0.0);
+ cr.set_source (pat);
+ cr.fill ();
+
+ cr.rectangle (point+1, y, 0.5, height);
+ pat = new Cairo.Pattern.linear (x, y, x, y + height);
+ pat.add_color_stop_rgba (0.0, 1.0, 1.0, 1.0, 0.0);
+ pat.add_color_stop_rgba (0.5, 1.0, 1.0, 1.0, 0.5);
+ pat.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);
+ cr.set_source (pat);
+ cr.fill ();
+ }
+
+ point += (int)(child.width) + SPACING;
+ last_sec = sec;
+ }
+ }
+ else
+ {
+ cr.line_to (x, y + radius);
+ cr.curve_to (x, y,
+ x, y,
+ x + radius, y);
+ cr.line_to (width - radius, y);
+ cr.curve_to (width, y,
+ width, y,
+ width, y + radius);
+ cr.line_to (width, height - radius);
+ cr.curve_to (width, height,
+ width, height,
+ width - radius, height);
+ cr.line_to (x + radius, height);
+ cr.curve_to (x, height,
+ x, height,
+ x, height - radius);
+ cr.close_path ();
- if (point < width - chevron - SPACING)
+ cr.set_source_rgba (1.0, 1.0, 1.0, 0.5);
+ cr.fill_preserve ();
+ cr.stroke ();
+
+ var chevron = 5;
+ var children = get_children ();
+ point = x;
+ foreach (Clutter.Actor child in children)
{
- cr.move_to (point - chevron, y);
- cr.line_to (point + chevron, y + height/2);
- cr.line_to (point - chevron, y + height);
- cr.set_source_rgba (1.0, 1.0, 1.0, 0.8);
- cr.stroke ();
+ point += (int)(child.width) + SPACING/2;
+
+ if (point < width - chevron - SPACING)
+ {
+ cr.move_to (point - chevron, y);
+ cr.line_to (point + chevron, y + height/2);
+ cr.line_to (point - chevron, y + height);
+ cr.set_source_rgba (1.0, 1.0, 1.0, 1.0);
+ cr.stroke ();
+ }
+ point += SPACING/2;
}
- point += SPACING/2;
}
}
}
@@ -345,7 +383,7 @@ namespace Unity.Places
if (_active)
{
- color = { 152, 74, 131, 255 };
+ color = { 50, 50, 50, 255 };
mode = Clutter.AnimationMode.EASE_IN_QUAD;
opacity = 255;
}
@@ -406,21 +444,6 @@ namespace Unity.Places
public void start_destroy ()
{
(get_parent () as Clutter.Container).remove_actor (this);
- /*
- if (_destroy_factor != 1.0f)
- return;
-
- var anim = animate (Clutter.AnimationMode.EASE_OUT_QUAD, 2000,
- "destroy_factor", 0.0f);
-
- anim.completed.connect ((a) => {
- var obj = a.get_object () as Clutter.Actor;
-
- (obj.get_parent () as Clutter.Container).remove_actor (obj);
- });
-
- debug ("started_animation");
- */
}
private override void get_preferred_width (float for_height,
diff --git a/unity-private/places/places-view.vala b/unity-private/places/places-view.vala
index 8e91bc4de..38fc1bd9b 100644
--- a/unity-private/places/places-view.vala
+++ b/unity-private/places/places-view.vala
@@ -106,8 +106,7 @@ namespace Unity.Places
update_views (entry, section_id);
- if (active_entry != home_entry)
- entry.renderer_info_changed.connect (on_entry_renderer_info_changed);
+ entry.renderer_info_changed.connect (on_entry_renderer_info_changed);
}
private void update_views (PlaceEntry entry, uint section_id=0)
@@ -154,6 +153,8 @@ namespace Unity.Places
if (browser_path != null)
return new FolderBrowserRenderer ();
+ else if (entry.entry_renderer_name == "UnityHomeScreen")
+ return new HomeRenderer ();
else
return new DefaultRenderer ();
}
diff --git a/unity-private/places/places-volume-child-controller.vala b/unity-private/places/places-volume-child-controller.vala
new file mode 100644
index 000000000..81ef7e6fa
--- /dev/null
+++ b/unity-private/places/places-volume-child-controller.vala
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+using Unity.Launcher;
+using Unity.Testing;
+
+namespace Unity.Places
+{
+ public class VolumeChildController : ScrollerChildController
+ {
+ public static const string ICON = "/usr/share/unity/trash.png";
+
+ public Volume volume { get; construct; }
+
+ public VolumeChildController (Volume volume)
+ {
+ Object (child:new ScrollerChild (),
+ volume:volume);
+ }
+
+ construct
+ {
+ name = volume.get_name ();
+
+ var icon = volume.get_icon ();
+ var icon_name = "";
+ if (icon is ThemedIcon)
+ {
+ icon_name = (icon as ThemedIcon).get_names ()[0];
+ }
+ else if (icon is FileIcon)
+ {
+ icon_name = (icon as FileIcon).get_file ().get_path ();
+ }
+ else
+ {
+ icon_name = ICON;
+ }
+ load_icon_from_icon_name (icon_name);
+
+ debug ("ICON NAME: %s", icon_name);
+
+ child.group_type = ScrollerChild.GroupType.DEVICE;
+ child.drag_removed.connect (eject_volume);
+
+ volume.removed.connect (on_volume_removed);
+ }
+
+ private void on_volume_removed ()
+ {
+ ScrollerModel s;
+
+ s = ObjectRegistry.get_default ().lookup ("UnityScrollerModel")[0] as ScrollerModel;
+ s.remove (this.child);
+
+ this.unref ();
+ }
+
+ private void open_volume ()
+ {
+ Mount? mount = volume.get_mount ();
+ string error_msg = @"Cannot open volume '$(volume.get_name ())': ";
+
+ if (mount is Mount)
+ {
+ var loc = mount.get_root ();
+ try {
+ AppInfo.launch_default_for_uri (loc.get_uri (), null);
+ } catch (Error err) {
+ warning (error_msg + err.message);
+ }
+ }
+ else
+ {
+ if (volume.can_mount () == false)
+ {
+ warning (error_msg + "Cannot be mounted");
+ return;
+ }
+ try {
+ volume.mount.begin (0, null, null);
+
+ mount = volume.get_mount ();
+ if (mount is Mount)
+ AppInfo.launch_default_for_uri (mount.get_root ().get_uri (), null);
+ else
+ warning (error_msg + "Unable to mount");
+
+ } catch (Error e) {
+ warning (error_msg + e.message);
+ }
+
+ }
+ }
+
+ private void eject_volume ()
+ {
+ /*
+ * Because there are bugs in making this work through the vala 0.9.5 and
+ * I don't have time to debug them.
+ */
+ Utils.volume_eject (volume);
+ }
+
+ /* Overides */
+ public override void activate ()
+ {
+ open_volume ();
+ }
+
+ public override QuicklistController? get_menu_controller ()
+ {
+ return new ApplicationQuicklistController (this);
+ }
+
+ public override void get_menu_actions (ScrollerChildController.menu_cb callback)
+ {
+ Dbusmenu.Menuitem root = new Dbusmenu.Menuitem ();
+ root.set_root (true);
+
+ Dbusmenu.Menuitem item;
+
+ item = new Dbusmenu.Menuitem ();
+ item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, _("Open"));
+ item.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true);
+ item.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true);
+ item.item_activated.connect (open_volume);
+ root.child_append (item);
+
+ callback (root);
+ }
+
+ public override void get_menu_navigation (ScrollerChildController.menu_cb callback)
+ {
+ Dbusmenu.Menuitem root = new Dbusmenu.Menuitem ();
+ root.set_root (true);
+
+ if (volume.get_mount () != null)
+ {
+ Dbusmenu.Menuitem item;
+
+ item = new Dbusmenu.Menuitem ();
+ item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, _("Eject"));
+ item.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true);
+ item.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true);
+ root.child_append (item);
+ item.item_activated.connect (eject_volume);
+ }
+
+ callback (root);
+ }
+
+ public override bool can_drag ()
+ {
+ return true;
+ }
+ }
+}
diff --git a/unity-private/places/places-volume-controller.vala b/unity-private/places/places-volume-controller.vala
new file mode 100644
index 000000000..79ec94615
--- /dev/null
+++ b/unity-private/places/places-volume-controller.vala
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+using Unity.Launcher;
+using Unity.Testing;
+
+namespace Unity.Places
+{
+ public class VolumeController : Object
+ {
+ private VolumeMonitor monitor;
+
+ public VolumeController ()
+ {
+ Object ();
+ }
+
+ construct
+ {
+ monitor = VolumeMonitor.get ();
+ monitor.volume_added.connect (on_volume_added);
+
+ var volumes = monitor.get_volumes ();
+ foreach (Volume volume in volumes)
+ {
+ on_volume_added_real (volume);
+
+ /* Because get_volumes () returns a list of ref'd volumes */
+ volume.unref ();
+ }
+ }
+
+ private bool on_volume_added_real (Volume volume)
+ {
+ if (volume.can_eject ())
+ {
+ debug ("VOLUME_ADDED: %s", volume.get_name ());
+
+ var child = new VolumeChildController (volume);
+
+ ScrollerModel s;
+
+ s = ObjectRegistry.get_default ().lookup ("UnityScrollerModel")[0] as ScrollerModel;
+ s.add (child.child);
+
+ return true;
+ }
+ else
+ return false;
+ }
+
+ private void on_volume_added (Volume volume)
+ {
+ on_volume_added_real (volume);
+ }
+ }
+}
diff --git a/unity-private/testing/test-window.vala b/unity-private/testing/test-window.vala
index 3d3319579..cb76fbd5f 100644
--- a/unity-private/testing/test-window.vala
+++ b/unity-private/testing/test-window.vala
@@ -26,6 +26,7 @@ namespace Unity.Testing
public class Window : Gtk.Window, Shell
{
public bool menus_swallow_events { get { return true; } }
+ public bool super_key_active {get; set;}
public bool is_popup { get; construct; }
public int popup_width { get; construct; }
public int popup_height { get; construct; }
diff --git a/unity-private/unity-utils.c b/unity-private/unity-utils.c
index cc9d1c808..2d5d2e758 100644
--- a/unity-private/unity-utils.c
+++ b/unity-private/unity-utils.c
@@ -55,7 +55,7 @@ typedef struct {
#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS"
gboolean
-utils_window_is_decorated (guint32 xid)
+utils_window_is_decorated (Window xid)
{
GdkDisplay *display = gdk_display_get_default();
Atom hints_atom = None;
@@ -76,20 +76,23 @@ utils_window_is_decorated (guint32 xid)
False, AnyPropertyType, &type, &format, &nitems,
&bytes_after, &data);
- if (type == None || !data) return TRUE;
+ if (type == None || !data)
+ {
+ return TRUE;
+ }
hints = (MotifWmHints *)data;
retval = hints->decorations;
-
+
if (data)
XFree (data);
- return retval;
+ return retval == 1;
}
static void
-gdk_window_set_mwm_hints (guint32 xid,
+gdk_window_set_mwm_hints (Window xid,
MotifWmHints *new_hints)
{
GdkDisplay *display = gdk_display_get_default();
@@ -103,7 +106,7 @@ gdk_window_set_mwm_hints (guint32 xid,
g_return_if_fail (GDK_IS_DISPLAY (display));
- g_debug ("gdk_window_set_mwm_hints: %lld %d\n", xid, new_hints->decorations);
+ g_debug ("gdk_window_set_mwm_hints: %lu %lu\n", xid, new_hints->decorations);
hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
_XA_MOTIF_WM_HINTS);
@@ -148,7 +151,7 @@ gdk_window_set_mwm_hints (guint32 xid,
}
void
-utils_window_set_decorations (guint32 xid,
+utils_window_set_decorations (Window xid,
GdkWMDecoration decorations)
{
MotifWmHints *hints;
@@ -420,3 +423,20 @@ indicator_object_entry_free (IndicatorObjectEntry *entry)
entry = NULL;
}
+
+
+static void
+on_volume_ejected (GVolume *volume,
+ GAsyncResult *res)
+{
+ g_volume_eject_with_operation_finish (volume, res, NULL);
+}
+
+void
+utils_volume_eject (GVolume *volume)
+{
+ g_return_if_fail (G_IS_VOLUME (volume));
+
+ g_volume_eject_with_operation (volume, 0, NULL, NULL,
+ (GAsyncReadyCallback)on_volume_ejected, NULL);
+}
diff --git a/unity-private/utils.vala b/unity-private/utils.vala
index 07af3d253..01ac63fde 100644
--- a/unity-private/utils.vala
+++ b/unity-private/utils.vala
@@ -117,8 +117,11 @@ namespace Utils
string img2_path);
[CCode (lower_case_prefix = "utils_")]
- public extern bool window_is_decorated (uint32 xid);
+ public extern bool window_is_decorated (X.Window window);
[CCode (lower_case_prefix = "utils_")]
- public extern void window_set_decorations (uint32 xid, uint decorations);
+ public extern void window_set_decorations (X.Window window, uint decorations);
+
+ [CCode (lower_case_prefix = "utils_")]
+ public extern void volume_eject (GLib.Volume volume);
}
diff --git a/unity/Makefile.am b/unity/Makefile.am
index 6a6032753..a8afcf088 100644
--- a/unity/Makefile.am
+++ b/unity/Makefile.am
@@ -79,6 +79,7 @@ libunity_la_VALASOURCES = \
unity-place-activation.vala \
unity-place-browser.vala \
unity-place-renderer.vala \
+ unity-stripe-texture.vala \
webapp-fetcher.vala
diff --git a/unity/icon-postprocessor.vala b/unity/icon-postprocessor.vala
index 1833b0274..2d211c1c5 100644
--- a/unity/icon-postprocessor.vala
+++ b/unity/icon-postprocessor.vala
@@ -296,8 +296,9 @@ namespace Unity
private Cogl.Material icon_material;
private Cogl.Material bgcol_material;
- public float rotation = 0.0f;
-
+ public float rotation {get; set;}
+ public float stored_height = 0;
+ public float stored_ymod = 0;
public UnityIcon (Clutter.Texture? icon, Clutter.Texture? bg_tex)
{
@@ -347,6 +348,8 @@ namespace Unity
tex = (Cogl.Texture)(unity_icon_fg_layer.get_cogl_texture ());
mat.set_layer (0, tex);
fg_mat = mat;
+ notify["rotation"].connect (() => { queue_relayout (); });
+ stored_height = 48;
}
public override void get_preferred_width (float for_height,
@@ -376,8 +379,8 @@ namespace Unity
{
set_effects_painting (true);
var mat = new Cogl.Material ();
- mat.set_color4ub (color.red, color.green, color.blue, color.alpha);
- Cogl.rectangle (0, 0, 48, 48);
+ //mat.set_color4ub (color.red, color.green, color.blue, color.alpha);
+ //Cogl.rectangle (0, stored_ymod, 1, 1);//stored_height);
base.pick (color);
set_effects_painting (false);
}
@@ -399,23 +402,25 @@ namespace Unity
Cogl.Matrix modelview = Cogl.Matrix.identity (); //model view matrix
Cogl.Matrix projection = Cogl.Matrix.identity (); // projection matrix
- projection.perspective (60.0f, 1.0f, 0.1f, 100.0f);
- modelview.translate (0.0f, 0.0f, -44.0f - Math.fabsf (self.rotation / 360.0f) * 100);
+ projection.perspective (45.0f, 1.0f, 0.1f, 100.0f);
+ modelview.translate (0.0f, 0.0f, -59.5f - Math.fabsf (self.rotation / 360.0f) * 100);
modelview.rotate (self.rotation, 1.0f, 0.0f, 0.0f);
Cogl.Matrix viewmatrix = Cogl.Matrix.multiply (projection, modelview);
+ float base_z = -((Math.fabsf (self.rotation) / 90.0f) * 15.0f);
+
p1_x = -25.0f; p1_y = -25.0f;
p2_x = 25.0f; p2_y = -25.0f;
p3_x = 25.0f; p3_y = 25.0f;
p4_x = -25.0f; p4_y = 25.0f;
- z = 0.0f;
+ z = base_z;
w = 1.0f;
- viewmatrix.transform_point (out p1_x, out p1_y, out z, out w); p1_x /= w; p1_y /= w; z = 0.0f; w = 1.0f;
- viewmatrix.transform_point (out p2_x, out p2_y, out z, out w); p2_x /= w; p2_y /= w; z = 0.0f; w = 1.0f;
- viewmatrix.transform_point (out p3_x, out p3_y, out z, out w); p3_x /= w; p3_y /= w; z = 0.0f; w = 1.0f;
- viewmatrix.transform_point (out p4_x, out p4_y, out z, out w); p4_x /= w; p4_y /= w; z = 0.0f; w = 1.0f;
+ viewmatrix.transform_point (out p1_x, out p1_y, out z, out w); p1_x /= w; p1_y /= w; z = base_z; w = 1.0f;
+ viewmatrix.transform_point (out p2_x, out p2_y, out z, out w); p2_x /= w; p2_y /= w; z = base_z; w = 1.0f;
+ viewmatrix.transform_point (out p3_x, out p3_y, out z, out w); p3_x /= w; p3_y /= w; z = base_z; w = 1.0f;
+ viewmatrix.transform_point (out p4_x, out p4_y, out z, out w); p4_x /= w; p4_y /= w; z = base_z; w = 1.0f;
//transform into screen co-ordinates
@@ -431,16 +436,25 @@ namespace Unity
p4_x = (50 * (p4_x + 1) / 2);
p4_y = 48 + (50 * (p4_y - 1) / 2);
- if (Math.fabsf (self.rotation) <= 3.0)
+ if (Math.fabsf (self.rotation) <= 1.0)
{
// floor all the values. we don't floor when its rotated because then
// we lose subpixel accuracy and things look like a 1991 video game
- p1_x = Math.floorf (p1_x); p1_y = Math.floorf (p1_y);
- p2_x = Math.floorf (p2_x); p2_y = Math.floorf (p2_y);
+ p1_x = Math.ceilf (p1_x); p1_y = Math.ceilf (p1_y);
+ p2_x = Math.floorf (p2_x); p2_y = Math.ceilf (p2_y);
p3_x = Math.floorf (p3_x); p3_y = Math.floorf (p3_y);
- p4_x = Math.floorf (p4_x); p4_y = Math.floorf (p4_y);
+ p4_x = Math.ceilf (p4_x); p4_y = Math.floorf (p4_y);
}
+ self.stored_height = p3_y - p1_y;
+ self.stored_ymod = (50 - self.stored_height) / 2.0f;
+/*
+ p1_y += self.stored_ymod;
+ p2_y += self.stored_ymod;
+ p3_y += self.stored_ymod;
+ p4_y += self.stored_ymod;
+*/
+
Cogl.TextureVertex[4] points = {
Cogl.TextureVertex () {
x = p1_x,
@@ -528,13 +542,13 @@ namespace Unity
p2_x = 25.0f; p2_y = -25.0f;
p3_x = 25.0f; p3_y = 25.0f;
p4_x = -25.0f; p4_y = 25.0f;
- z = 0.0f;
+ z = base_z;
w = 1.0f;
- viewmatrix.transform_point (out p1_x, out p1_y, out z, out w); p1_x /= w; p1_y /= w; z = 0.0f; w = 1.0f;
- viewmatrix.transform_point (out p2_x, out p2_y, out z, out w); p2_x /= w; p2_y /= w; z = 0.0f; w = 1.0f;
- viewmatrix.transform_point (out p3_x, out p3_y, out z, out w); p3_x /= w; p3_y /= w; z = 0.0f; w = 1.0f;
- viewmatrix.transform_point (out p4_x, out p4_y, out z, out w); p4_x /= w; p4_y /= w; z = 0.0f; w = 1.0f;
+ viewmatrix.transform_point (out p1_x, out p1_y, out z, out w); p1_x /= w; p1_y /= w; z = base_z; w = 1.0f;
+ viewmatrix.transform_point (out p2_x, out p2_y, out z, out w); p2_x /= w; p2_y /= w; z = base_z; w = 1.0f;
+ viewmatrix.transform_point (out p3_x, out p3_y, out z, out w); p3_x /= w; p3_y /= w; z = base_z; w = 1.0f;
+ viewmatrix.transform_point (out p4_x, out p4_y, out z, out w); p4_x /= w; p4_y /= w; z = base_z; w = 1.0f;
//transform into screen co-ordinates
p1_x = xpad + (base_width * (p1_x + 1) / 2);
@@ -549,16 +563,23 @@ namespace Unity
p4_x = xpad + (base_width * (p4_x + 1) / 2);
p4_y = (48 - ypad) + (base_height * (p4_y - 1) / 2);
- if (Math.fabsf (self.rotation) <= 3.0)
+ if (Math.fabsf (self.rotation) <= 1.0)
{
// floor all the values. we don't floor when its rotated because then
// we lose subpixel accuracy and things look like a 1991 video game
- p1_x = Math.floorf (p1_x); p1_y = Math.floorf (p1_y);
- p2_x = Math.floorf (p2_x); p2_y = Math.floorf (p2_y);
+ p1_x = Math.ceilf (p1_x); p1_y = Math.ceilf (p1_y);
+ p2_x = Math.floorf (p2_x); p2_y = Math.ceilf (p2_y);
p3_x = Math.floorf (p3_x); p3_y = Math.floorf (p3_y);
- p4_x = Math.floorf (p4_x); p4_y = Math.floorf (p4_y);
+ p4_x = Math.ceilf (p4_x); p4_y = Math.floorf (p4_y);
}
+/*
+ p1_y += self.stored_ymod;
+ p2_y += self.stored_ymod;
+ p3_y += self.stored_ymod;
+ p4_y += self.stored_ymod;
+*/
+
Cogl.TextureVertex[4] icon_points = {
Cogl.TextureVertex () {
x = p1_x,
diff --git a/unity/quicklist-rendering.vala b/unity/quicklist-rendering.vala
index 22df34cb6..652282200 100644
--- a/unity/quicklist-rendering.vala
+++ b/unity/quicklist-rendering.vala
@@ -35,6 +35,7 @@ namespace Unity.QuicklistRendering
const float ITEM_HEIGHT = 2.0f;
const float ITEM_CORNER_RADIUS = 0.3f;
const float ITEM_CORNER_RADIUS_ABS = 4.0f;
+ const float ITEM_INDENT_ABS = 20.0f;
const float ANCHOR_HEIGHT = 1.5f;
const float ANCHOR_HEIGHT_ABS = 18.0f;
const float ANCHOR_WIDTH = 0.75f;
@@ -202,17 +203,8 @@ namespace Unity.QuicklistRendering
// draw checkmark
cr.save ();
- cr.translate (_align ((30.0f - 16.0f) / 2.0f),
- _align (((double) h - 16.0f) / 2.0f));
- cr.set_source_rgba (1.0f, 1.0f, 1.0f, 0.65f);
- _round_rect (cr,
- 1.0f, // aspect
- 0.0f, // top-left corner
- 0.0f, // top-left corner
- 3.0f, // "size" of the corners
- 16.0f, // width of the rectangle
- 16.0f); // height of the rectangle
- cr.stroke ();
+ cr.translate (_align ((ITEM_INDENT_ABS - 16.0f) / 2.0f),
+ _align (((double) h - 16.0f)/ 2.0f));
cr.set_source_rgba (1.0f, 1.0f, 1.0f, 1.0f);
@@ -255,7 +247,7 @@ namespace Unity.QuicklistRendering
int text_width;
int text_height;
get_text_extents (font, text, out text_width, out text_height);
- cr.move_to (30.0f + Ctk.em_to_pixel (MARGIN),
+ cr.move_to (ITEM_INDENT_ABS + Ctk.em_to_pixel (MARGIN),
(float) (h - text_height) / 2.0f);
Pango.cairo_show_layout (cr, layout);
@@ -293,18 +285,9 @@ namespace Unity.QuicklistRendering
// draw checkmark
cr.save ();
- cr.translate (_align ((30.0f - 16.0f) / 2.0f),
+ cr.translate (_align ((ITEM_INDENT_ABS - 16.0f) / 2.0f),
_align (((double) h - 16.0f) / 2.0f));
- _round_rect (cr,
- 1.0f, // aspect
- 0.0f, // top-left corner
- 0.0f, // top-left corner
- 3.0f, // "size" of the corners
- 16.0f, // width of the rectangle
- 16.0f); // height of the rectangle
- cr.stroke ();
-
if (enabled)
{
cr.translate (3.0f, 1.0f);
@@ -344,7 +327,7 @@ namespace Unity.QuicklistRendering
int text_width;
int text_height;
get_text_extents (font, text, out text_width, out text_height);
- cr.move_to (30.0f + Ctk.em_to_pixel (MARGIN),
+ cr.move_to (ITEM_INDENT_ABS + Ctk.em_to_pixel (MARGIN),
(float) (h - text_height) / 2.0f);
Pango.cairo_show_layout (cr, layout);
@@ -371,7 +354,7 @@ namespace Unity.QuicklistRendering
cr.scale (1.0f, 1.0f);
cr.set_line_width (1.0f);
- double x = _align (15.0f);
+ double x = _align (ITEM_INDENT_ABS / 2.0f);
double y = _align ((double) h / 2.0f);
double r1 = 3.5f;
double r2 = 8.5f;
@@ -383,17 +366,6 @@ namespace Unity.QuicklistRendering
cr.arc (x, y, r1, 0.0f * (GLib.Math.PI / 180.0f),
360.0f * (GLib.Math.PI / 180.0f));
cr.fill ();
- cr.set_source_rgba (1.0f, 1.0f, 1.0f, 0.65f);
- cr.arc (x, y, r2, 0.0f * (GLib.Math.PI / 180.0f),
- 360.0f * (GLib.Math.PI / 180.0f));
- cr.stroke ();
- }
- else
- {
- cr.set_source_rgba (1.0f, 1.0f, 1.0f, 0.65f);
- cr.arc (x, y, r2, 0.0f * (GLib.Math.PI / 180.0f),
- 360.0f * (GLib.Math.PI / 180.0f));
- cr.stroke ();
}
cr.set_source_rgba (1.0f, 1.0f, 1.0f, 1.0f);
@@ -419,7 +391,7 @@ namespace Unity.QuicklistRendering
int text_width;
int text_height;
get_text_extents (font, text, out text_width, out text_height);
- cr.move_to (30.0f + Ctk.em_to_pixel (MARGIN),
+ cr.move_to (ITEM_INDENT_ABS + Ctk.em_to_pixel (MARGIN),
(float) (h - text_height) / 2.0f);
Pango.cairo_show_layout (cr, layout);
@@ -452,7 +424,7 @@ namespace Unity.QuicklistRendering
h - 1.0f);
cr.fill ();
- double x = _align (15.0f);
+ double x = _align (ITEM_INDENT_ABS / 2.0f);
double y = _align ((double) h / 2.0f);
double r1 = 3.5f;
double r2 = 8.5f;
@@ -465,16 +437,7 @@ namespace Unity.QuicklistRendering
cr.arc (x, y, r1, 0.0f * (GLib.Math.PI / 180.0f),
360.0f * (GLib.Math.PI / 180.0f));
cr.fill ();
- cr.arc (x, y, r2, 0.0f * (GLib.Math.PI / 180.0f),
- 360.0f * (GLib.Math.PI / 180.0f));
- cr.stroke ();
}
- else
- {
- cr.arc (x, y, r2, 0.0f * (GLib.Math.PI / 180.0f),
- 360.0f * (GLib.Math.PI / 180.0f));
- cr.stroke ();
- }
// draw text
Pango.Layout layout = Pango.cairo_create_layout (cr);
@@ -498,7 +461,7 @@ namespace Unity.QuicklistRendering
int text_width;
int text_height;
get_text_extents (font, text, out text_width, out text_height);
- cr.move_to (30.0f + Ctk.em_to_pixel (MARGIN),
+ cr.move_to (ITEM_INDENT_ABS + Ctk.em_to_pixel (MARGIN),
(float) (h - text_height) / 2.0f);
Pango.cairo_show_layout (cr, layout);
@@ -543,7 +506,7 @@ namespace Unity.QuicklistRendering
int text_width;
int text_height;
get_text_extents (font, text, out text_width, out text_height);
- cr.move_to (Ctk.em_to_pixel (MARGIN),
+ cr.move_to (ITEM_INDENT_ABS + Ctk.em_to_pixel (MARGIN),
(float) (h - text_height) / 2.0f);
Pango.cairo_show_layout (cr, layout);
@@ -597,7 +560,7 @@ namespace Unity.QuicklistRendering
int text_width;
int text_height;
get_text_extents (font, text, out text_width, out text_height);
- cr.move_to (Ctk.em_to_pixel (MARGIN),
+ cr.move_to (ITEM_INDENT_ABS + Ctk.em_to_pixel (MARGIN),
(float) (h - text_height) / 2.0f);
cr.set_source_rgba (0.0f, 0.0f, 0.0f, 0.0f);
diff --git a/unity/shell.vala b/unity/shell.vala
index c0f4224a0..7a7239795 100644
--- a/unity/shell.vala
+++ b/unity/shell.vala
@@ -63,6 +63,7 @@ namespace Unity
public abstract void expose_xids (Array<uint32> xids);
public abstract void stop_expose ();
+ public abstract bool super_key_active {get; set;}
public abstract void get_window_details (uint32 xid,
out bool allows_resize,
out bool is_maximised);
@@ -73,6 +74,9 @@ namespace Unity
public signal void indicators_changed (int width);
public signal void mode_changed (ShellMode mode);
public signal void active_window_state_changed ();
+ public signal void super_key_modifier_release (uint keysym);
+ public signal void super_key_modifier_press (uint keysym);
+
}
public Shell? global_shell; // our global shell
diff --git a/unity/unity-appinfo-manager.vala b/unity/unity-appinfo-manager.vala
index 75eab0df6..24d82f04b 100644
--- a/unity/unity-appinfo-manager.vala
+++ b/unity/unity-appinfo-manager.vala
@@ -33,21 +33,42 @@ namespace Unity {
/**
* A singleton class that caches GLib.AppInfo objects.
* Singletons are evil, yes, but this on slightly less
- * so because the exposed API is immutable
+ * so because the exposed API is immutable.
+ *
+ * To detect when any of the managed AppInfo objects changes, appears,
+ * or goes away listen for the 'changed' signal.
*/
public class AppInfoManager : Object
{
private static AppInfoManager singleton = null;
- private Map<string,AppInfo> appinfo_by_id;
+ private Map<string,AppInfo?> appinfo_by_id; /* id or path -> AppInfo */
+ private Map<string,FileMonitor> monitors; /* parent uri -> monitor */
+ private Map<string, Gee.List<string>> categories_by_id; /* desktop id or path -> xdg cats */
private uchar[] buffer;
private size_t buffer_size;
private AppInfoManager ()
{
- appinfo_by_id = new HashMap<string,AppInfo> (GLib.str_hash, GLib.str_equal);
+ appinfo_by_id = new HashMap<string,AppInfo?> (GLib.str_hash, GLib.str_equal);
+ categories_by_id = new HashMap<string,Gee.List<string>> (GLib.str_hash, GLib.str_equal);
buffer_size = 1024;
buffer = new uchar[buffer_size];
+
+ monitors = new HashMap<string,AppInfo?> (GLib.str_hash, GLib.str_equal);
+ foreach (string path in IO.get_system_data_dirs())
+ {
+ var dir = File.new_for_path (
+ Path.build_filename (path, "applications"));
+ try {
+ var monitor = dir.monitor_directory (FileMonitorFlags.NONE);
+ monitor.changed.connect (on_dir_changed);
+ monitors.set (dir.get_uri(), monitor);
+ } catch (IOError e) {
+ warning ("Error setting up directory monitor on '%s': %s",
+ dir.get_uri (), e.message);
+ }
+ }
}
/**
@@ -56,12 +77,41 @@ namespace Unity {
public static AppInfoManager get_instance ()
{
if (AppInfoManager.singleton == null)
- AppInfoManager.singleton = new AppInfoManager();
+ AppInfoManager.singleton = new AppInfoManager();
return AppInfoManager.singleton;
}
/**
+ * Emitted whenever an AppInfo in any of the monitored paths change.
+ * Note that @new_appinfo may be null in case it has been removed.
+ */
+ public signal void changed (string id, AppInfo? new_appinfo);
+
+ /* Whenever something happens to a monitored file,
+ * we remove it from the cache */
+ private void on_dir_changed (FileMonitor mon, File file, File? other_file, FileMonitorEvent e)
+ {
+ var desktop_id = file.get_basename ();
+ var path = file.get_path ();
+ AppInfo? appinfo;
+
+ if (appinfo_by_id.has_key(desktop_id))
+ {
+ appinfo_by_id.unset(desktop_id);
+ appinfo = lookup (desktop_id);
+ changed (desktop_id, appinfo);
+ }
+
+ if (appinfo_by_id.has_key(path))
+ {
+ appinfo_by_id.unset(path);
+ appinfo = lookup (path);
+ changed (path, appinfo);
+ }
+ }
+
+ /**
* Look up an AppInfo given its desktop id or absolute path. The desktop id
* is the base filename of the .desktop file for the application including
* the .desktop extension.
@@ -71,26 +121,97 @@ namespace Unity {
*/
public AppInfo? lookup (string id)
{
- /* Try the cache */
- var appinfo = appinfo_by_id.get (id);
- if (appinfo != null)
- return appinfo;
+ /* Check the cache. Note that null is a legal value since it means that
+ * the files doesn't exist */
+ if (appinfo_by_id.has_key (id))
+ return appinfo_by_id.get (id);
/* Look up by path or by desktop id */
+ AppInfo? appinfo;
+ KeyFile? keyfile = new KeyFile ();
if (id.has_prefix("/"))
- appinfo = new DesktopAppInfo.from_filename (id);
+ {
+ try {
+ keyfile.load_from_file (id, KeyFileFlags.NONE);
+ } catch (Error e) {
+ keyfile = null;
+ if (!(e is IOError.NOT_FOUND || e is KeyFileError.NOT_FOUND))
+ warning ("Error loading '%s': %s", id, e.message);
+ }
+ var dir = File.new_for_path (id).get_parent ();
+ var dir_uri = dir.get_uri ();
+ if (!monitors.has_key (dir_uri))
+ {
+ try {
+ var monitor = dir.monitor_directory (FileMonitorFlags.NONE);
+ monitor.changed.connect (on_dir_changed);
+ monitors.set (dir_uri, monitor);
+ debug ("Monitoring extra app directory: %s", dir_uri);
+ } catch (IOError ioe) {
+ warning ("Error setting up extra app directory monitor on '%s': %s",
+ dir_uri, ioe.message);
+ }
+ }
+ }
else
- appinfo = new DesktopAppInfo (id);
-
- if (appinfo != null)
{
- appinfo_by_id.set (id, appinfo);
- // FIXME install monitor
+ string path = Path.build_filename ("applications", id, null);
+ string full_path;
+ try {
+ keyfile.load_from_data_dirs (path, out full_path, KeyFileFlags.NONE);
+ } catch (Error e) {
+ keyfile = null;
+ if (!(e is IOError.NOT_FOUND || e is KeyFileError.NOT_FOUND))
+ warning ("Error loading '%s': %s", id, e.message);
+ }
+ }
+
+ /* If keyfile is null we had an error loading it */
+ if (keyfile != null)
+ {
+ appinfo = new DesktopAppInfo.from_keyfile (keyfile);
+ try {
+ string[] categories = keyfile.get_string_list ("Desktop Entry",
+ "Categories");
+ var cats = new Gee.ArrayList<string>();
+ foreach (var cat in categories)
+ cats.add (cat);
+
+ categories_by_id.set (id, cats);
+ } catch (KeyFileError e) {
+ /* Unknown key or group. This app has no XDG Catories */
+ }
}
+ else
+ appinfo = null;
+
+ /* If we don't find the file, we also cache that fact since we'll store
+ * a null AppInfo in that case */
+ appinfo_by_id.set (id, appinfo);
+
return appinfo;
}
/**
+ * Look up XDG categories for for desktop id or file path @id.
+ * Returns null if id is not found.
+ * This method will do sync IO if the desktop file for @id is not
+ * already cached. So if you are living in an async world you must first
+ * do an async call to lookup_async(id) before calling this method, in which
+ * case no sync io will be done.
+ */
+ public Gee.List<string>? get_categories (string id)
+ {
+ /* Make sure we have loaded the relevant .desktop file: */
+ AppInfo? appinfo = lookup (id);
+
+ if (appinfo == null)
+ return null;
+
+ return categories_by_id.get (id);
+ }
+
+ /**
* Look up an AppInfo given its desktop id or absolute path.
* The desktop id is the base filename of the .desktop file for the
* application including the .desktop extension.
@@ -100,10 +221,10 @@ namespace Unity {
*/
public async AppInfo? lookup_async (string id) throws Error
{
- /* Check the cache */
- var appinfo = appinfo_by_id.get (id);
- if (appinfo != null)
- return appinfo;
+ /* Check the cache. Note that null is a legal value since it means that
+ * the files doesn't exist */
+ if (appinfo_by_id.has_key (id))
+ return appinfo_by_id.get (id);
/* Load it async */
size_t data_size;
@@ -115,6 +236,20 @@ namespace Unity {
{
var f = File.new_for_path (id);
input = yield f.read_async (Priority.DEFAULT, null);
+ var dir = f.get_parent ();
+ var dir_uri = dir.get_uri ();
+ if (!monitors.has_key (dir_uri))
+ {
+ try {
+ var monitor = dir.monitor_directory (FileMonitorFlags.NONE);
+ monitor.changed.connect (on_dir_changed);
+ monitors.set (dir_uri, monitor);
+ debug ("Monitoring extra app directory: %s", dir_uri);
+ } catch (IOError ioe) {
+ warning ("Error setting up extra app directory monitor on '%s': %s",
+ dir_uri, ioe.message);
+ }
+ }
}
else
{
@@ -122,8 +257,13 @@ namespace Unity {
input = yield IO.open_from_data_dirs (path);
}
+ /* If we don't find the file, we also cache that fact by caching a
+ * null value for that id */
if (input == null)
- return null;
+ {
+ appinfo_by_id.set (id, null);
+ return null;
+ }
try
{
@@ -150,7 +290,7 @@ namespace Unity {
}
/* Create the appinfo and cache it */
- appinfo = new DesktopAppInfo.from_keyfile (keyfile);
+ var appinfo = new DesktopAppInfo.from_keyfile (keyfile);
appinfo_by_id.set (id, appinfo);
/* Manually free the raw file data */
diff --git a/unity/unity-cairo-canvas.vala b/unity/unity-cairo-canvas.vala
index 91aee9a2f..8b1738fef 100644
--- a/unity/unity-cairo-canvas.vala
+++ b/unity/unity-cairo-canvas.vala
@@ -38,7 +38,7 @@ namespace Unity
private int last_width = 0;
private int last_height = 0;
- private CairoCanvasPaint paint_func;
+ public CairoCanvasPaint paint_func;
public CairoCanvas (CairoCanvasPaint _func)
{
diff --git a/unity/unity-place.vala b/unity/unity-place.vala
index 8fd5c1730..cf17eaee8 100644
--- a/unity/unity-place.vala
+++ b/unity/unity-place.vala
@@ -172,6 +172,11 @@ namespace Unity.Place {
return search;
}
+ public List<unowned string> get_hints ()
+ {
+ return hints.get_keys ();
+ }
+
public void set_hint (string hint, string val)
{
hints.insert (hint, val);
@@ -196,6 +201,27 @@ namespace Unity.Place {
{
return hints.size ();
}
+
+ /* Returns true if search strings and all hints match */
+ public bool equals (Search? other)
+ {
+ if (other == null)
+ return false;
+
+ if (get_search_string() != other.get_search_string ())
+ return false;
+
+ if (num_hints () != other.num_hints())
+ return false;
+
+ foreach (var hint in get_hints ())
+ {
+ if (other.get_hint (hint) != get_hint (hint))
+ return false;
+ }
+
+ return true;
+ }
}
/**
@@ -695,13 +721,19 @@ namespace Unity.Place {
public void set_global_search (string search,
HashTable<string,string> hints)
{
- this._entry_info.active_global_search = new Search (search, hints);
+ var s = new Search (search, hints);
+
+ if (!s.equals (this._entry_info.active_global_search))
+ this._entry_info.active_global_search = s;
}
public void set_search (string search,
HashTable<string,string> hints)
{
- this._entry_info.active_search = new Search (search, hints);
+ var s = new Search (search, hints);
+
+ if (!s.equals (this._entry_info.active_search))
+ this._entry_info.active_search = s;
}
public void set_active (bool is_active)
@@ -842,6 +874,7 @@ namespace Unity.Place {
private string _dbus_path;
private bool _exported = false;
private HashTable<string, _EntrySignals?> entry_signals;
+ private Gee.Set<string> ignore_remote_notify_props;
/*
* Properties
@@ -873,6 +906,12 @@ namespace Unity.Place {
construct {
service = new ServiceImpl (_dbus_path);
entry_signals = new HashTable<string, _EntrySignals?>(str_hash, str_equal);
+
+ ignore_remote_notify_props = new Gee.HashSet<string> ();
+ ignore_remote_notify_props.add ("active-search");
+ ignore_remote_notify_props.add ("active-global-search");
+ ignore_remote_notify_props.add ("active");
+ ignore_remote_notify_props.add ("active-section");
}
public Controller (string dbus_path)
@@ -1015,6 +1054,11 @@ namespace Unity.Place {
entry.dbus_path);
return;
}
+
+ /* Don't emit signals on the bus that are strictly local metadata */
+ if (pspec.get_name () in ignore_remote_notify_props)
+ return;
+
entry_service.queue_place_entry_info_changed_signal ();
}
diff --git a/unity/unity-stripe-texture.vala b/unity/unity-stripe-texture.vala
new file mode 100644
index 000000000..df6ed1c95
--- /dev/null
+++ b/unity/unity-stripe-texture.vala
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 Canonical, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License
+ * version 3.0 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3.0 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+namespace Unity
+{
+ /*
+ * UnityStripeTexture will paint itself in the stripe-style that's used
+ * in many places in Unity. This is best-used as a background for CtkActor.
+ * However there are some options to make the painting of more complex
+ * objects easier
+ */
+ public class StripeTexture : CairoCanvas
+ {
+ /* Set the outline_paint_func if you want to draw your own outline for
+ * the stripe to paint in
+ */
+ public delegate void StripeTextureOutlineFunc (Cairo.Context cr,
+ int width,
+ int height);
+
+ public float radius { get; construct set; }
+
+ public StripeTextureOutlineFunc outline_paint_func;
+
+ private Cairo.Surface? pattern;
+
+ public StripeTexture (StripeTextureOutlineFunc? func)
+ {
+ Object (radius:10.0f);
+
+ outline_paint_func = rounded_outline;
+ if (func != null)
+ outline_paint_func = func;
+ }
+
+ construct
+ {
+ paint_func = paint_bg;
+ }
+
+ public void rounded_outline (Cairo.Context cr, int width, int height)
+ {
+ var x = 0;
+ var y = 0;
+ width -= 1;
+ height -= 1;
+
+ cr.line_to (x, y + radius);
+ cr.curve_to (x, y,
+ x, y,
+ x + radius, y);
+ cr.line_to (width - radius, y);
+ cr.curve_to (width, y,
+ width, y,
+ width, y + radius);
+ cr.line_to (width, height - radius);
+ cr.curve_to (width, height,
+ width, height,
+ width - radius, height);
+ cr.line_to (x + radius, height);
+ cr.curve_to (x, height,
+ x, height,
+ x, height - radius);
+ cr.close_path ();
+ }
+
+ private void paint_bg (Cairo.Context cr, int width, int height)
+ {
+ cr.set_operator (Cairo.Operator.CLEAR);
+ cr.paint ();
+
+ cr.set_operator (Cairo.Operator.OVER);
+ cr.set_line_width (1.0);
+
+ cr.translate (0.5, 0.5);
+
+ outline_paint_func (cr, width, height);
+
+ if (pattern == null)
+ {
+ pattern = new Cairo.Surface.similar (cr.get_target (),
+ Cairo.Content.COLOR_ALPHA,
+ 4, 4);
+ var context = new Cairo.Context (pattern);
+
+ context.set_operator (Cairo.Operator.CLEAR);
+ context.paint ();
+
+ context.set_line_width (0.3);
+ context.set_operator (Cairo.Operator.OVER);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.65);
+
+ context.move_to (0, 0);
+ context.line_to (4, 4);
+
+ context.stroke ();
+ }
+
+ var pat = new Cairo.Pattern.for_surface (pattern);
+ pat.set_extend (Cairo.Extend.REPEAT);
+ cr.set_source (pat);
+ cr.fill_preserve ();
+
+ cr.set_line_width (1.75);
+ cr.set_source_rgba (1.0, 1.0, 1.0, 0.5);
+ cr.stroke ();
+ }
+ }
+}
diff --git a/vapi/clutter-1.0.vapi b/vapi/clutter-1.0.vapi
index bac197fd5..6c3a49fd8 100644
--- a/vapi/clutter-1.0.vapi
+++ b/vapi/clutter-1.0.vapi
@@ -5654,6 +5654,8 @@ namespace Clutter {
[CCode (cheader_filename = "clutter/clutter.h")]
public static bool get_motion_events_enabled ();
[CCode (cheader_filename = "clutter/clutter.h")]
+ public static bool get_gl_picking_enabled ();
+ [CCode (cheader_filename = "clutter/clutter.h")]
public static GLib.OptionGroup get_option_group ();
[CCode (cheader_filename = "clutter/clutter.h")]
public static GLib.OptionGroup get_option_group_without_init ();
@@ -5698,6 +5700,8 @@ namespace Clutter {
[CCode (cheader_filename = "clutter/clutter.h")]
public static void set_motion_events_enabled (bool enable);
[CCode (cheader_filename = "clutter/clutter.h")]
+ public static void set_gl_picking_enabled (bool enable);
+ [CCode (cheader_filename = "clutter/clutter.h")]
public static uint threads_add_frame_source (uint fps, GLib.SourceFunc func, void* data);
[CCode (cheader_filename = "clutter/clutter.h")]
public static uint threads_add_frame_source_full (int priority, uint fps, GLib.SourceFunc func, void* data, GLib.DestroyNotify notify);
diff --git a/vapi/mutter-2.28.vapi b/vapi/mutter-2.28.vapi
index f5f8cbab6..a6a2ed1ea 100644
--- a/vapi/mutter-2.28.vapi
+++ b/vapi/mutter-2.28.vapi
@@ -130,6 +130,11 @@ namespace Mutter {
public static void set_input_focus_window (Mutter.MetaDisplay display, Mutter.MetaWindow window, bool focus_frame, uint32 timestamp);
[CCode (cname = "meta_display_xwindow_is_a_no_focus_window")]
public static bool xwindow_is_a_no_focus_window (Mutter.MetaDisplay display, X.Window xwindow);
+
+ public signal void overlay_key ();
+ public signal void overlay_key_down ();
+ public signal void overlay_key_with_modifier (uint keysym);
+ public signal void overlay_key_with_modifier_down (uint keysym);
}
[Compact]
[CCode (cheader_filename = "mutter-plugins.h")]