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
This commit is contained in:
parent
93f3412f70
commit
2f1ca7bf28
@ -287,6 +287,16 @@ StTooltip {
|
|||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Panel */
|
||||||
|
|
||||||
|
#panelActivities {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panelActivities:pressed {
|
||||||
|
background-color: rgba(50,76,111,0.98);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calendar popup */
|
/* Calendar popup */
|
||||||
|
|
||||||
#calendarPopup {
|
#calendarPopup {
|
||||||
|
@ -4,8 +4,7 @@ dist_jsui_DATA = \
|
|||||||
altTab.js \
|
altTab.js \
|
||||||
appDisplay.js \
|
appDisplay.js \
|
||||||
appFavorites.js \
|
appFavorites.js \
|
||||||
appIcon.js \
|
appIcon.js \
|
||||||
button.js \
|
|
||||||
calendar.js \
|
calendar.js \
|
||||||
chrome.js \
|
chrome.js \
|
||||||
dash.js \
|
dash.js \
|
||||||
|
@ -440,16 +440,18 @@ SwitcherList.prototype = {
|
|||||||
addItem : function(item) {
|
addItem : function(item) {
|
||||||
// We want the St.Bin's padding to be clickable (since it will
|
// We want the St.Bin's padding to be clickable (since it will
|
||||||
// be part of the highlighted background color), so we put the
|
// 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 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);
|
bin.add_actor(item);
|
||||||
bbox.append(bin, Big.BoxPackFlags.NONE);
|
bbox.set_child(bin);
|
||||||
this._list.add_actor(bbox);
|
this._list.add_actor(bbox);
|
||||||
|
|
||||||
let n = this._items.length;
|
let n = this._items.length;
|
||||||
bbox.connect('activate', Lang.bind(this, function () {
|
bbox.connect('clicked', Lang.bind(this, function () {
|
||||||
this._itemActivated(n);
|
this._itemActivated(n);
|
||||||
}));
|
}));
|
||||||
bbox.connect('enter-event', Lang.bind(this, function () {
|
bbox.connect('enter-event', Lang.bind(this, function () {
|
||||||
@ -681,7 +683,7 @@ AppSwitcher.prototype = {
|
|||||||
this.icons.push(appIcon);
|
this.icons.push(appIcon);
|
||||||
this.addItem(appIcon.actor);
|
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.
|
// avoid intercepting the events it wants.
|
||||||
appIcon.actor.reactive = false;
|
appIcon.actor.reactive = false;
|
||||||
|
|
||||||
|
172
js/ui/button.js
172
js/ui/button.js
@ -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" });
|
|
||||||
}
|
|
||||||
};
|
|
@ -16,7 +16,6 @@ const AppDisplay = imports.ui.appDisplay;
|
|||||||
const DocDisplay = imports.ui.docDisplay;
|
const DocDisplay = imports.ui.docDisplay;
|
||||||
const PlaceDisplay = imports.ui.placeDisplay;
|
const PlaceDisplay = imports.ui.placeDisplay;
|
||||||
const GenericDisplay = imports.ui.genericDisplay;
|
const GenericDisplay = imports.ui.genericDisplay;
|
||||||
const Button = imports.ui.button;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
const DEFAULT_PADDING = 4;
|
const DEFAULT_PADDING = 4;
|
||||||
|
@ -13,7 +13,6 @@ const Signals = imports.signals;
|
|||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
const Button = imports.ui.button;
|
|
||||||
const Calendar = imports.ui.calendar;
|
const Calendar = imports.ui.calendar;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const StatusMenu = imports.ui.statusMenu;
|
const StatusMenu = imports.ui.statusMenu;
|
||||||
@ -274,11 +273,12 @@ Panel.prototype = {
|
|||||||
|
|
||||||
/* Button on the left side of the panel. */
|
/* 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". */
|
/* 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,
|
let label = new St.Label({ text: _("Activities") });
|
||||||
PANEL_FOREGROUND_COLOR, DEFAULT_FONT);
|
this.button = new St.Clickable({ name: 'panelActivities' });
|
||||||
this.button.actor.height = PANEL_HEIGHT;
|
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
|
// 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
|
// 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
|
// 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
|
// have the Overview act like a menu that allows the user to release the mouse on the activity the user wants
|
||||||
// to switch to.
|
// to switch to.
|
||||||
this.button.actor.connect('button-press-event', Lang.bind(this, function(b, e) {
|
this.button.connect('clicked', Lang.bind(this, function(b) {
|
||||||
if (e.get_button() == 1 && e.get_click_count() == 1 && !Main.overview.animationInProgress) {
|
let event = Clutter.get_current_event();
|
||||||
|
if (!Main.overview.animationInProgress) {
|
||||||
this._maybeToggleOverviewOnClick();
|
this._maybeToggleOverviewOnClick();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} 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
|
// 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.
|
// and to be released when it is exited regardless of how it was triggered.
|
||||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
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() {
|
Main.overview.connect('hiding', Lang.bind(this, function() {
|
||||||
this.button.actor.active = false;
|
this.button.active = false;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Main.chrome.addActor(this.actor, { visibleInOverview: true });
|
Main.chrome.addActor(this.actor, { visibleInOverview: true });
|
||||||
|
@ -63,8 +63,6 @@ libgnome_shell_la_SOURCES = \
|
|||||||
shell-app-usage.h \
|
shell-app-usage.h \
|
||||||
shell-arrow.c \
|
shell-arrow.c \
|
||||||
shell-arrow.h \
|
shell-arrow.h \
|
||||||
shell-button-box.c \
|
|
||||||
shell-button-box.h \
|
|
||||||
shell-drawing.c \
|
shell-drawing.c \
|
||||||
shell-drawing.h \
|
shell-drawing.h \
|
||||||
shell-embedded-window.c \
|
shell-embedded-window.c \
|
||||||
|
@ -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);
|
|
||||||
}
|
|
@ -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 <clutter/clutter.h>
|
|
||||||
#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__ */
|
|
Loading…
Reference in New Issue
Block a user