From 2f1ca7bf28326073dd95d58215c300b890d0e417 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 16 Nov 2009 14:16:22 -0500 Subject: [PATCH] Remove ShellButtonBox, button.js; Use St.Clickable in panel.js StClickable replaces ShellButtonBox. Reduce the number of button-like things by deleting button.js. To do so, add CSS style for the actitivies button. https://bugzilla.gnome.org/show_bug.cgi?id=602131 --- data/theme/gnome-shell.css | 10 ++ js/ui/Makefile.am | 3 +- js/ui/altTab.js | 12 +- js/ui/button.js | 172 -------------------- js/ui/dash.js | 1 - js/ui/panel.js | 19 +-- src/Makefile.am | 2 - src/shell-button-box.c | 317 ------------------------------------- src/shell-button-box.h | 36 ----- 9 files changed, 28 insertions(+), 544 deletions(-) delete mode 100644 js/ui/button.js delete mode 100644 src/shell-button-box.c delete mode 100644 src/shell-button-box.h diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index 16b6f76b0..ab2d8acce 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -287,6 +287,16 @@ StTooltip { spacing: 4px; } +/* Panel */ + +#panelActivities { + color: #ffffff; +} + +#panelActivities:pressed { + background-color: rgba(50,76,111,0.98); +} + /* Calendar popup */ #calendarPopup { diff --git a/js/ui/Makefile.am b/js/ui/Makefile.am index a74fb862e..4b6260ca2 100644 --- a/js/ui/Makefile.am +++ b/js/ui/Makefile.am @@ -4,8 +4,7 @@ dist_jsui_DATA = \ altTab.js \ appDisplay.js \ appFavorites.js \ - appIcon.js \ - button.js \ + appIcon.js \ calendar.js \ chrome.js \ dash.js \ diff --git a/js/ui/altTab.js b/js/ui/altTab.js index add986fb8..78f8262c7 100644 --- a/js/ui/altTab.js +++ b/js/ui/altTab.js @@ -440,16 +440,18 @@ SwitcherList.prototype = { addItem : function(item) { // We want the St.Bin's padding to be clickable (since it will // be part of the highlighted background color), so we put the - // bin inside the ButtonBox rather than vice versa. + // bin inside the Clickable rather than vice versa. let bin = new St.Bin({ style_class: 'item-box' }); - let bbox = new Shell.ButtonBox({ reactive: true }); + let bbox = new St.Clickable({ reactive: true, + x_fill: true, + y_fill: true }); bin.add_actor(item); - bbox.append(bin, Big.BoxPackFlags.NONE); + bbox.set_child(bin); this._list.add_actor(bbox); let n = this._items.length; - bbox.connect('activate', Lang.bind(this, function () { + bbox.connect('clicked', Lang.bind(this, function () { this._itemActivated(n); })); bbox.connect('enter-event', Lang.bind(this, function () { @@ -681,7 +683,7 @@ AppSwitcher.prototype = { this.icons.push(appIcon); this.addItem(appIcon.actor); - // SwitcherList creates its own Shell.ButtonBox; we want to + // SwitcherList creates its own St.Clickable; we want to // avoid intercepting the events it wants. appIcon.actor.reactive = false; diff --git a/js/ui/button.js b/js/ui/button.js deleted file mode 100644 index 7cae476af..000000000 --- a/js/ui/button.js +++ /dev/null @@ -1,172 +0,0 @@ -/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ - -const Big = imports.gi.Big; -const Clutter = imports.gi.Clutter; -const Lang = imports.lang; -const Mainloop = imports.mainloop; -const Shell = imports.gi.Shell; -const Signals = imports.signals; -const Tweener = imports.ui.tweener; - -const DEFAULT_BUTTON_COLOR = new Clutter.Color(); -DEFAULT_BUTTON_COLOR.from_pixel(0xeeddcc66); - -const DEFAULT_PRESSED_BUTTON_COLOR = new Clutter.Color(); -DEFAULT_PRESSED_BUTTON_COLOR.from_pixel(0xccbbaa66); - -const DEFAULT_TEXT_COLOR = new Clutter.Color(); -DEFAULT_TEXT_COLOR.from_pixel(0x000000ff); - -const DEFAULT_FONT = 'Sans Bold 16px'; - -// Padding on the left and right side of the button. -const SIDE_PADDING = 14; - -function Button(widget, buttonColor, pressedButtonColor, textColor, font) { - this._init(widget, buttonColor, pressedButtonColor, textColor, font); -} - -Button.prototype = { - _init : function(widgetOrText, buttonColor, pressedButtonColor, textColor, font) { - this._buttonColor = buttonColor - if (buttonColor == null) - this._buttonColor = DEFAULT_BUTTON_COLOR; - - this._pressedButtonColor = pressedButtonColor - if (pressedButtonColor == null) - this._pressedButtonColor = DEFAULT_PRESSED_BUTTON_COLOR; - - this._textColor = textColor; - if (textColor == null) - this._textColor = DEFAULT_TEXT_COLOR; - - this._font = font; - if (font == null) - this._font = DEFAULT_FONT; - - this._isBetweenPressAndRelease = false; - this._mouseIsOverButton = false; - - this.actor = new Shell.ButtonBox({ reactive: true, - corner_radius: 5, - padding_left: SIDE_PADDING, - padding_right: SIDE_PADDING, - orientation: Big.BoxOrientation.HORIZONTAL, - y_align: Big.BoxAlignment.CENTER - }); - if (typeof widgetOrText == 'string') { - this._widget = new Clutter.Text({ font_name: this._font, - color: this._textColor, - text: widgetOrText }); - } else { - this._widget = widgetOrText; - } - - this.actor.append(this._widget, Big.BoxPackFlags.EXPAND); - - this.actor.connect('notify::hover', Lang.bind(this, this._updateColors)); - this.actor.connect('notify::pressed', Lang.bind(this, this._updateColors)); - this.actor.connect('notify::active', Lang.bind(this, this._updateColors)); - }, - - _updateColors : function() { - if (this.actor.active || this.actor.pressed) - this.actor.backgroundColor = this._pressedButtonColor; - else if (this.actor.hover) - this.actor.backgroundColor = this._buttonColor; - else - this.actor.backgroundColor = null; - } -}; - -Signals.addSignalMethods(Button.prototype); - -/* Delay before the icon should appear, in seconds after the pointer has entered the parent */ -const ANIMATION_TIME = 0.25; - -/* This is an icon button that fades in/out when mouse enters/leaves the parent. - * A delay is used before the fading starts. You can force it to be shown if needed. - * - * parent -- used to show/hide the button depending on mouse entering/leaving it - * size -- size in pixels of both the button and the icon it contains - * texture -- optional, must be used if the texture for the icon is already created (else, use setIconFromName) - */ -function IconButton(parent, size, texture) { - this._init(parent, size, texture); -} - -IconButton.prototype = { - _init : function(parent, size, texture) { - this._size = size; - if (texture) - this.actor = texture; - else - this.actor = new Clutter.Texture({ width: this._size, height: this._size }); - this.actor.set_reactive(true); - this.actor.set_opacity(0); - parent.connect("enter-event", Lang.bind(this, function(actor, event) { - this._shouldHide = false; - // Nothing to do if the cursor has come back from a child of the parent actor - if (actor.get_children().indexOf(event.get_related()) != -1) - return; - - this._fadeIn(); - })); - parent.connect("leave-event", Lang.bind(this, function(actor, event) { - // Nothing to do if the cursor has merely entered a child of the parent actor - if (actor.get_children().indexOf(event.get_related()) != -1) - return; - - // Remember that we should not be visible to hide the button if forceShow is unset - if (this._forceShow) { - this._shouldHide = true; - return; - } - - this._fadeOut(); - })); - }, - - /// Private methods /// - - setIconFromName : function(iconName) { - let iconTheme = Gtk.IconTheme.get_default(); - let iconInfo = iconTheme.lookup_icon(iconName, this._size, 0); - if (!iconInfo) - return; - - let iconPath = iconInfo.get_filename(); - this.actor.set_from_file(iconPath); - }, - - // Useful if we want to show the button immediately, - // e.g. in case the mouse is already in the parent when the button is created - show : function() { - this.actor.set_opacity(255); - }, - - // If show is true, prevents the button from fading out - forceShow : function(show) { - this._forceShow = show; - // Hide the button if it should have been hidden under normal conditions - if (!this._forceShow && this._shouldHide) { - this._fadeOut(); - } - }, - - /// Private methods /// - - _fadeIn : function() { - Tweener.removeTweens(this.actor); - Tweener.addTween(this.actor, { opacity: 255, - time: ANIMATION_TIME, - transition :"easeInQuad" }); - }, - - _fadeOut : function() { - Tweener.removeTweens(this.actor); - Tweener.addTween(this.actor, { opacity: 0, - time: ANIMATION_TIME, - transition :"easeOutQuad" }); - } -}; diff --git a/js/ui/dash.js b/js/ui/dash.js index 3a2f5e4cb..1fc2184d6 100644 --- a/js/ui/dash.js +++ b/js/ui/dash.js @@ -16,7 +16,6 @@ const AppDisplay = imports.ui.appDisplay; const DocDisplay = imports.ui.docDisplay; const PlaceDisplay = imports.ui.placeDisplay; const GenericDisplay = imports.ui.genericDisplay; -const Button = imports.ui.button; const Main = imports.ui.main; const DEFAULT_PADDING = 4; diff --git a/js/ui/panel.js b/js/ui/panel.js index 6d126a8c6..9ae999b8e 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -13,7 +13,6 @@ const Signals = imports.signals; const Gettext = imports.gettext.domain('gnome-shell'); const _ = Gettext.gettext; -const Button = imports.ui.button; const Calendar = imports.ui.calendar; const Main = imports.ui.main; const StatusMenu = imports.ui.statusMenu; @@ -274,11 +273,12 @@ Panel.prototype = { /* Button on the left side of the panel. */ /* Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview". */ - this.button = new Button.Button(_("Activities"), PANEL_BUTTON_COLOR, PRESSED_BUTTON_BACKGROUND_COLOR, - PANEL_FOREGROUND_COLOR, DEFAULT_FONT); - this.button.actor.height = PANEL_HEIGHT; + let label = new St.Label({ text: _("Activities") }); + this.button = new St.Clickable({ name: 'panelActivities' }); + this.button.set_child(label); + this.button.height = PANEL_HEIGHT; - this._leftBox.append(this.button.actor, Big.BoxPackFlags.NONE); + this._leftBox.append(this.button, Big.BoxPackFlags.NONE); // We use this flag to mark the case where the user has entered the // hot corner and has not left both the hot corner and a surrounding @@ -402,8 +402,9 @@ Panel.prototype = { // We get into the Overview mode on button-press-event as opposed to button-release-event because eventually we'll probably // have the Overview act like a menu that allows the user to release the mouse on the activity the user wants // to switch to. - this.button.actor.connect('button-press-event', Lang.bind(this, function(b, e) { - if (e.get_button() == 1 && e.get_click_count() == 1 && !Main.overview.animationInProgress) { + this.button.connect('clicked', Lang.bind(this, function(b) { + let event = Clutter.get_current_event(); + if (!Main.overview.animationInProgress) { this._maybeToggleOverviewOnClick(); return true; } else { @@ -414,10 +415,10 @@ Panel.prototype = { // pressing the System key, Alt+F1 or Esc. We want the button to be pressed in when the Overview is entered // and to be released when it is exited regardless of how it was triggered. Main.overview.connect('showing', Lang.bind(this, function() { - this.button.actor.active = true; + this.button.active = true; })); Main.overview.connect('hiding', Lang.bind(this, function() { - this.button.actor.active = false; + this.button.active = false; })); Main.chrome.addActor(this.actor, { visibleInOverview: true }); diff --git a/src/Makefile.am b/src/Makefile.am index ed9ae6041..29c36cb80 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -63,8 +63,6 @@ libgnome_shell_la_SOURCES = \ shell-app-usage.h \ shell-arrow.c \ shell-arrow.h \ - shell-button-box.c \ - shell-button-box.h \ shell-drawing.c \ shell-drawing.h \ shell-embedded-window.c \ diff --git a/src/shell-button-box.c b/src/shell-button-box.c deleted file mode 100644 index bd74d732f..000000000 --- a/src/shell-button-box.c +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/** - * SECTION:shell-button-box - * @short_description: A box with properties useful for implementing buttons - * - * A #BigBox subclass which translates lower-level Clutter button events - * into higher level properties which are useful for implementing "button-like" - * actors. - */ - -#include "shell-button-box.h" - -G_DEFINE_TYPE(ShellButtonBox, shell_button_box, BIG_TYPE_BOX); - -struct _ShellButtonBoxPrivate { - gboolean active; - gboolean held; - gboolean hover; - gboolean pressed; -}; - -/* Signals */ -enum -{ - ACTIVATE, - LAST_SIGNAL -}; - -enum { - PROP_0, - - PROP_ACTIVE, - PROP_HOVER, - PROP_PRESSED, -}; - -static guint shell_button_box_signals [LAST_SIGNAL] = { 0 }; - -static void -set_active (ShellButtonBox *box, - gboolean active) -{ - if (box->priv->active == active) - return; - box->priv->active = active; - g_object_notify (G_OBJECT (box), "active"); -} - -static void -set_hover (ShellButtonBox *box, - gboolean hover) -{ - if (box->priv->hover == hover) - return; - box->priv->hover = hover; - g_object_notify (G_OBJECT (box), "hover"); -} - -static void -set_pressed (ShellButtonBox *box, - gboolean pressed) -{ - if (box->priv->pressed == pressed) - return; - box->priv->pressed = pressed; - g_object_notify (G_OBJECT (box), "pressed"); -} - -static gboolean -shell_button_box_contains (ShellButtonBox *box, - ClutterActor *actor) -{ - while (actor != NULL && actor != (ClutterActor*)box) - { - actor = clutter_actor_get_parent (actor); - } - return actor != NULL; -} - -static gboolean -shell_button_box_enter_event (ClutterActor *actor, - ClutterCrossingEvent *event) -{ - ShellButtonBox *box = SHELL_BUTTON_BOX (actor); - - if (shell_button_box_contains (box, event->related)) - return TRUE; - if (!shell_button_box_contains (box, event->source)) - return TRUE; - - g_object_freeze_notify (G_OBJECT (actor)); - - if (box->priv->held) - set_pressed (box, TRUE); - set_hover (box, TRUE); - - g_object_thaw_notify (G_OBJECT (actor)); - - return TRUE; -} - -static gboolean -shell_button_box_leave_event (ClutterActor *actor, - ClutterCrossingEvent *event) -{ - ShellButtonBox *box = SHELL_BUTTON_BOX (actor); - - if (shell_button_box_contains (box, event->related)) - return TRUE; - - set_hover (box, FALSE); - set_pressed (box, FALSE); - - return TRUE; -} - -static gboolean -shell_button_box_button_press_event (ClutterActor *actor, - ClutterButtonEvent *event) -{ - ShellButtonBox *box = SHELL_BUTTON_BOX (actor); - - if (event->button != 1 || event->click_count != 1) - return FALSE; - - if (box->priv->held) - return TRUE; - - if (!shell_button_box_contains (box, event->source)) - return FALSE; - - box->priv->held = TRUE; - clutter_grab_pointer (CLUTTER_ACTOR (box)); - - set_pressed (box, TRUE); - - return TRUE; -} - -static gboolean -shell_button_box_button_release_event (ClutterActor *actor, - ClutterButtonEvent *event) -{ - ShellButtonBox *box = SHELL_BUTTON_BOX (actor); - - if (event->button != 1 || event->click_count != 1) - return FALSE; - - if (!box->priv->held) - return TRUE; - - box->priv->held = FALSE; - clutter_ungrab_pointer (); - - if (!shell_button_box_contains (box, event->source)) - return FALSE; - - set_pressed (box, FALSE); - - g_signal_emit (G_OBJECT (box), shell_button_box_signals[ACTIVATE], 0, event); - - return TRUE; -} - -/** - * shell_button_box_fake_release: - * @box: - * - * If this button box is holding a pointer grab, this function will - * will ungrab it, and reset the pressed state. The effect is - * similar to if the user had released the mouse button, but without - * emitting the activate signal. - * - * This function is useful if for example you want to do something after the user - * is holding the mouse button for a given period of time, breaking the - * grab. - */ -void -shell_button_box_fake_release (ShellButtonBox *box) -{ - if (!box->priv->held) - return; - - box->priv->held = FALSE; - clutter_ungrab_pointer (); - - set_pressed (box, FALSE); -} - -static void -shell_button_box_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ShellButtonBox *box = SHELL_BUTTON_BOX (object); - - switch (prop_id) - { - case PROP_ACTIVE: - set_active (box, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -shell_button_box_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ShellButtonBox *box = SHELL_BUTTON_BOX (object); - - switch (prop_id) - { - case PROP_ACTIVE: - g_value_set_boolean (value, box->priv->active); - break; - case PROP_PRESSED: - g_value_set_boolean (value, box->priv->pressed); - break; - case PROP_HOVER: - g_value_set_boolean (value, box->priv->hover); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -shell_button_box_class_init (ShellButtonBoxClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - gobject_class->get_property = shell_button_box_get_property; - gobject_class->set_property = shell_button_box_set_property; - - actor_class->enter_event = shell_button_box_enter_event; - actor_class->leave_event = shell_button_box_leave_event; - actor_class->button_press_event = shell_button_box_button_press_event; - actor_class->button_release_event = shell_button_box_button_release_event; - - /** - * ShellButtonBox::activate - * @box: The #ShellButtonBox - * @event: Release event which triggered the activation - * - * This signal is emitted when the button should take the action - * associated with button click+release. - */ - shell_button_box_signals[ACTIVATE] = - g_signal_new ("activate", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 1, CLUTTER_TYPE_EVENT); - - /** - * ShellButtonBox:active - * - * The property allows the button to be used as a "toggle button"; it's up to the - * application to update the active property in response to the activate signal; - * it doesn't happen automatically. - */ - g_object_class_install_property (gobject_class, - PROP_ACTIVE, - g_param_spec_boolean ("active", - "Active", - "Whether the button persistently active", - FALSE, - G_PARAM_READWRITE)); - - /** - * ShellButtonBox:hover - * - * This property tracks whether the mouse is over the button; note this - * state is independent of whether the button is pressed. - */ - g_object_class_install_property (gobject_class, - PROP_HOVER, - g_param_spec_boolean ("hover", - "Hovering state", - "Whether the mouse is over the button", - FALSE, - G_PARAM_READABLE)); - - /** - * ShellButtonBox:pressed - * - * This property tracks whether the button should have a "pressed in" - * effect. - */ - g_object_class_install_property (gobject_class, - PROP_PRESSED, - g_param_spec_boolean ("pressed", - "Pressed state", - "Whether the button is currently pressed", - FALSE, - G_PARAM_READABLE)); - - g_type_class_add_private (gobject_class, sizeof (ShellButtonBoxPrivate)); -} - -static void -shell_button_box_init (ShellButtonBox *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SHELL_TYPE_BUTTON_BOX, - ShellButtonBoxPrivate); -} diff --git a/src/shell-button-box.h b/src/shell-button-box.h deleted file mode 100644 index 3ebe8d772..000000000 --- a/src/shell-button-box.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -#ifndef __SHELL_BUTTON_BOX_H__ -#define __SHELL_BUTTON_BOX_H__ - -#include -#include "big/box.h" - -#define SHELL_TYPE_BUTTON_BOX (shell_button_box_get_type ()) -#define SHELL_BUTTON_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_BUTTON_BOX, ShellButtonBox)) -#define SHELL_BUTTON_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_BUTTON_BOX, ShellButtonBoxClass)) -#define SHELL_IS_BUTTON_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_BUTTON_BOX)) -#define SHELL_IS_BUTTON_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_BUTTON_BOX)) -#define SHELL_BUTTON_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_BUTTON_BOX, ShellButtonBoxClass)) - -typedef struct _ShellButtonBox ShellButtonBox; -typedef struct _ShellButtonBoxClass ShellButtonBoxClass; - -typedef struct _ShellButtonBoxPrivate ShellButtonBoxPrivate; - -struct _ShellButtonBox -{ - BigBox parent; - - ShellButtonBoxPrivate *priv; -}; - -struct _ShellButtonBoxClass -{ - BigBoxClass parent_class; -}; - -GType shell_button_box_get_type (void) G_GNUC_CONST; - -void shell_button_box_fake_release (ShellButtonBox *box); - -#endif /* __SHELL_BUTTON_BOX_H__ */