event-editor/multi-choice: Replace GtkToggleButton with AdwBin
Using GtkToggleButton in this case is not only overkill for our intended use case, it is also a hinderance, as the states and focus of the widget are handled by the widget itself, which can lead to unpredictable and undesired behavior. Using AdwBin solves this problem by allowing us to set the styles and states from the parent, provided that the CSS name is changed to "button". Switching to AdwBin also allows us to not override the `focus()`, `grab_focus()`, and `get_platform_state()` virtual methods. Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/841>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $GcalMultiChoice: Widget {
|
||||
accessible-role: spin_button;
|
||||
@@ -6,6 +7,10 @@ template $GcalMultiChoice: Widget {
|
||||
focusable: true;
|
||||
hexpand: true;
|
||||
|
||||
GestureClick {
|
||||
released => $on_gesture_click_released(template);
|
||||
}
|
||||
|
||||
PopoverBin popover_bin {
|
||||
child: Box {
|
||||
spacing: 6;
|
||||
@@ -23,9 +28,8 @@ template $GcalMultiChoice: Widget {
|
||||
]
|
||||
}
|
||||
|
||||
ToggleButton button {
|
||||
accessible-role: none;
|
||||
toggled => $button_toggled_cb() swapped;
|
||||
Adw.Bin button {
|
||||
css-name: "button";
|
||||
state-flags-changed => $gcal_multi_choice_state_flags_changed(template);
|
||||
|
||||
styles [
|
||||
@@ -34,7 +38,7 @@ template $GcalMultiChoice: Widget {
|
||||
"popup",
|
||||
]
|
||||
|
||||
Stack stack {
|
||||
child: Stack stack {
|
||||
hexpand: true;
|
||||
vexpand: true;
|
||||
|
||||
@@ -49,7 +53,7 @@ template $GcalMultiChoice: Widget {
|
||||
|
||||
child: Label label2 {};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Button up_button {
|
||||
|
||||
@@ -79,12 +79,9 @@ enum
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
static void gcal_multi_choice_accessible_init (GtkAccessibleInterface *iface);
|
||||
|
||||
static void gcal_multi_choice_accessible_range_init (GtkAccessibleRangeInterface *iface);
|
||||
|
||||
G_DEFINE_FINAL_TYPE_WITH_CODE (GcalMultiChoice, gcal_multi_choice, GTK_TYPE_WIDGET,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACCESSIBLE, gcal_multi_choice_accessible_init)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACCESSIBLE_RANGE, gcal_multi_choice_accessible_range_init))
|
||||
|
||||
/*
|
||||
@@ -223,33 +220,38 @@ update_sensitivity (GcalMultiChoice *self)
|
||||
}
|
||||
|
||||
static void
|
||||
button_toggled_cb (GcalMultiChoice *self)
|
||||
on_widget_activated (GcalMultiChoice *self)
|
||||
{
|
||||
const gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->button));
|
||||
|
||||
if (gtk_popover_bin_get_popover (self->popover_bin))
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
gtk_popover_bin_popup (self->popover_bin);
|
||||
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_EXPANDED, TRUE,
|
||||
-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_accessible_reset_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_EXPANDED);
|
||||
}
|
||||
gtk_popover_bin_popup (self->popover_bin);
|
||||
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_EXPANDED, TRUE,
|
||||
-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_accessible_reset_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_EXPANDED);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
menu_deactivate_cb (GcalMultiChoice *self)
|
||||
static void
|
||||
on_gesture_click_released (GcalMultiChoice *self,
|
||||
gint n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkGestureClick *gesture)
|
||||
{
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->button), FALSE);
|
||||
if (gtk_widget_contains (GTK_WIDGET (self), x, y))
|
||||
{
|
||||
if (!gtk_widget_grab_focus (GTK_WIDGET (self)))
|
||||
g_assert_not_reached ();
|
||||
|
||||
return TRUE;
|
||||
gtk_widget_activate (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -381,57 +383,28 @@ gcal_multi_choice_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state_flags)
|
||||
{
|
||||
GcalMultiChoice *self;
|
||||
GtkStateFlags button_state_flags;
|
||||
GtkStateFlags state_flags;
|
||||
GtkWidget *popover;
|
||||
|
||||
g_assert (GCAL_IS_MULTI_CHOICE (widget));
|
||||
|
||||
self = GCAL_MULTI_CHOICE (widget);
|
||||
|
||||
button_state_flags = gtk_widget_get_state_flags (self->button);
|
||||
if (button_state_flags & GTK_STATE_FLAG_FOCUSED)
|
||||
button_state_flags |= GTK_STATE_FLAG_FOCUS_VISIBLE;
|
||||
gtk_widget_set_state_flags (GTK_WIDGET (self), button_state_flags, TRUE);
|
||||
|
||||
if (!gtk_widget_is_sensitive (widget))
|
||||
if ((popover = gtk_popover_bin_get_popover (self->popover_bin)))
|
||||
{
|
||||
if ((popover = gtk_popover_bin_get_popover (self->popover_bin)))
|
||||
gtk_widget_set_visible (popover, FALSE);
|
||||
if (gtk_widget_get_mapped (popover))
|
||||
gtk_widget_set_state_flags (self->button, GTK_STATE_FLAG_CHECKED, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (self->button, GTK_STATE_FLAG_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcal_multi_choice_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction)
|
||||
{
|
||||
GcalMultiChoice *self = GCAL_MULTI_CHOICE (widget);
|
||||
GtkWidget *popover = gtk_popover_bin_get_popover (self->popover_bin);
|
||||
|
||||
if (popover && gtk_widget_get_visible (popover))
|
||||
return gtk_widget_child_focus (popover, direction);
|
||||
else
|
||||
return gtk_widget_child_focus (self->button, direction);
|
||||
}
|
||||
{
|
||||
gtk_widget_set_state_flags (self->button, GTK_STATE_FLAG_NORMAL, TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcal_multi_choice_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
GcalMultiChoice *self = GCAL_MULTI_CHOICE (widget);
|
||||
|
||||
return gtk_widget_grab_focus (self->button);
|
||||
}
|
||||
|
||||
/*
|
||||
* GtkAccessible overrides
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
gcal_multi_choice_accessible_get_platform_state (GtkAccessible *accessible,
|
||||
GtkAccessiblePlatformState state)
|
||||
{
|
||||
GcalMultiChoice *self = GCAL_MULTI_CHOICE (accessible);
|
||||
|
||||
return gtk_accessible_get_platform_state (GTK_ACCESSIBLE (self->button), state);
|
||||
state_flags = gtk_widget_get_state_flags (widget);
|
||||
if (state_flags & GTK_STATE_FLAG_FOCUSED)
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_FOCUS_VISIBLE, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -461,8 +434,6 @@ gcal_multi_choice_class_init (GcalMultiChoiceClass *class)
|
||||
object_class->get_property = gcal_multi_choice_get_property;
|
||||
|
||||
widget_class->state_flags_changed = gcal_multi_choice_state_flags_changed;
|
||||
widget_class->focus = gcal_multi_choice_focus;
|
||||
widget_class->grab_focus = gcal_multi_choice_grab_focus;
|
||||
|
||||
properties[PROP_VALUE] =
|
||||
g_param_spec_int ("value", "Value", "Value",
|
||||
@@ -533,20 +504,14 @@ gcal_multi_choice_class_init (GcalMultiChoiceClass *class)
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalMultiChoice, label2);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalMultiChoice, popover_bin);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_gesture_click_released);
|
||||
gtk_widget_class_bind_template_callback (widget_class, gcal_multi_choice_state_flags_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, button_toggled_cb);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "navigator");
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_multi_choice_accessible_init (GtkAccessibleInterface *iface)
|
||||
{
|
||||
iface->get_platform_state = gcal_multi_choice_accessible_get_platform_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_multi_choice_accessible_range_init (GtkAccessibleRangeInterface *iface)
|
||||
{
|
||||
@@ -560,7 +525,7 @@ gcal_multi_choice_init (GcalMultiChoice *self)
|
||||
|
||||
update_sensitivity (self);
|
||||
|
||||
g_signal_connect_swapped (self, "activate", (GCallback) button_toggled_cb, self);
|
||||
g_signal_connect_swapped (self, "activate", (GCallback) on_widget_activated, self);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -700,9 +665,6 @@ gcal_multi_choice_set_popover (GcalMultiChoice *self,
|
||||
|
||||
gtk_popover_bin_set_popover (self->popover_bin, popover);
|
||||
|
||||
if (popover)
|
||||
g_signal_connect_swapped (popover, "closed", G_CALLBACK (menu_deactivate_cb), self);
|
||||
|
||||
update_sensitivity (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_POPOVER]);
|
||||
|
||||
Reference in New Issue
Block a user