From 46c210c31479d0a57de4370b0f6aa96b7a758336 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 31 Mar 2010 14:57:07 -0400 Subject: [PATCH] [ShellMenu] port from BigBox to StBoxLayout The actual changes to shell-menu.[ch] are pretty minimal; most of the changes there are just style/spacing/indentation. Also, removed shell_menu_append_separator() since it wasn't needed; the separators would already have been behaving as intended just because they were non-reactive. https://bugzilla.gnome.org/show_bug.cgi?id=614516 --- data/theme/gnome-shell.css | 2 +- js/ui/appDisplay.js | 31 +++---- src/shell-menu.c | 170 +++++++++++++++++-------------------- src/shell-menu.h | 22 ++--- 4 files changed, 98 insertions(+), 127 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index 69628614b..848929cbf 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -502,7 +502,7 @@ StTooltip { padding: 4px; background-color: rgba(0,0,0,0.9); color: #ffffff; - -shell-menu-spacing: 4px; + spacing: 4px; } .app-well-menu-arrow { diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index c8261ad82..c48ed20c5 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -613,15 +613,14 @@ AppIconMenu.prototype = { this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight)); this.actor.connect('allocate', Lang.bind(this, this._allocate)); - this._windowContainerBox = new St.Bin({ style_class: 'app-well-menu' }); - this._windowContainer = new Shell.Menu({ orientation: Big.BoxOrientation.VERTICAL, - width: Main.overview._dash.actor.width }); - this._windowContainerBox.set_child(this._windowContainer); + this._windowContainer = new Shell.Menu({ style_class: 'app-well-menu', + vertical: true, + width: Main.overview._dash.actor.width }); this._windowContainer.connect('unselected', Lang.bind(this, this._onItemUnselected)); this._windowContainer.connect('selected', Lang.bind(this, this._onItemSelected)); this._windowContainer.connect('cancelled', Lang.bind(this, this._onWindowSelectionCancelled)); this._windowContainer.connect('activate', Lang.bind(this, this._onItemActivate)); - this.actor.add_actor(this._windowContainerBox); + this.actor.add_actor(this._windowContainer); // Stay popped up on release over application icon this._windowContainer.set_persistent_source(this._source.actor); @@ -631,8 +630,6 @@ AppIconMenu.prototype = { this._windowContainer.connect('leave-event', Lang.bind(this, this._onMenuLeave)); this._windowContainer.connect('button-release-event', Lang.bind(this, this._onMenuButtonRelease)); - this._windowContainerBox.connect('style-changed', Lang.bind(this, this._onStyleChanged)); - this._arrow = new St.DrawingArea({ style_class: 'app-well-menu-arrow' }); this._arrow.connect('repaint', Lang.bind(this, function (area) { Shell.draw_box_pointer(area, Shell.PointerDirection.LEFT); @@ -650,21 +647,21 @@ AppIconMenu.prototype = { }, _getPreferredWidth: function(actor, forHeight, alloc) { - let [menuMin, menuNatural] = this._windowContainerBox.get_preferred_width(forHeight); + let [menuMin, menuNatural] = this._windowContainer.get_preferred_width(forHeight); let [arrowMin, arrowNatural] = this._arrow.get_preferred_width(forHeight); alloc.min_size = menuMin + arrowMin; alloc.natural_size = menuNatural + arrowNatural; }, _getPreferredHeight: function(actor, forWidth, alloc) { - let [min, natural] = this._windowContainerBox.get_preferred_height(forWidth); + let [min, natural] = this._windowContainer.get_preferred_height(forWidth); alloc.min_size = min; alloc.natural_size = natural; }, _allocate: function(actor, box, flags) { let childBox = new Clutter.ActorBox(); - let themeNode = this._windowContainerBox.get_theme_node(); + let themeNode = this._windowContainer.get_theme_node(); let width = box.x2 - box.x1; let height = box.y2 - box.y1; @@ -683,7 +680,7 @@ AppIconMenu.prototype = { childBox.x2 = width; childBox.y1 = 0; childBox.y2 = height; - this._windowContainerBox.allocate(childBox, flags); + this._windowContainer.allocate(childBox, flags); }, _redisplay: function() { @@ -736,7 +733,7 @@ AppIconMenu.prototype = { _appendSeparator: function () { let bin = new St.Bin({ style_class: "app-well-menu-separator" }); - this._windowContainer.append_separator(bin, Big.BoxPackFlags.NONE); + this._windowContainer.add_actor(bin); }, _appendMenuItem: function(labelText) { @@ -744,7 +741,7 @@ AppIconMenu.prototype = { reactive: true }); let label = new St.Label({ text: labelText }); box.add(label); - this._windowContainer.append(box, Big.BoxPackFlags.NONE); + this._windowContainer.add_actor(box); return box; }, @@ -862,14 +859,6 @@ AppIconMenu.prototype = { _onWindowSelectionCancelled: function () { this.emit('highlight-window', null); this.popdown(); - }, - - _onStyleChanged: function() { - let themeNode = this._windowContainerBox.get_theme_node(); - [success, len] = themeNode.get_length('-shell-menu-spacing', false) - if (success) { - this._windowContainer.spacing = len; - } } }; Signals.addSignalMethods(AppIconMenu.prototype); diff --git a/src/shell-menu.c b/src/shell-menu.c index 605a7ab74..505bbd64c 100644 --- a/src/shell-menu.c +++ b/src/shell-menu.c @@ -4,15 +4,15 @@ * SECTION:shell-menu * @short_description: A box which acts like a popup menu * - * A #BigBox subclass which adds methods and signals useful for implementing - * popup-menu like actors. + * A #StBoxLayout subclass which adds methods and signals useful for + * implementing popup-menu like actors. */ #include "config.h" #include "shell-menu.h" -G_DEFINE_TYPE(ShellMenu, shell_menu, BIG_TYPE_BOX); +G_DEFINE_TYPE (ShellMenu, shell_menu, ST_TYPE_BOX_LAYOUT); struct _ShellMenuPrivate { gboolean popped_up; @@ -41,7 +41,9 @@ static gboolean container_contains (ClutterContainer *container, ClutterActor *actor) { - while (actor != NULL && actor != (ClutterActor*)container) + ClutterActor *container_actor = CLUTTER_ACTOR (container); + + while (actor != NULL && actor != container_actor) { actor = clutter_actor_get_parent (actor); } @@ -49,37 +51,42 @@ container_contains (ClutterContainer *container, } static void -shell_menu_popdown_nosignal (ShellMenu *box) +shell_menu_popdown_nosignal (ShellMenu *menu) { - box->priv->popped_up = FALSE; - if (box->priv->have_grab) + menu->priv->popped_up = FALSE; + if (menu->priv->have_grab) clutter_ungrab_pointer (); - clutter_actor_hide (CLUTTER_ACTOR (box)); + clutter_actor_hide (CLUTTER_ACTOR (menu)); } static void on_selected_destroy (ClutterActor *actor, - ShellMenu *box) + ShellMenu *menu) { - box->priv->selected = NULL; + menu->priv->selected = NULL; } static void -set_selected (ShellMenu *box, +set_selected (ShellMenu *menu, ClutterActor *actor) { - if (actor == box->priv->selected) + if (actor == menu->priv->selected) return; - if (box->priv->selected) + if (menu->priv->selected) { - g_signal_handlers_disconnect_by_func (box->priv->selected, G_CALLBACK(on_selected_destroy), box); - g_signal_emit (G_OBJECT (box), shell_menu_signals[UNSELECTED], 0, box->priv->selected); + g_signal_handlers_disconnect_by_func (menu->priv->selected, + G_CALLBACK (on_selected_destroy), + menu); + g_signal_emit (G_OBJECT (menu), shell_menu_signals[UNSELECTED], 0, + menu->priv->selected); } - box->priv->selected = actor; - if (box->priv->selected) + menu->priv->selected = actor; + if (menu->priv->selected) { - g_signal_connect (box->priv->selected, "destroy", G_CALLBACK(on_selected_destroy), box); - g_signal_emit (G_OBJECT (box), shell_menu_signals[SELECTED], 0, box->priv->selected); + g_signal_connect (menu->priv->selected, "destroy", + G_CALLBACK (on_selected_destroy), menu); + g_signal_emit (G_OBJECT (menu), shell_menu_signals[SELECTED], 0, + menu->priv->selected); } } @@ -87,113 +94,108 @@ static gboolean shell_menu_enter_event (ClutterActor *actor, ClutterCrossingEvent *event) { - ShellMenu *box = SHELL_MENU (actor); + ShellMenu *menu = SHELL_MENU (actor); - if (!container_contains (CLUTTER_CONTAINER (box), event->source)) - return TRUE; + if (container_contains (CLUTTER_CONTAINER (menu), event->source) && + event->source != CLUTTER_ACTOR (menu)) + set_selected (menu, event->source); - if (event->source == (ClutterActor*)box) - return TRUE; - - if (g_object_get_data (G_OBJECT (event->source), "shell-is-separator")) - return TRUE; - - set_selected (box, event->source); - - return TRUE; + return CLUTTER_ACTOR_CLASS (shell_menu_parent_class)->enter_event (actor, event); } static gboolean shell_menu_leave_event (ClutterActor *actor, ClutterCrossingEvent *event) { - ShellMenu *box = SHELL_MENU (actor); + ShellMenu *menu = SHELL_MENU (actor); - set_selected (box, NULL); + set_selected (menu, NULL); - return TRUE; + return CLUTTER_ACTOR_CLASS (shell_menu_parent_class)->leave_event (actor, event); } static gboolean shell_menu_button_release_event (ClutterActor *actor, ClutterButtonEvent *event) { - ShellMenu *box = SHELL_MENU (actor); + ShellMenu *menu = SHELL_MENU (actor); /* Until the user releases the button that brought up the menu, we just * ignore other button press/releass. * See https://bugzilla.gnome.org/show_bug.cgi?id=596371 */ - if (box->priv->activating_button > 0 && box->priv->activating_button != event->button) + if (menu->priv->activating_button > 0 && + menu->priv->activating_button != event->button) return FALSE; - box->priv->activating_button = 0; + menu->priv->activating_button = 0; - if (box->priv->source_actor && !box->priv->released_on_source) + if (menu->priv->source_actor && !menu->priv->released_on_source) { - if (box->priv->source_actor == event->source || - (CLUTTER_IS_CONTAINER (box->priv->source_actor) && - container_contains (CLUTTER_CONTAINER (box->priv->source_actor), event->source))) + if (menu->priv->source_actor == event->source || + (CLUTTER_IS_CONTAINER (menu->priv->source_actor) && + container_contains (CLUTTER_CONTAINER (menu->priv->source_actor), event->source))) { /* On the next release, we want to pop down the menu regardless */ - box->priv->released_on_source = TRUE; + menu->priv->released_on_source = TRUE; return TRUE; } } - shell_menu_popdown_nosignal (box); + shell_menu_popdown_nosignal (menu); - if (!container_contains (CLUTTER_CONTAINER (box), event->source) || - box->priv->selected == NULL) + if (!container_contains (CLUTTER_CONTAINER (menu), event->source) || + menu->priv->selected == NULL) { - g_signal_emit (G_OBJECT (box), shell_menu_signals[CANCELLED], 0); + g_signal_emit (G_OBJECT (menu), shell_menu_signals[CANCELLED], 0); return FALSE; } - g_signal_emit (G_OBJECT (box), shell_menu_signals[ACTIVATE], 0, box->priv->selected); + g_signal_emit (G_OBJECT (menu), shell_menu_signals[ACTIVATE], 0, + menu->priv->selected); return TRUE; } void -shell_menu_popup (ShellMenu *box, +shell_menu_popup (ShellMenu *menu, guint button, guint32 activate_time) { - if (box->priv->popped_up) + if (menu->priv->popped_up) return; - box->priv->activating_button = button; - box->priv->popped_up = TRUE; - box->priv->have_grab = TRUE; - box->priv->released_on_source = FALSE; - clutter_grab_pointer (CLUTTER_ACTOR (box)); + menu->priv->activating_button = button; + menu->priv->popped_up = TRUE; + menu->priv->have_grab = TRUE; + menu->priv->released_on_source = FALSE; + clutter_grab_pointer (CLUTTER_ACTOR (menu)); } /** * shell_menu_popdown: - * @box: + * @menu: * * If the menu is currently active, hide it, emitting the 'cancelled' signal. */ void -shell_menu_popdown (ShellMenu *box) +shell_menu_popdown (ShellMenu *menu) { - if (!box->priv->popped_up) + if (!menu->priv->popped_up) return; - shell_menu_popdown_nosignal (box); - g_signal_emit (G_OBJECT (box), shell_menu_signals[CANCELLED], 0); + shell_menu_popdown_nosignal (menu); + g_signal_emit (G_OBJECT (menu), shell_menu_signals[CANCELLED], 0); } static void on_source_destroyed (ClutterActor *actor, - ShellMenu *box) + ShellMenu *menu) { - box->priv->source_actor = NULL; + menu->priv->source_actor = NULL; } /** * shell_menu_set_persistent_source: - * @box: + * @menu: * @source: Actor to use as menu origin * * This function changes the menu behavior on button release. Normally @@ -204,45 +206,25 @@ on_source_destroyed (ClutterActor *actor, * The given @source actor must be reactive for this function to work. */ void -shell_menu_set_persistent_source (ShellMenu *box, +shell_menu_set_persistent_source (ShellMenu *menu, ClutterActor *source) { - if (box->priv->source_actor) + if (menu->priv->source_actor) { - g_signal_handlers_disconnect_by_func (G_OBJECT (box->priv->source_actor), + g_signal_handlers_disconnect_by_func (G_OBJECT (menu->priv->source_actor), G_CALLBACK (on_source_destroyed), - box); + menu); } - box->priv->source_actor = source; - if (box->priv->source_actor) + menu->priv->source_actor = source; + if (menu->priv->source_actor) { - g_signal_connect (G_OBJECT (box->priv->source_actor), + g_signal_connect (G_OBJECT (menu->priv->source_actor), "destroy", G_CALLBACK (on_source_destroyed), - box); + menu); } } -/** - * shell_menu_append_separator: - * @box: - * @separator: An actor which functions as a menu separator - * @flags: Packing flags - * - * Actors added to the menu with default functions are treated like - * menu items; this function will add an actor that should instead - * be treated like a menu separator. The current practical effect - * is that the separators will not be selectable. - */ -void -shell_menu_append_separator (ShellMenu *box, - ClutterActor *separator, - BigBoxPackFlags flags) -{ - g_object_set_data (G_OBJECT (separator), "shell-is-separator", GUINT_TO_POINTER(TRUE)); - big_box_append (BIG_BOX (box), separator, flags); -} - static void shell_menu_dispose (GObject *gobject) { @@ -267,7 +249,7 @@ shell_menu_class_init (ShellMenuClass *klass) /** * ShellMenu::unselected - * @box: The #ShellMenu + * @menu: The #ShellMenu * @actor: The previously hovered-over menu item * * This signal is emitted when a menu item transitions to @@ -284,7 +266,7 @@ shell_menu_class_init (ShellMenuClass *klass) /** * ShellMenu::selected - * @box: The #ShellMenu + * @menu: The #ShellMenu * @actor: The hovered-over menu item * * This signal is emitted when a menu item is in a selected state. @@ -300,7 +282,7 @@ shell_menu_class_init (ShellMenuClass *klass) /** * ShellMenu::activate - * @box: The #ShellMenu + * @menu: The #ShellMenu * @actor: The clicked menu item * * This signal is emitted when a menu item is selected. @@ -316,7 +298,7 @@ shell_menu_class_init (ShellMenuClass *klass) /** * ShellMenu::cancelled - * @box: The #ShellMenu + * @menu: The #ShellMenu * * This signal is emitted when the menu is closed without an option selected. */ diff --git a/src/shell-menu.h b/src/shell-menu.h index 6507988d9..55417e61a 100644 --- a/src/shell-menu.h +++ b/src/shell-menu.h @@ -3,7 +3,7 @@ #define __SHELL_MENU_H__ #include -#include "big/box.h" +#include "st.h" #define SHELL_TYPE_MENU (shell_menu_get_type ()) #define SHELL_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_MENU, ShellMenu)) @@ -19,24 +19,24 @@ typedef struct _ShellMenuPrivate ShellMenuPrivate; struct _ShellMenu { - BigBox parent; + StBoxLayout parent; - ShellMenuPrivate *priv; + ShellMenuPrivate *priv; }; struct _ShellMenuClass { - BigBoxClass parent_class; + StBoxLayoutClass parent_class; }; -GType shell_menu_get_type (void) G_GNUC_CONST; +GType shell_menu_get_type (void) G_GNUC_CONST; -void shell_menu_popup (ShellMenu *behavior, guint button, guint32 activate_time); +void shell_menu_popup (ShellMenu *menu, + guint button, + guint32 activate_time); +void shell_menu_popdown (ShellMenu *menu); -void shell_menu_set_persistent_source (ShellMenu *behavior, ClutterActor *source); - -void shell_menu_append_separator (ShellMenu *behavior, ClutterActor *separator, BigBoxPackFlags flags); - -void shell_menu_popdown (ShellMenu *behavior); +void shell_menu_set_persistent_source (ShellMenu *menu, + ClutterActor *source); #endif /* __SHELL_MENU_H__ */