static void st_button_set_property (GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec) { StButton *button = ST_BUTTON (gobject); switch (prop_id) { case PROP_LABEL: st_button_set_label (button, g_value_get_string (value)); break; case PROP_BUTTON_MASK: st_button_set_button_mask (button, g_value_get_flags (value)); break; case PROP_TOGGLE_MODE: st_button_set_toggle_mode (button, g_value_get_boolean (value)); break; case PROP_CHECKED: st_button_set_checked (button, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; } }
static void st_button_get_property (GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec) { StButtonPrivate *priv = ST_BUTTON (gobject)->priv; switch (prop_id) { case PROP_LABEL: g_value_set_string (value, priv->text); break; case PROP_BUTTON_MASK: g_value_set_flags (value, priv->button_mask); break; case PROP_TOGGLE_MODE: g_value_set_boolean (value, priv->is_toggle); break; case PROP_CHECKED: g_value_set_boolean (value, priv->is_checked); break; case PROP_PRESSED: g_value_set_boolean (value, priv->pressed != 0); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; } }
static gboolean st_button_button_press (ClutterActor *actor, ClutterButtonEvent *event) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button); ClutterInputDevice *device = clutter_event_get_device ((ClutterEvent*) event); if (priv->press_sequence) return CLUTTER_EVENT_PROPAGATE; if (priv->button_mask & mask) { if (priv->grabbed == 0) clutter_grab_pointer (actor); priv->grabbed |= mask; st_button_press (button, device, mask, NULL); return TRUE; } return FALSE; }
static gboolean st_button_button_release (ClutterActor *actor, ClutterButtonEvent *event) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button); ClutterInputDevice *device = clutter_event_get_device ((ClutterEvent*) event); if (priv->button_mask & mask) { gboolean is_click; is_click = priv->grabbed && clutter_actor_contains (actor, event->source); st_button_release (button, device, mask, is_click ? event->button : 0, NULL); priv->grabbed &= ~mask; if (priv->grabbed == 0) clutter_ungrab_pointer (); return TRUE; } return FALSE; }
static gboolean st_button_touch_event (ClutterActor *actor, ClutterTouchEvent *event) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (1); ClutterEventSequence *sequence; ClutterInputDevice *device; if (priv->pressed != 0) return CLUTTER_EVENT_PROPAGATE; device = clutter_event_get_device ((ClutterEvent*) event); sequence = clutter_event_get_event_sequence ((ClutterEvent*) event); if (event->type == CLUTTER_TOUCH_BEGIN && !priv->press_sequence) { clutter_input_device_sequence_grab (device, sequence, actor); st_button_press (button, device, 0, sequence); return CLUTTER_EVENT_STOP; } else if (event->type == CLUTTER_TOUCH_END && priv->device == device && priv->press_sequence == sequence) { st_button_release (button, device, mask, 0, sequence); clutter_input_device_sequence_ungrab (device, sequence); return CLUTTER_EVENT_STOP; } return CLUTTER_EVENT_PROPAGATE; }
static void st_button_finalize (GObject *gobject) { StButtonPrivate *priv = ST_BUTTON (gobject)->priv; g_free (priv->text); G_OBJECT_CLASS (st_button_parent_class)->finalize (gobject); }
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 void st_button_key_focus_out (ClutterActor *actor) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); /* If we lose focus between a key press and release, undo the press */ if ((priv->pressed & ST_BUTTON_ONE) && !(priv->grabbed & ST_BUTTON_ONE)) st_button_release (button, NULL, ST_BUTTON_ONE, 0, NULL); CLUTTER_ACTOR_CLASS (st_button_parent_class)->key_focus_out (actor); }
static gboolean st_button_key_press (ClutterActor *actor, ClutterKeyEvent *event) { StButton *button = ST_BUTTON (actor); if (button->priv->button_mask & ST_BUTTON_ONE) { if (event->keyval == CLUTTER_KEY_space || event->keyval == CLUTTER_KEY_Return) { st_button_press (button, ST_BUTTON_ONE); return TRUE; } } return CLUTTER_ACTOR_CLASS (st_button_parent_class)->key_press_event (actor, event); }
static gboolean st_button_leave (ClutterActor *actor, ClutterCrossingEvent *event) { StButton *button = ST_BUTTON (actor); gboolean ret; ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event); if (button->priv->grabbed) { if (st_widget_get_hover (ST_WIDGET (button))) st_button_press (button, button->priv->grabbed); else st_button_release (button, button->priv->grabbed, 0); } return ret; }
static gboolean st_button_button_press (ClutterActor *actor, ClutterButtonEvent *event) { StButton *button = ST_BUTTON (actor); StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button); if (button->priv->button_mask & mask) { if (button->priv->grabbed == 0) clutter_grab_pointer (actor); button->priv->grabbed |= mask; st_button_press (button, mask); return TRUE; } return FALSE; }
static gboolean st_button_key_press (ClutterActor *actor, ClutterKeyEvent *event) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); if (priv->button_mask & ST_BUTTON_ONE) { if (event->keyval == CLUTTER_KEY_space || event->keyval == CLUTTER_KEY_Return || event->keyval == CLUTTER_KEY_KP_Enter || event->keyval == CLUTTER_KEY_ISO_Enter) { st_button_press (button, NULL, ST_BUTTON_ONE, NULL); return TRUE; } } return CLUTTER_ACTOR_CLASS (st_button_parent_class)->key_press_event (actor, event); }
static gboolean st_button_key_release (ClutterActor *actor, ClutterKeyEvent *event) { StButton *button = ST_BUTTON (actor); if (button->priv->button_mask & ST_BUTTON_ONE) { if (event->keyval == CLUTTER_KEY_space || event->keyval == CLUTTER_KEY_Return) { gboolean is_click; is_click = (button->priv->pressed & ST_BUTTON_ONE); st_button_release (button, ST_BUTTON_ONE, is_click ? 1 : 0); return TRUE; } } return FALSE; }
static gboolean st_button_enter (ClutterActor *actor, ClutterCrossingEvent *event) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); gboolean ret; ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->enter_event (actor, event); if (priv->grabbed) { if (st_widget_get_hover (ST_WIDGET (button))) st_button_press (button, priv->device, priv->grabbed, NULL); else st_button_release (button, priv->device, priv->grabbed, 0, NULL); } return ret; }
static gboolean st_button_button_release (ClutterActor *actor, ClutterButtonEvent *event) { StButton *button = ST_BUTTON (actor); StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button); if (button->priv->button_mask & mask) { gboolean is_click; is_click = button->priv->grabbed && st_widget_get_hover (ST_WIDGET (button)); st_button_release (button, mask, is_click ? event->button : 0); button->priv->grabbed &= ~mask; if (button->priv->grabbed == 0) clutter_ungrab_pointer (); return TRUE; } return FALSE; }
static gboolean st_button_key_release (ClutterActor *actor, ClutterKeyEvent *event) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); if (priv->button_mask & ST_BUTTON_ONE) { if (event->keyval == CLUTTER_KEY_space || event->keyval == CLUTTER_KEY_Return || event->keyval == CLUTTER_KEY_KP_Enter || event->keyval == CLUTTER_KEY_ISO_Enter) { gboolean is_click; is_click = (priv->pressed & ST_BUTTON_ONE); st_button_release (button, NULL, ST_BUTTON_ONE, is_click ? 1 : 0, NULL); return TRUE; } } return FALSE; }
static void st_button_style_changed (StWidget *widget) { StButton *button = ST_BUTTON (widget); StButtonPrivate *priv = button->priv; StButtonClass *button_class = ST_BUTTON_GET_CLASS (button); StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (button)); double spacing; ST_WIDGET_CLASS (st_button_parent_class)->style_changed (widget); spacing = 6; st_theme_node_lookup_length (theme_node, "border-spacing", FALSE, &spacing); priv->spacing = (int)(0.5 + spacing); /* update the label styling */ st_button_update_label_style (button); /* run a transition if applicable */ if (button_class->transition) { button_class->transition (button); } }