St: drop StClickable, add some functionality to StButton
For historical reasons, we had both StClickable and StButton, which were nearly identical. StButton was more widely-used, so keep that and port all StClickable users to that. https://bugzilla.gnome.org/show_bug.cgi?id=640583
This commit is contained in:
parent
c256fa9b9f
commit
c86a977564
@ -217,7 +217,7 @@ StTooltip StLabel {
|
|||||||
transition-duration: 100;
|
transition-duration: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-button:active, .panel-button:checked, .panel-button:pressed, .panel-button:focus {
|
.panel-button:active, .panel-button:checked, .panel-button:focus {
|
||||||
background-gradient-direction: vertical;
|
background-gradient-direction: vertical;
|
||||||
background-gradient-start: #3c3c3c;
|
background-gradient-start: #3c3c3c;
|
||||||
background-gradient-end: #131313;
|
background-gradient-end: #131313;
|
||||||
@ -541,11 +541,6 @@ StTooltip StLabel {
|
|||||||
transition-duration: 100;
|
transition-duration: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-well-app:active > .overview-icon {
|
|
||||||
background-color: #1e1e1e;
|
|
||||||
border: 1px solid #5f5f5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-well-menu {
|
.app-well-menu {
|
||||||
font-size: 12px
|
font-size: 12px
|
||||||
}
|
}
|
||||||
|
@ -593,7 +593,7 @@ SwitcherList.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
addItem : function(item) {
|
addItem : function(item) {
|
||||||
let bbox = new St.Clickable({ style_class: 'item-box',
|
let bbox = new St.Button({ style_class: 'item-box',
|
||||||
reactive: true });
|
reactive: true });
|
||||||
|
|
||||||
bbox.set_child(item);
|
bbox.set_child(item);
|
||||||
|
@ -319,8 +319,9 @@ function AppWellIcon(app, iconParams) {
|
|||||||
AppWellIcon.prototype = {
|
AppWellIcon.prototype = {
|
||||||
_init : function(app, iconParams) {
|
_init : function(app, iconParams) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.actor = new St.Clickable({ style_class: 'app-well-app',
|
this.actor = new St.Button({ style_class: 'app-well-app',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
@ -390,12 +391,11 @@ AppWellIcon.prototype = {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClicked: function(actor, event) {
|
_onClicked: function(actor, button) {
|
||||||
this._removeMenuTimeout();
|
this._removeMenuTimeout();
|
||||||
|
|
||||||
let button = event.get_button();
|
|
||||||
if (button == 1) {
|
if (button == 1) {
|
||||||
this._onActivate(event);
|
this._onActivate(Clutter.get_current_event());
|
||||||
} else if (button == 2) {
|
} else if (button == 2) {
|
||||||
let newWorkspace = Main.overview.workspaces.addWorkspace();
|
let newWorkspace = Main.overview.workspaces.addWorkspace();
|
||||||
if (newWorkspace != null) {
|
if (newWorkspace != null) {
|
||||||
|
10
js/ui/dnd.js
10
js/ui/dnd.js
@ -112,11 +112,11 @@ _Draggable.prototype = {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
this._buttonDown = true;
|
this._buttonDown = true;
|
||||||
// special case St.Clickable: grabbing the pointer would mess up the
|
// special case St.Button: grabbing the pointer would mess up the
|
||||||
// internal state, so we start the drag manually on hover change
|
// internal state, so we start the drag manually on hover change
|
||||||
if (this.actor instanceof St.Clickable)
|
if (this.actor instanceof St.Button)
|
||||||
this.actor.connect('notify::hover',
|
this.actor.connect('notify::hover',
|
||||||
Lang.bind(this, this._onClickableHoverChanged));
|
Lang.bind(this, this._onButtonHoverChanged));
|
||||||
else
|
else
|
||||||
this._grabActor();
|
this._grabActor();
|
||||||
|
|
||||||
@ -127,8 +127,8 @@ _Draggable.prototype = {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClickableHoverChanged: function(button) {
|
_onButtonHoverChanged: function(button) {
|
||||||
if (button.hover || !button.held)
|
if (button.hover || !button.pressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
button.fake_release();
|
button.fake_release();
|
||||||
|
@ -137,7 +137,7 @@ ListItem.prototype = {
|
|||||||
|
|
||||||
let layout = new St.BoxLayout({ vertical: false});
|
let layout = new St.BoxLayout({ vertical: false});
|
||||||
|
|
||||||
this.actor = new St.Clickable({ style_class: 'end-session-dialog-app-list-item',
|
this.actor = new St.Button({ style_class: 'end-session-dialog-app-list-item',
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
child: layout,
|
child: layout,
|
||||||
reactive: true,
|
reactive: true,
|
||||||
|
@ -612,7 +612,7 @@ 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". */
|
||||||
let label = new St.Label({ text: _("Activities") });
|
let label = new St.Label({ text: _("Activities") });
|
||||||
this.button = new St.Clickable({ name: 'panelActivities',
|
this.button = new St.Button({ name: 'panelActivities',
|
||||||
style_class: 'panel-button',
|
style_class: 'panel-button',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
can_focus: true });
|
can_focus: true });
|
||||||
@ -712,7 +712,7 @@ 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.connect('clicked', Lang.bind(this, function(b, event) {
|
this.button.connect('clicked', Lang.bind(this, function(b) {
|
||||||
if (!Main.overview.animationInProgress) {
|
if (!Main.overview.animationInProgress) {
|
||||||
this._maybeToggleOverviewOnClick();
|
this._maybeToggleOverviewOnClick();
|
||||||
return true;
|
return true;
|
||||||
@ -724,10 +724,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.active = true;
|
this.button.checked = true;
|
||||||
}));
|
}));
|
||||||
Main.overview.connect('hiding', Lang.bind(this, function() {
|
Main.overview.connect('hiding', Lang.bind(this, function() {
|
||||||
this.button.active = false;
|
this.button.checked = false;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Main.chrome.addActor(this.actor, { visibleInOverview: true });
|
Main.chrome.addActor(this.actor, { visibleInOverview: true });
|
||||||
|
@ -24,7 +24,7 @@ SearchResult.prototype = {
|
|||||||
_init: function(provider, metaInfo, terms) {
|
_init: function(provider, metaInfo, terms) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.metaInfo = metaInfo;
|
this.metaInfo = metaInfo;
|
||||||
this.actor = new St.Clickable({ style_class: 'search-result',
|
this.actor = new St.Button({ style_class: 'search-result',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
@ -69,7 +69,7 @@ SearchResult.prototype = {
|
|||||||
Main.overview.toggle();
|
Main.overview.toggle();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onResultClicked: function(actor, event) {
|
_onResultClicked: function(actor) {
|
||||||
this.activate();
|
this.activate();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -221,23 +221,23 @@ SearchResults.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_createOpenSearchProviderButton: function(provider) {
|
_createOpenSearchProviderButton: function(provider) {
|
||||||
let clickable = new St.Clickable({ style_class: 'dash-search-button',
|
let button = new St.Button({ style_class: 'dash-search-button',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_align: St.Align.MIDDLE });
|
y_align: St.Align.MIDDLE });
|
||||||
let bin = new St.Bin({ x_fill: false,
|
let bin = new St.Bin({ x_fill: false,
|
||||||
x_align:St.Align.MIDDLE });
|
x_align:St.Align.MIDDLE });
|
||||||
clickable.connect('clicked', Lang.bind(this, function() {
|
button.connect('clicked', Lang.bind(this, function() {
|
||||||
this._openSearchSystem.activateResult(provider.id);
|
this._openSearchSystem.activateResult(provider.id);
|
||||||
}));
|
}));
|
||||||
let title = new St.Label({ text: provider.name,
|
let title = new St.Label({ text: provider.name,
|
||||||
style_class: 'dash-search-button-label' });
|
style_class: 'dash-search-button-label' });
|
||||||
|
|
||||||
bin.set_child(title);
|
bin.set_child(title);
|
||||||
clickable.set_child(bin);
|
button.set_child(bin);
|
||||||
provider.actor = clickable;
|
provider.actor = button;
|
||||||
|
|
||||||
this._searchProvidersBox.add(clickable);
|
this._searchProvidersBox.add(button);
|
||||||
},
|
},
|
||||||
|
|
||||||
createProviderMeta: function(provider) {
|
createProviderMeta: function(provider) {
|
||||||
|
@ -72,7 +72,6 @@ st_source_h = \
|
|||||||
st/st-box-layout.h \
|
st/st-box-layout.h \
|
||||||
st/st-box-layout-child.h \
|
st/st-box-layout-child.h \
|
||||||
st/st-button.h \
|
st/st-button.h \
|
||||||
st/st-clickable.h \
|
|
||||||
st/st-clipboard.h \
|
st/st-clipboard.h \
|
||||||
st/st-container.h \
|
st/st-container.h \
|
||||||
st/st-drawing-area.h \
|
st/st-drawing-area.h \
|
||||||
@ -130,7 +129,6 @@ st_source_c = \
|
|||||||
st/st-box-layout.c \
|
st/st-box-layout.c \
|
||||||
st/st-box-layout-child.c \
|
st/st-box-layout-child.c \
|
||||||
st/st-button.c \
|
st/st-button.c \
|
||||||
st/st-clickable.c \
|
|
||||||
st/st-clipboard.c \
|
st/st-clipboard.c \
|
||||||
st/st-container.c \
|
st/st-container.c \
|
||||||
st/st-drawing-area.c \
|
st/st-drawing-area.c \
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
#include "st-button.h"
|
#include "st-button.h"
|
||||||
|
|
||||||
|
#include "st-enum-types.h"
|
||||||
#include "st-marshal.h"
|
#include "st-marshal.h"
|
||||||
#include "st-texture-cache.h"
|
#include "st-texture-cache.h"
|
||||||
#include "st-private.h"
|
#include "st-private.h"
|
||||||
@ -49,8 +50,10 @@ enum
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_LABEL,
|
PROP_LABEL,
|
||||||
|
PROP_BUTTON_MASK,
|
||||||
PROP_TOGGLE_MODE,
|
PROP_TOGGLE_MODE,
|
||||||
PROP_CHECKED
|
PROP_CHECKED,
|
||||||
|
PROP_PRESSED
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -67,10 +70,12 @@ struct _StButtonPrivate
|
|||||||
{
|
{
|
||||||
gchar *text;
|
gchar *text;
|
||||||
|
|
||||||
guint is_pressed : 1;
|
guint button_mask : 3;
|
||||||
guint is_checked : 1;
|
|
||||||
guint is_toggle : 1;
|
guint is_toggle : 1;
|
||||||
guint has_grab : 1;
|
|
||||||
|
guint pressed : 3;
|
||||||
|
guint grabbed : 3;
|
||||||
|
guint is_checked : 1;
|
||||||
|
|
||||||
gint spacing;
|
gint spacing;
|
||||||
};
|
};
|
||||||
@ -119,31 +124,32 @@ st_button_style_changed (StWidget *widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st_button_press (StButton *button)
|
st_button_press (StButton *button,
|
||||||
|
StButtonMask mask)
|
||||||
{
|
{
|
||||||
if (button->priv->is_pressed)
|
if (button->priv->pressed == 0)
|
||||||
return;
|
|
||||||
|
|
||||||
button->priv->is_pressed = TRUE;
|
|
||||||
st_widget_add_style_pseudo_class (ST_WIDGET (button), "active");
|
st_widget_add_style_pseudo_class (ST_WIDGET (button), "active");
|
||||||
|
|
||||||
|
button->priv->pressed |= mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st_button_release (StButton *button,
|
st_button_release (StButton *button,
|
||||||
gboolean clicked)
|
StButtonMask mask,
|
||||||
|
int clicked_button)
|
||||||
{
|
{
|
||||||
if (!button->priv->is_pressed)
|
button->priv->pressed &= ~mask;
|
||||||
|
if (button->priv->pressed != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
button->priv->is_pressed = FALSE;
|
|
||||||
st_widget_remove_style_pseudo_class (ST_WIDGET (button), "active");
|
st_widget_remove_style_pseudo_class (ST_WIDGET (button), "active");
|
||||||
|
|
||||||
if (clicked)
|
if (clicked_button)
|
||||||
{
|
{
|
||||||
if (button->priv->is_toggle)
|
if (button->priv->is_toggle)
|
||||||
st_button_set_checked (button, !button->priv->is_checked);
|
st_button_set_checked (button, !button->priv->is_checked);
|
||||||
|
|
||||||
g_signal_emit (button, button_signals[CLICKED], 0);
|
g_signal_emit (button, button_signals[CLICKED], 0, clicked_button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,15 +157,18 @@ static gboolean
|
|||||||
st_button_button_press (ClutterActor *actor,
|
st_button_button_press (ClutterActor *actor,
|
||||||
ClutterButtonEvent *event)
|
ClutterButtonEvent *event)
|
||||||
{
|
{
|
||||||
|
StButton *button = ST_BUTTON (actor);
|
||||||
|
StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button);
|
||||||
|
|
||||||
st_widget_hide_tooltip (ST_WIDGET (actor));
|
st_widget_hide_tooltip (ST_WIDGET (actor));
|
||||||
|
|
||||||
if (event->button == 1)
|
if (button->priv->button_mask & mask)
|
||||||
{
|
{
|
||||||
StButton *button = ST_BUTTON (actor);
|
if (button->priv->grabbed == 0)
|
||||||
|
|
||||||
clutter_grab_pointer (actor);
|
clutter_grab_pointer (actor);
|
||||||
button->priv->has_grab = TRUE;
|
|
||||||
st_button_press (button);
|
button->priv->grabbed |= mask;
|
||||||
|
st_button_press (button, mask);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -171,19 +180,19 @@ static gboolean
|
|||||||
st_button_button_release (ClutterActor *actor,
|
st_button_button_release (ClutterActor *actor,
|
||||||
ClutterButtonEvent *event)
|
ClutterButtonEvent *event)
|
||||||
{
|
{
|
||||||
if (event->button == 1)
|
|
||||||
{
|
|
||||||
StButton *button = ST_BUTTON (actor);
|
StButton *button = ST_BUTTON (actor);
|
||||||
|
StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button);
|
||||||
|
|
||||||
|
if (button->priv->button_mask & mask)
|
||||||
|
{
|
||||||
gboolean is_click;
|
gboolean is_click;
|
||||||
|
|
||||||
is_click = button->priv->has_grab && st_widget_get_hover (ST_WIDGET (button));
|
is_click = button->priv->grabbed && st_widget_get_hover (ST_WIDGET (button));
|
||||||
st_button_release (button, is_click);
|
st_button_release (button, mask, is_click ? event->button : 0);
|
||||||
|
|
||||||
if (button->priv->has_grab)
|
button->priv->grabbed &= ~mask;
|
||||||
{
|
if (button->priv->grabbed == 0)
|
||||||
button->priv->has_grab = FALSE;
|
|
||||||
clutter_ungrab_pointer ();
|
clutter_ungrab_pointer ();
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -195,14 +204,19 @@ static gboolean
|
|||||||
st_button_key_press (ClutterActor *actor,
|
st_button_key_press (ClutterActor *actor,
|
||||||
ClutterKeyEvent *event)
|
ClutterKeyEvent *event)
|
||||||
{
|
{
|
||||||
|
StButton *button = ST_BUTTON (actor);
|
||||||
|
|
||||||
st_widget_hide_tooltip (ST_WIDGET (actor));
|
st_widget_hide_tooltip (ST_WIDGET (actor));
|
||||||
|
|
||||||
|
if (button->priv->button_mask & ST_BUTTON_ONE)
|
||||||
|
{
|
||||||
if (event->keyval == CLUTTER_KEY_space ||
|
if (event->keyval == CLUTTER_KEY_space ||
|
||||||
event->keyval == CLUTTER_KEY_Return)
|
event->keyval == CLUTTER_KEY_Return)
|
||||||
{
|
{
|
||||||
st_button_press (ST_BUTTON (actor));
|
st_button_press (button, ST_BUTTON_ONE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -211,16 +225,34 @@ static gboolean
|
|||||||
st_button_key_release (ClutterActor *actor,
|
st_button_key_release (ClutterActor *actor,
|
||||||
ClutterKeyEvent *event)
|
ClutterKeyEvent *event)
|
||||||
{
|
{
|
||||||
|
StButton *button = ST_BUTTON (actor);
|
||||||
|
|
||||||
|
if (button->priv->button_mask & ST_BUTTON_ONE)
|
||||||
|
{
|
||||||
if (event->keyval == CLUTTER_KEY_space ||
|
if (event->keyval == CLUTTER_KEY_space ||
|
||||||
event->keyval == CLUTTER_KEY_Return)
|
event->keyval == CLUTTER_KEY_Return)
|
||||||
{
|
{
|
||||||
st_button_release (ST_BUTTON (actor), TRUE);
|
st_button_release (button, ST_BUTTON_ONE, 1);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
st_button_key_focus_out (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
StButton *button = ST_BUTTON (actor);
|
||||||
|
|
||||||
|
/* If we lose focus between a key press and release, undo the press */
|
||||||
|
if ((button->priv->pressed & ST_BUTTON_ONE) &&
|
||||||
|
!(button->priv->grabbed & ST_BUTTON_ONE))
|
||||||
|
st_button_release (button, ST_BUTTON_ONE, 0);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (st_button_parent_class)->key_focus_out (actor);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
st_button_enter (ClutterActor *actor,
|
st_button_enter (ClutterActor *actor,
|
||||||
ClutterCrossingEvent *event)
|
ClutterCrossingEvent *event)
|
||||||
@ -230,12 +262,12 @@ st_button_enter (ClutterActor *actor,
|
|||||||
|
|
||||||
ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->enter_event (actor, event);
|
ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->enter_event (actor, event);
|
||||||
|
|
||||||
if (button->priv->has_grab)
|
if (button->priv->grabbed)
|
||||||
{
|
{
|
||||||
if (st_widget_get_hover (ST_WIDGET (button)))
|
if (st_widget_get_hover (ST_WIDGET (button)))
|
||||||
st_button_press (button);
|
st_button_press (button, button->priv->grabbed);
|
||||||
else
|
else
|
||||||
st_button_release (button, FALSE);
|
st_button_release (button, button->priv->grabbed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -250,12 +282,12 @@ st_button_leave (ClutterActor *actor,
|
|||||||
|
|
||||||
ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event);
|
ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event);
|
||||||
|
|
||||||
if (button->priv->has_grab)
|
if (button->priv->grabbed)
|
||||||
{
|
{
|
||||||
if (st_widget_get_hover (ST_WIDGET (button)))
|
if (st_widget_get_hover (ST_WIDGET (button)))
|
||||||
st_button_press (button);
|
st_button_press (button, button->priv->grabbed);
|
||||||
else
|
else
|
||||||
st_button_release (button, FALSE);
|
st_button_release (button, button->priv->grabbed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -274,6 +306,9 @@ st_button_set_property (GObject *gobject,
|
|||||||
case PROP_LABEL:
|
case PROP_LABEL:
|
||||||
st_button_set_label (button, g_value_get_string (value));
|
st_button_set_label (button, g_value_get_string (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_BUTTON_MASK:
|
||||||
|
st_button_set_button_mask (button, g_value_get_flags (value));
|
||||||
|
break;
|
||||||
case PROP_TOGGLE_MODE:
|
case PROP_TOGGLE_MODE:
|
||||||
st_button_set_toggle_mode (button, g_value_get_boolean (value));
|
st_button_set_toggle_mode (button, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
@ -301,12 +336,18 @@ st_button_get_property (GObject *gobject,
|
|||||||
case PROP_LABEL:
|
case PROP_LABEL:
|
||||||
g_value_set_string (value, priv->text);
|
g_value_set_string (value, priv->text);
|
||||||
break;
|
break;
|
||||||
|
case PROP_BUTTON_MASK:
|
||||||
|
g_value_set_flags (value, priv->button_mask);
|
||||||
|
break;
|
||||||
case PROP_TOGGLE_MODE:
|
case PROP_TOGGLE_MODE:
|
||||||
g_value_set_boolean (value, priv->is_toggle);
|
g_value_set_boolean (value, priv->is_toggle);
|
||||||
break;
|
break;
|
||||||
case PROP_CHECKED:
|
case PROP_CHECKED:
|
||||||
g_value_set_boolean (value, priv->is_checked);
|
g_value_set_boolean (value, priv->is_checked);
|
||||||
break;
|
break;
|
||||||
|
case PROP_PRESSED:
|
||||||
|
g_value_set_boolean (value, priv->pressed != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -343,6 +384,7 @@ st_button_class_init (StButtonClass *klass)
|
|||||||
actor_class->button_release_event = st_button_button_release;
|
actor_class->button_release_event = st_button_button_release;
|
||||||
actor_class->key_press_event = st_button_key_press;
|
actor_class->key_press_event = st_button_key_press;
|
||||||
actor_class->key_release_event = st_button_key_release;
|
actor_class->key_release_event = st_button_key_release;
|
||||||
|
actor_class->key_focus_out = st_button_key_focus_out;
|
||||||
actor_class->enter_event = st_button_enter;
|
actor_class->enter_event = st_button_enter;
|
||||||
actor_class->leave_event = st_button_leave;
|
actor_class->leave_event = st_button_leave;
|
||||||
|
|
||||||
@ -354,6 +396,13 @@ st_button_class_init (StButtonClass *klass)
|
|||||||
NULL, G_PARAM_READWRITE);
|
NULL, G_PARAM_READWRITE);
|
||||||
g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
|
g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_flags ("button-mask",
|
||||||
|
"Button mask",
|
||||||
|
"Which buttons trigger the 'clicked' signal",
|
||||||
|
ST_TYPE_BUTTON_MASK, ST_BUTTON_ONE,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_BUTTON_MASK, pspec);
|
||||||
|
|
||||||
pspec = g_param_spec_boolean ("toggle-mode",
|
pspec = g_param_spec_boolean ("toggle-mode",
|
||||||
"Toggle Mode",
|
"Toggle Mode",
|
||||||
"Enable or disable toggling",
|
"Enable or disable toggling",
|
||||||
@ -367,23 +416,30 @@ st_button_class_init (StButtonClass *klass)
|
|||||||
FALSE, G_PARAM_READWRITE);
|
FALSE, G_PARAM_READWRITE);
|
||||||
g_object_class_install_property (gobject_class, PROP_CHECKED, pspec);
|
g_object_class_install_property (gobject_class, PROP_CHECKED, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_boolean ("pressed",
|
||||||
|
"Pressed",
|
||||||
|
"Indicates if the button is pressed in",
|
||||||
|
FALSE, G_PARAM_READABLE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_PRESSED, pspec);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StButton::clicked:
|
* StButton::clicked:
|
||||||
* @button: the object that received the signal
|
* @button: the object that received the signal
|
||||||
|
* @clicked_button: the mouse button that was used
|
||||||
*
|
*
|
||||||
* Emitted when the user activates the button, either with a mouse press and
|
* Emitted when the user activates the button, either with a mouse press and
|
||||||
* release or with the keyboard.
|
* release or with the keyboard.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
button_signals[CLICKED] =
|
button_signals[CLICKED] =
|
||||||
g_signal_new ("clicked",
|
g_signal_new ("clicked",
|
||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (StButtonClass, clicked),
|
G_STRUCT_OFFSET (StButtonClass, clicked),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
_st_marshal_VOID__VOID,
|
_st_marshal_VOID__INT,
|
||||||
G_TYPE_NONE, 0);
|
G_TYPE_NONE, 1,
|
||||||
|
G_TYPE_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -391,6 +447,7 @@ st_button_init (StButton *button)
|
|||||||
{
|
{
|
||||||
button->priv = ST_BUTTON_GET_PRIVATE (button);
|
button->priv = ST_BUTTON_GET_PRIVATE (button);
|
||||||
button->priv->spacing = 6;
|
button->priv->spacing = 6;
|
||||||
|
button->priv->button_mask = ST_BUTTON_ONE;
|
||||||
|
|
||||||
clutter_actor_set_reactive (CLUTTER_ACTOR (button), TRUE);
|
clutter_actor_set_reactive (CLUTTER_ACTOR (button), TRUE);
|
||||||
st_widget_set_track_hover (ST_WIDGET (button), TRUE);
|
st_widget_set_track_hover (ST_WIDGET (button), TRUE);
|
||||||
@ -431,7 +488,7 @@ st_button_new_with_label (const gchar *text)
|
|||||||
*
|
*
|
||||||
* Returns: the text for the button. This must not be freed by the application
|
* Returns: the text for the button. This must not be freed by the application
|
||||||
*/
|
*/
|
||||||
G_CONST_RETURN gchar *
|
const gchar *
|
||||||
st_button_get_label (StButton *button)
|
st_button_get_label (StButton *button)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (ST_IS_BUTTON (button), NULL);
|
g_return_val_if_fail (ST_IS_BUTTON (button), NULL);
|
||||||
@ -487,6 +544,42 @@ st_button_set_label (StButton *button,
|
|||||||
g_object_notify (G_OBJECT (button), "label");
|
g_object_notify (G_OBJECT (button), "label");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_button_get_button_mask:
|
||||||
|
* @button: a #StButton
|
||||||
|
*
|
||||||
|
* Gets the mask of mouse buttons that @button emits the
|
||||||
|
* #StButton::clicked signal for.
|
||||||
|
*
|
||||||
|
* Returns: the mask of mouse buttons that @button emits the
|
||||||
|
* #StButton::clicked signal for.
|
||||||
|
*/
|
||||||
|
StButtonMask
|
||||||
|
st_button_get_button_mask (StButton *button)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ST_IS_BUTTON (button), 0);
|
||||||
|
|
||||||
|
return button->priv->button_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_button_set_button_mask:
|
||||||
|
* @button: a #Stbutton
|
||||||
|
* @mask: the mask of mouse buttons that @button responds to
|
||||||
|
*
|
||||||
|
* Sets which mouse buttons @button emits #StButton::clicked for.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_button_set_button_mask (StButton *button,
|
||||||
|
StButtonMask mask)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ST_IS_BUTTON (button));
|
||||||
|
|
||||||
|
button->priv->button_mask = mask;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (button), "button-mask");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_button_get_toggle_mode:
|
* st_button_get_toggle_mode:
|
||||||
* @button: a #StButton
|
* @button: a #StButton
|
||||||
@ -564,3 +657,29 @@ st_button_set_checked (StButton *button,
|
|||||||
|
|
||||||
g_object_notify (G_OBJECT (button), "checked");
|
g_object_notify (G_OBJECT (button), "checked");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_button_fake_release:
|
||||||
|
* @button: an #StButton
|
||||||
|
*
|
||||||
|
* If this widget 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 clicked 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
|
||||||
|
st_button_fake_release (StButton *button)
|
||||||
|
{
|
||||||
|
if (button->priv->pressed)
|
||||||
|
st_button_release (button, button->priv->pressed, 0);
|
||||||
|
|
||||||
|
if (button->priv->grabbed)
|
||||||
|
{
|
||||||
|
button->priv->grabbed = 0;
|
||||||
|
clutter_ungrab_pointer ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -68,9 +68,9 @@ struct _StButtonClass
|
|||||||
|
|
||||||
GType st_button_get_type (void) G_GNUC_CONST;
|
GType st_button_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
StWidget * st_button_new (void);
|
StWidget *st_button_new (void);
|
||||||
StWidget * st_button_new_with_label (const gchar *text);
|
StWidget *st_button_new_with_label (const gchar *text);
|
||||||
G_CONST_RETURN gchar *st_button_get_label (StButton *button);
|
const gchar *st_button_get_label (StButton *button);
|
||||||
void st_button_set_label (StButton *button,
|
void st_button_set_label (StButton *button,
|
||||||
const gchar *text);
|
const gchar *text);
|
||||||
void st_button_set_toggle_mode (StButton *button,
|
void st_button_set_toggle_mode (StButton *button,
|
||||||
@ -80,6 +80,28 @@ void st_button_set_checked (StButton *button,
|
|||||||
gboolean checked);
|
gboolean checked);
|
||||||
gboolean st_button_get_checked (StButton *button);
|
gboolean st_button_get_checked (StButton *button);
|
||||||
|
|
||||||
|
void st_button_fake_release (StButton *button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StButtonMask:
|
||||||
|
* @ST_BUTTON_ONE: button 1 (left)
|
||||||
|
* @ST_BUTTON_TWO: button 2 (middle)
|
||||||
|
* @ST_BUTTON_THREE: button 3 (right)
|
||||||
|
*
|
||||||
|
* A mask representing which mouse buttons an StButton responds to.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ST_BUTTON_ONE = (1 << 0),
|
||||||
|
ST_BUTTON_TWO = (1 << 1),
|
||||||
|
ST_BUTTON_THREE = (1 << 2),
|
||||||
|
} StButtonMask;
|
||||||
|
|
||||||
|
#define ST_BUTTON_MASK_FROM_BUTTON(button) (1 << ((button) - 1))
|
||||||
|
|
||||||
|
void st_button_set_button_mask (StButton *button,
|
||||||
|
StButtonMask mask);
|
||||||
|
StButtonMask st_button_get_button_mask (StButton *button);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __ST_BUTTON_H__ */
|
#endif /* __ST_BUTTON_H__ */
|
||||||
|
@ -1,363 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
/*
|
|
||||||
* st-clickable.h: A bin with methods and properties useful for implementing buttons
|
|
||||||
*
|
|
||||||
* Copyright 2009, 2010 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope 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 for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:st-clickable
|
|
||||||
* @short_description: A bin with methods and properties useful for implementing buttons
|
|
||||||
*
|
|
||||||
* A #StBin subclass which translates lower-level Clutter button events
|
|
||||||
* into higher level properties which are useful for implementing "button-like"
|
|
||||||
* actors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "st-clickable.h"
|
|
||||||
|
|
||||||
#include "st-private.h"
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (StClickable, st_clickable, ST_TYPE_BIN);
|
|
||||||
|
|
||||||
struct _StClickablePrivate {
|
|
||||||
gboolean active;
|
|
||||||
gboolean held;
|
|
||||||
gboolean pressed;
|
|
||||||
|
|
||||||
guint initiating_button;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Signals */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
CLICKED,
|
|
||||||
LAST_SIGNAL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_0,
|
|
||||||
|
|
||||||
PROP_ACTIVE,
|
|
||||||
PROP_HELD,
|
|
||||||
PROP_PRESSED
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint st_clickable_signals [LAST_SIGNAL] = { 0 };
|
|
||||||
|
|
||||||
static void
|
|
||||||
sync_pseudo_class (StClickable *self)
|
|
||||||
{
|
|
||||||
if (self->priv->pressed || self->priv->active)
|
|
||||||
st_widget_add_style_pseudo_class (ST_WIDGET (self), "pressed");
|
|
||||||
else
|
|
||||||
st_widget_remove_style_pseudo_class (ST_WIDGET (self), "pressed");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_active (StClickable *self,
|
|
||||||
gboolean active)
|
|
||||||
{
|
|
||||||
if (self->priv->active == active)
|
|
||||||
return;
|
|
||||||
self->priv->active = active;
|
|
||||||
sync_pseudo_class (self);
|
|
||||||
g_object_notify (G_OBJECT (self), "active");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_pressed (StClickable *self,
|
|
||||||
gboolean pressed)
|
|
||||||
{
|
|
||||||
if (self->priv->pressed == pressed)
|
|
||||||
return;
|
|
||||||
self->priv->pressed = pressed;
|
|
||||||
sync_pseudo_class (self);
|
|
||||||
g_object_notify (G_OBJECT (self), "pressed");
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
st_clickable_enter_event (ClutterActor *actor,
|
|
||||||
ClutterCrossingEvent *event)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (actor);
|
|
||||||
gboolean result;
|
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (actor));
|
|
||||||
|
|
||||||
result = CLUTTER_ACTOR_CLASS (st_clickable_parent_class)->enter_event (actor, event);
|
|
||||||
|
|
||||||
/* We can't just assume get_hover() is TRUE; see st_widget_enter(). */
|
|
||||||
set_pressed (self, self->priv->held && st_widget_get_hover (ST_WIDGET (actor)));
|
|
||||||
|
|
||||||
g_object_thaw_notify (G_OBJECT (actor));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
st_clickable_leave_event (ClutterActor *actor,
|
|
||||||
ClutterCrossingEvent *event)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (actor);
|
|
||||||
gboolean result;
|
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (actor));
|
|
||||||
|
|
||||||
result = CLUTTER_ACTOR_CLASS (st_clickable_parent_class)->leave_event (actor, event);
|
|
||||||
|
|
||||||
/* As above, we can't just assume get_hover() is FALSE. */
|
|
||||||
set_pressed (self, self->priv->held && st_widget_get_hover (ST_WIDGET (actor)));
|
|
||||||
|
|
||||||
g_object_thaw_notify (G_OBJECT (actor));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
st_clickable_button_press_event (ClutterActor *actor,
|
|
||||||
ClutterButtonEvent *event)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (actor);
|
|
||||||
|
|
||||||
if (event->click_count != 1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (self->priv->held)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (!clutter_actor_contains (actor, event->source))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
self->priv->held = TRUE;
|
|
||||||
self->priv->initiating_button = event->button;
|
|
||||||
clutter_grab_pointer (CLUTTER_ACTOR (self));
|
|
||||||
|
|
||||||
set_pressed (self, TRUE);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
st_clickable_button_release_event (ClutterActor *actor,
|
|
||||||
ClutterButtonEvent *event)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (actor);
|
|
||||||
|
|
||||||
if (event->button != self->priv->initiating_button || event->click_count != 1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!self->priv->held)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
self->priv->held = FALSE;
|
|
||||||
clutter_ungrab_pointer ();
|
|
||||||
|
|
||||||
if (!clutter_actor_contains (actor, event->source))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
set_pressed (self, FALSE);
|
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (self), st_clickable_signals[CLICKED], 0, event);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
st_clickable_key_press_event (ClutterActor *actor,
|
|
||||||
ClutterKeyEvent *event)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (actor);
|
|
||||||
|
|
||||||
if (event->keyval == CLUTTER_KEY_space ||
|
|
||||||
event->keyval == CLUTTER_KEY_Return)
|
|
||||||
{
|
|
||||||
set_pressed (self, TRUE);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
st_clickable_key_release_event (ClutterActor *actor,
|
|
||||||
ClutterKeyEvent *event)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (actor);
|
|
||||||
|
|
||||||
if (event->keyval != CLUTTER_KEY_space &&
|
|
||||||
event->keyval != CLUTTER_KEY_Return)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
set_pressed (self, FALSE);
|
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (self), st_clickable_signals[CLICKED], 0, event);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* st_clickable_fake_release:
|
|
||||||
* @box:
|
|
||||||
*
|
|
||||||
* If this widget 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 clicked 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
|
|
||||||
st_clickable_fake_release (StClickable *self)
|
|
||||||
{
|
|
||||||
if (!self->priv->held)
|
|
||||||
return;
|
|
||||||
|
|
||||||
self->priv->held = FALSE;
|
|
||||||
clutter_ungrab_pointer ();
|
|
||||||
|
|
||||||
set_pressed (self, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
st_clickable_set_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_ACTIVE:
|
|
||||||
set_active (self, g_value_get_boolean (value));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
st_clickable_get_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
StClickable *self = ST_CLICKABLE (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_ACTIVE:
|
|
||||||
g_value_set_boolean (value, self->priv->active);
|
|
||||||
break;
|
|
||||||
case PROP_HELD:
|
|
||||||
g_value_set_boolean (value, self->priv->held);
|
|
||||||
break;
|
|
||||||
case PROP_PRESSED:
|
|
||||||
g_value_set_boolean (value, self->priv->pressed);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
st_clickable_class_init (StClickableClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
|
||||||
|
|
||||||
gobject_class->get_property = st_clickable_get_property;
|
|
||||||
gobject_class->set_property = st_clickable_set_property;
|
|
||||||
|
|
||||||
actor_class->enter_event = st_clickable_enter_event;
|
|
||||||
actor_class->leave_event = st_clickable_leave_event;
|
|
||||||
actor_class->button_press_event = st_clickable_button_press_event;
|
|
||||||
actor_class->button_release_event = st_clickable_button_release_event;
|
|
||||||
actor_class->key_press_event = st_clickable_key_press_event;
|
|
||||||
actor_class->key_release_event = st_clickable_key_release_event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StClickable::clicked
|
|
||||||
* @box: The #StClickable
|
|
||||||
*
|
|
||||||
* This signal is emitted when the button should take the action
|
|
||||||
* associated with button click+release.
|
|
||||||
*/
|
|
||||||
st_clickable_signals[CLICKED] =
|
|
||||||
g_signal_new ("clicked",
|
|
||||||
G_TYPE_FROM_CLASS (klass),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
0,
|
|
||||||
NULL, NULL,
|
|
||||||
g_cclosure_marshal_VOID__BOXED,
|
|
||||||
G_TYPE_NONE, 1, CLUTTER_TYPE_EVENT);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StClickable: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));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StClickable:held
|
|
||||||
*
|
|
||||||
* This property tracks whether the button has the pointer grabbed,
|
|
||||||
* whether or not the pointer is currently hovering over the button.
|
|
||||||
*/
|
|
||||||
g_object_class_install_property (gobject_class,
|
|
||||||
PROP_HELD,
|
|
||||||
g_param_spec_boolean ("held",
|
|
||||||
"Held state",
|
|
||||||
"Whether the mouse button is currently pressed",
|
|
||||||
FALSE,
|
|
||||||
G_PARAM_READABLE));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StClickable: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 (StClickablePrivate));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
st_clickable_init (StClickable *self)
|
|
||||||
{
|
|
||||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ST_TYPE_CLICKABLE,
|
|
||||||
StClickablePrivate);
|
|
||||||
st_widget_set_track_hover (ST_WIDGET (self), TRUE);
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
/*
|
|
||||||
* st-clickable.h: A bin with methods and properties useful for implementing buttons
|
|
||||||
*
|
|
||||||
* Copyright 2009, 2010 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope 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 for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __ST_CLICKABLE_H__
|
|
||||||
#define __ST_CLICKABLE_H__
|
|
||||||
|
|
||||||
#include "st-bin.h"
|
|
||||||
|
|
||||||
#define ST_TYPE_CLICKABLE (st_clickable_get_type ())
|
|
||||||
#define ST_CLICKABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ST_TYPE_CLICKABLE, StClickable))
|
|
||||||
#define ST_CLICKABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ST_TYPE_CLICKABLE, StClickableClass))
|
|
||||||
#define ST_IS_CLICKABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ST_TYPE_CLICKABLE))
|
|
||||||
#define ST_IS_CLICKABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ST_TYPE_CLICKABLE))
|
|
||||||
#define ST_CLICKABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ST_TYPE_CLICKABLE, StClickableClass))
|
|
||||||
|
|
||||||
typedef struct _StClickable StClickable;
|
|
||||||
typedef struct _StClickableClass StClickableClass;
|
|
||||||
|
|
||||||
typedef struct _StClickablePrivate StClickablePrivate;
|
|
||||||
|
|
||||||
struct _StClickable
|
|
||||||
{
|
|
||||||
StBin parent;
|
|
||||||
|
|
||||||
StClickablePrivate *priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _StClickableClass
|
|
||||||
{
|
|
||||||
StBinClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType st_clickable_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
void st_clickable_fake_release (StClickable *box);
|
|
||||||
|
|
||||||
#endif /* __ST_CLICKABLE_H__ */
|
|
@ -2,6 +2,7 @@ VOID:OBJECT
|
|||||||
VOID:VOID
|
VOID:VOID
|
||||||
VOID:PARAM
|
VOID:PARAM
|
||||||
VOID:POINTER
|
VOID:POINTER
|
||||||
|
VOID:INT
|
||||||
VOID:UINT
|
VOID:UINT
|
||||||
VOID:UINT,UINT
|
VOID:UINT,UINT
|
||||||
VOID:OBJECT,OBJECT
|
VOID:OBJECT,OBJECT
|
||||||
|
Loading…
Reference in New Issue
Block a user