Compare commits

...

3 Commits

Author SHA1 Message Date
Matthias Clasen d8c5e86b30 gtk-demo: Use a default action in the infobars demo
This makes the question infobar activatable by clicking
anywhere in it.
2020-01-09 19:04:15 -05:00
Matthias Clasen 035f874ca4 Adwaita: Add hover for clickable infobars 2020-01-09 19:03:56 -05:00
Matthias Clasen 155fe56bf2 infobar: Activate default action on clicks
When we have a default action set on the infobar, activate it
for clicks anywhere in the infobar.  Also add an .action style
class in this case, so we can add a hover highlight to the infobar
just for this case.
2020-01-09 19:03:38 -05:00
5 changed files with 166 additions and 1 deletions
+1
View File
@@ -97,6 +97,7 @@ do_infobar (GtkWidget *do_widget)
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label, FALSE, FALSE, 0);
gtk_info_bar_set_default_response (GTK_INFO_BAR (bar), GTK_RESPONSE_OK);
button = gtk_toggle_button_new_with_label ("Question");
g_object_bind_property (button, "active", bar, "visible", G_BINDING_BIDIRECTIONAL);
+155 -1
View File
@@ -50,6 +50,7 @@
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#include "deprecated/gtkstock.h"
#include "gtkgesturemultipress.h"
/**
* SECTION:gtkinfobar
@@ -147,6 +148,10 @@ struct _GtkInfoBarPrivate
gboolean show_close_button;
GtkMessageType message_type;
int default_response;
gboolean default_response_sensitive;
GtkGesture *gesture;
};
typedef struct _ResponseData ResponseData;
@@ -299,6 +304,93 @@ find_button (GtkInfoBar *info_bar,
return child;
}
static void
update_state (GtkWidget *widget,
gboolean in)
{
GtkStateFlags state;
state = gtk_widget_get_state_flags (widget);
if (in)
state |= GTK_STATE_FLAG_PRELIGHT;
else
state &= ~GTK_STATE_FLAG_PRELIGHT;
gtk_widget_set_state_flags (widget, state, TRUE);
}
static gboolean
gtk_info_bar_enter_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
if (event->detail != GDK_NOTIFY_INFERIOR)
update_state (widget, TRUE);
return FALSE;
}
static gboolean
gtk_info_bar_leave_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
if (event->detail != GDK_NOTIFY_INFERIOR)
update_state (widget, FALSE);
return FALSE;
}
static void
gtk_info_bar_realize (GtkWidget *widget)
{
GtkAllocation allocation;
GdkWindow *window;
GdkWindowAttr attributes;
gint attributes_mask;
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_set_realized (widget, TRUE);
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = allocation.x;
attributes.y = allocation.y;
attributes.width = allocation.width;
attributes.height = allocation.height;
attributes.wclass = GDK_INPUT_ONLY;
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_TOUCH_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y;
window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
gtk_widget_register_window (widget, window);
gtk_widget_set_window (widget, window);
}
static void
gtk_info_bar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GdkWindow *window;
gtk_widget_set_allocation (widget, allocation);
window = gtk_widget_get_window (widget);
if (window != NULL)
gdk_window_move_resize (window,
allocation->x, allocation->y,
allocation->width, allocation->height);
allocation->x = 0;
allocation->y = 0;
GTK_WIDGET_CLASS (gtk_info_bar_parent_class)->size_allocate (widget, allocation);
}
static void
gtk_info_bar_close (GtkInfoBar *info_bar)
{
@@ -310,6 +402,16 @@ gtk_info_bar_close (GtkInfoBar *info_bar)
GTK_RESPONSE_CANCEL);
}
static void
gtk_info_bar_finalize (GObject *object)
{
GtkInfoBar *info_bar = GTK_INFO_BAR (object);
g_object_unref (info_bar->priv->gesture);
G_OBJECT_CLASS (gtk_info_bar_parent_class)->finalize (object);
}
static void
gtk_info_bar_class_init (GtkInfoBarClass *klass)
{
@@ -320,9 +422,15 @@ gtk_info_bar_class_init (GtkInfoBarClass *klass)
widget_class = GTK_WIDGET_CLASS (klass);
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gtk_info_bar_finalize;
object_class->get_property = gtk_info_bar_get_property;
object_class->set_property = gtk_info_bar_set_property;
widget_class->realize = gtk_info_bar_realize;
widget_class->enter_notify_event = gtk_info_bar_enter_notify;
widget_class->leave_notify_event = gtk_info_bar_leave_notify;
widget_class->size_allocate = gtk_info_bar_size_allocate;
klass->close = gtk_info_bar_close;
/**
@@ -498,6 +606,19 @@ close_button_clicked_cb (GtkWidget *button,
GTK_RESPONSE_CLOSE);
}
static void
click_pressed_cb (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkInfoBar *info_bar)
{
GtkInfoBarPrivate *priv = gtk_info_bar_get_instance_private (info_bar);
if (priv->default_response && priv->default_response_sensitive)
gtk_info_bar_response (info_bar, priv->default_response);
}
static void
gtk_info_bar_init (GtkInfoBar *info_bar)
{
@@ -511,11 +632,16 @@ gtk_info_bar_init (GtkInfoBar *info_bar)
* during construction */
priv->message_type = GTK_MESSAGE_OTHER;
gtk_widget_set_has_window (widget, TRUE);
gtk_widget_init_template (widget);
gtk_widget_set_no_show_all (priv->close_button, TRUE);
g_signal_connect (priv->close_button, "clicked",
G_CALLBACK (close_button_clicked_cb), info_bar);
priv->gesture = gtk_gesture_multi_press_new (widget);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->gesture), GDK_BUTTON_PRIMARY);
g_signal_connect (priv->gesture, "pressed", G_CALLBACK (click_pressed_cb), widget);
}
static GtkBuildableIface *parent_buildable_iface;
@@ -789,6 +915,22 @@ gtk_info_bar_new_with_buttons (const gchar *first_button_text,
return GTK_WIDGET (info_bar);
}
static void
update_default_response (GtkInfoBar *info_bar,
int response_id,
gboolean sensitive)
{
GtkInfoBarPrivate *priv = gtk_info_bar_get_instance_private (info_bar);
priv->default_response = response_id;
priv->default_response_sensitive = sensitive;
if (response_id && sensitive)
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (info_bar)), "action");
else
gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (info_bar)), "action");
}
/**
* gtk_info_bar_set_response_sensitive:
* @info_bar: a #GtkInfoBar
@@ -810,6 +952,9 @@ gtk_info_bar_set_response_sensitive (GtkInfoBar *info_bar,
g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
if (info_bar->priv->default_response == response_id)
info_bar->priv->default_response_sensitive = setting;
children = gtk_container_get_children (GTK_CONTAINER (info_bar->priv->action_area));
for (list = children; list; list = list->next)
@@ -822,6 +967,9 @@ gtk_info_bar_set_response_sensitive (GtkInfoBar *info_bar,
}
g_list_free (children);
if (response_id == info_bar->priv->default_response)
update_default_response (info_bar, response_id, setting);
}
/**
@@ -843,6 +991,7 @@ gtk_info_bar_set_default_response (GtkInfoBar *info_bar,
gint response_id)
{
GList *children, *list;
gboolean sensitive = TRUE;
g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
@@ -854,10 +1003,15 @@ gtk_info_bar_set_default_response (GtkInfoBar *info_bar,
ResponseData *rd = get_response_data (widget, FALSE);
if (rd && rd->response_id == response_id)
gtk_widget_grab_default (widget);
{
gtk_widget_grab_default (widget);
sensitive = gtk_widget_get_sensitive (widget);
}
}
g_list_free (children);
update_default_response (info_bar, response_id, sensitive);
}
/**
+6
View File
@@ -4228,6 +4228,12 @@ paned {
infobar {
border-style: none;
&.action:hover > revealer > box {
background-color: if($variant == 'light', desaturate(lighten(invert($selected_bg_color), 47%), 30%),
desaturate(darken(invert($selected_bg_color),42%), 70%));
border-bottom: 1px solid lighten($borders_color, 5%);
}
&.info,
&.question,
&.warning,
+2
View File
@@ -1689,6 +1689,8 @@ paned.vertical > separator.wide { margin: 0; padding: 0; background-repeat: repe
/************** GtkInfoBar * */
infobar { border-style: none; }
infobar.action:hover > revealer > box { background-color: #3e3b37; border-bottom: 1px solid #282828; }
infobar.info, infobar.question, infobar.warning, infobar.error { text-shadow: none; }
infobar.info:backdrop > revealer > box, infobar.info > revealer > box, infobar.question:backdrop > revealer > box, infobar.question > revealer > box, infobar.warning:backdrop > revealer > box, infobar.warning > revealer > box, infobar.error:backdrop > revealer > box, infobar.error > revealer > box { background-color: #44403b; border-bottom: 1px solid #282828; }
+2
View File
@@ -1705,6 +1705,8 @@ paned.vertical > separator.wide { margin: 0; padding: 0; background-repeat: repe
/************** GtkInfoBar * */
infobar { border-style: none; }
infobar.action:hover > revealer > box { background-color: #f4ebe1; border-bottom: 1px solid #d8d4d0; }
infobar.info, infobar.question, infobar.warning, infobar.error { text-shadow: none; }
infobar.info:backdrop > revealer > box, infobar.info > revealer > box, infobar.question:backdrop > revealer > box, infobar.question > revealer > box, infobar.warning:backdrop > revealer > box, infobar.warning > revealer > box, infobar.error:backdrop > revealer > box, infobar.error > revealer > box { background-color: #f1e6d9; border-bottom: 1px solid #d8d4d0; }