From ca718b34aaec785ea6d550679a8cb6624f7048f6 Mon Sep 17 00:00:00 2001 From: Viktor Odintsev Date: Sat, 24 Jun 2017 12:08:42 +0300 Subject: [PATCH] Allow to display icons squared in systray --- plugins/systray/systray-box.c | 147 ++++++++++++++++++++++++++--------- plugins/systray/systray-box.h | 8 +- plugins/systray/systray-dialog.glade | 17 +++- plugins/systray/systray.c | 68 +++++++++++++--- 4 files changed, 189 insertions(+), 51 deletions(-) diff --git a/plugins/systray/systray-box.c b/plugins/systray/systray-box.c index 45d28241..6d4d7bfc 100644 --- a/plugins/systray/systray-box.c +++ b/plugins/systray/systray-box.c @@ -108,8 +108,12 @@ struct _SystrayBox /* maximum icon size */ gint size_max; + /* whether icons are squared */ + guint square_icons : 1; + /* allocated size by the plugin */ gint size_alloc; + gint nrows; }; @@ -163,6 +167,7 @@ systray_box_init (SystrayBox *box) box->n_visible_children = 0; box->horizontal = TRUE; box->show_hidden = FALSE; + box->square_icons = FALSE; } @@ -222,40 +227,55 @@ systray_box_size_get_max_child_size (SystrayBox *box, gint row_size; GtkStyleContext *ctx; GtkBorder padding; + gint spacing; ctx = gtk_widget_get_style_context (widget); gtk_style_context_get_padding (ctx, gtk_widget_get_state_flags (widget), &padding); alloc_size -= MAX (padding.left+padding.right, padding.top+padding.bottom); - /* count the number of rows that fit in the allocated space */ - for (rows = 1;; rows++) + if (box->square_icons) { - size = rows * box->size_max + (rows - 1) * SPACING; - if (size < alloc_size) - continue; + if (rows_ret != NULL) + *rows_ret = box->nrows; - /* decrease rows if the new size doesn't fit */ - if (rows > 1 && size > alloc_size) - rows--; + if (row_size_ret != NULL) + *row_size_ret = alloc_size / box->nrows; - break; + if (offset_ret != NULL) + *offset_ret = 0; } + else + { + /* count the number of rows that fit in the allocated space */ + for (rows = 1;; rows++) + { + size = rows * box->size_max + (rows - 1) * SPACING; + if (size < alloc_size) + continue; - row_size = (alloc_size - (rows - 1) * SPACING) / rows; - row_size = MIN (box->size_max, row_size); + /* decrease rows if the new size doesn't fit */ + if (rows > 1 && size > alloc_size) + rows--; - if (rows_ret != NULL) - *rows_ret = rows; + break; + } - if (row_size_ret != NULL) - *row_size_ret = row_size; + row_size = (alloc_size - (rows - 1) * SPACING) / rows; + row_size = MIN (box->size_max, row_size); - if (offset_ret != NULL) - { - rows = MIN (rows, box->n_visible_children); - *offset_ret = (alloc_size - (rows * row_size + (rows - 1) * SPACING)) / 2; - if (*offset_ret < 1) - *offset_ret = 0; + if (rows_ret != NULL) + *rows_ret = rows; + + if (row_size_ret != NULL) + *row_size_ret = row_size; + + if (offset_ret != NULL) + { + rows = MIN (rows, box->n_visible_children); + *offset_ret = (alloc_size - (rows * row_size + (rows - 1) * SPACING)) / 2; + if (*offset_ret < 1) + *offset_ret = 0; + } } } @@ -282,6 +302,7 @@ systray_box_get_preferred_width (GtkWidget *widget, } + static void systray_box_get_preferred_height (GtkWidget *widget, gint *minimum_height, @@ -303,6 +324,7 @@ systray_box_get_preferred_height (GtkWidget *widget, } + static void systray_box_get_preferred_length (GtkWidget *widget, gint *minimum_length, @@ -351,7 +373,7 @@ systray_box_get_preferred_length (GtkWidget *widget, /* special handling for non-squared icons. this only works if * the icon size ratio is > 1.00, if this is lower then 1.00 * the icon implementation should respect the tray orientation */ - if (G_UNLIKELY (child_req.width != child_req.height)) + if (!box->square_icons && G_UNLIKELY (child_req.width != child_req.height)) { ratio = (gdouble) child_req.width / (gdouble) child_req.height; if (!box->horizontal) @@ -398,7 +420,10 @@ systray_box_get_preferred_length (GtkWidget *widget, if (min_seq_cells != -1) cols = MAX (min_seq_cells, cols); - length = row_size * cols + (cols - 1) * SPACING; + if (box->square_icons) + length = row_size * cols; + else + length = row_size * cols + (cols - 1) * SPACING; } else { @@ -449,6 +474,7 @@ systray_box_size_allocate (GtkWidget *widget, gint idx; GtkStyleContext *ctx; GtkBorder padding; + gint spacing; gtk_widget_set_allocation (widget, allocation); @@ -456,6 +482,7 @@ systray_box_size_allocate (GtkWidget *widget, gtk_style_context_get_padding (ctx, gtk_widget_get_state_flags (widget), &padding); alloc_size = box->horizontal ? allocation->height : allocation->width; + spacing = box->square_icons ? 0 : SPACING; systray_box_size_get_max_child_size (box, alloc_size, &rows, &row_size, &offset); @@ -507,7 +534,7 @@ systray_box_size_allocate (GtkWidget *widget, else { /* special case handling for non-squared icons */ - if (G_UNLIKELY (child_req.width != child_req.height)) + if (!box->square_icons && G_UNLIKELY (child_req.width != child_req.height)) { ratio = (gdouble) child_req.width / (gdouble) child_req.height; @@ -541,10 +568,20 @@ systray_box_size_allocate (GtkWidget *widget, else { /* fix icon to row size */ - child_alloc.width = row_size; - child_alloc.height = row_size; - child_alloc.x = 0; - child_alloc.y = 0; + if (box->square_icons) + { + child_alloc.width = MIN (row_size, box->size_max); + child_alloc.height = MIN (row_size, box->size_max); + child_alloc.x = (row_size - child_alloc.width) / 2; + child_alloc.y = (row_size - child_alloc.height) / 2; + } + else + { + child_alloc.width = row_size; + child_alloc.height = row_size; + child_alloc.x = 0; + child_alloc.y = 0; + } ratio = 1.00; } @@ -568,9 +605,9 @@ systray_box_size_allocate (GtkWidget *widget, if (box->horizontal) { x = x_start; - y += row_size + SPACING; + y += row_size + spacing; - if (y > y_end) + if (!box->square_icons && y > y_end) { /* we overflow the number of rows, restart * allocation with 1px smaller icons */ @@ -586,9 +623,9 @@ systray_box_size_allocate (GtkWidget *widget, else { y = y_start; - x += row_size + SPACING; + x += row_size + spacing; - if (x > x_end) + if (!box->square_icons && x > x_end) { /* we overflow the number of rows, restart * allocation with 1px smaller icons */ @@ -607,9 +644,9 @@ systray_box_size_allocate (GtkWidget *widget, child_alloc.y += y; if (box->horizontal) - x += row_size * ratio + SPACING; + x += row_size * ratio + spacing; else - y += row_size * ratio + SPACING; + y += row_size * ratio + spacing; } panel_debug_filtered (PANEL_DEBUG_SYSTRAY, "allocated %s[%p] at (%d,%d;%d,%d)", @@ -618,6 +655,13 @@ systray_box_size_allocate (GtkWidget *widget, gtk_widget_size_allocate (child, &child_alloc); } + + /* recalculate size with higher precise */ + if (alloc_size != box->size_alloc) + { + box->size_alloc = alloc_size; + gtk_widget_queue_resize (GTK_WIDGET (box)); + } } @@ -802,13 +846,15 @@ systray_box_get_size_max (SystrayBox *box) void systray_box_set_size_alloc (SystrayBox *box, - gint size_alloc) + gint size_alloc, + gint nrows) { panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box)); - if (G_LIKELY (size_alloc != box->size_alloc)) + if (G_LIKELY (size_alloc != box->size_alloc || nrows != box->nrows)) { box->size_alloc = size_alloc; + box->nrows = nrows; if (box->childeren != NULL) gtk_widget_queue_resize (GTK_WIDGET (box)); @@ -819,7 +865,7 @@ systray_box_set_size_alloc (SystrayBox *box, void systray_box_set_show_hidden (SystrayBox *box, - gboolean show_hidden) + gboolean show_hidden) { panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box)); @@ -845,6 +891,33 @@ systray_box_get_show_hidden (SystrayBox *box) void +systray_box_set_squared (SystrayBox *box, + gboolean square_icons) +{ + panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box)); + + if (box->square_icons != square_icons) + { + box->square_icons = square_icons; + + if (box->childeren != NULL) + gtk_widget_queue_resize (GTK_WIDGET (box)); + } +} + + + +gboolean +systray_box_get_squared (SystrayBox *box) +{ + panel_return_val_if_fail (XFCE_IS_SYSTRAY_BOX (box), FALSE); + + return box->square_icons; +} + + + +void systray_box_update (SystrayBox *box, GSList *names_ordered) { diff --git a/plugins/systray/systray-box.h b/plugins/systray/systray-box.h index c640d768..cd804fa6 100644 --- a/plugins/systray/systray-box.h +++ b/plugins/systray/systray-box.h @@ -49,13 +49,19 @@ void systray_box_set_size_max (SystrayBox *box, gint systray_box_get_size_max (SystrayBox *box); void systray_box_set_size_alloc (SystrayBox *box, - gint size_alloc); + gint size_alloc, + gint nrows); void systray_box_set_show_hidden (SystrayBox *box, gboolean show_hidden); gboolean systray_box_get_show_hidden (SystrayBox *box); +void systray_box_set_squared (SystrayBox *box, + gboolean square_icons); + +gboolean systray_box_get_squared (SystrayBox *box); + void systray_box_update (SystrayBox *box, GSList *names_ordered); diff --git a/plugins/systray/systray-dialog.glade b/plugins/systray/systray-dialog.glade index 4a615b8d..e8028a36 100644 --- a/plugins/systray/systray-dialog.glade +++ b/plugins/systray/systray-dialog.glade @@ -148,6 +148,21 @@ + + Sq_uare icons + True + True + False + True + True + + + False + True + 1 + + + Show _frame True @@ -159,7 +174,7 @@ False True - 1 + 2 diff --git a/plugins/systray/systray.c b/plugins/systray/systray.c index 37cdcc39..5af44755 100644 --- a/plugins/systray/systray.c +++ b/plugins/systray/systray.c @@ -124,6 +124,7 @@ enum { PROP_0, PROP_SIZE_MAX, + PROP_SQUARE_ICONS, PROP_SHOW_FRAME, PROP_NAMES_ORDERED, PROP_NAMES_HIDDEN @@ -189,6 +190,13 @@ systray_plugin_class_init (SystrayPluginClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, + PROP_SQUARE_ICONS, + g_param_spec_boolean ("square-icons", + NULL, NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SHOW_FRAME, g_param_spec_boolean ("show-frame", NULL, NULL, @@ -271,7 +279,12 @@ systray_plugin_get_property (GObject *object, { case PROP_SIZE_MAX: g_value_set_uint (value, - systray_box_get_size_max (XFCE_SYSTRAY_BOX (plugin->box))); + systray_box_get_size_max (XFCE_SYSTRAY_BOX (plugin->box))); + break; + + case PROP_SQUARE_ICONS: + g_value_set_boolean (value, + systray_box_get_squared (XFCE_SYSTRAY_BOX (plugin->box))); break; case PROP_SHOW_FRAME: @@ -307,7 +320,7 @@ systray_plugin_set_property (GObject *object, GParamSpec *pspec) { SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (object); - gboolean show_frame; + gboolean boolean_val, old_boolean_val; GPtrArray *array; const GValue *tmp; gchar *name; @@ -321,22 +334,39 @@ systray_plugin_set_property (GObject *object, g_value_get_uint (value)); break; + case PROP_SQUARE_ICONS: case PROP_SHOW_FRAME: - show_frame = g_value_get_boolean (value); - if (plugin->show_frame != show_frame) + boolean_val = g_value_get_boolean (value); + old_boolean_val = !systray_box_get_squared (XFCE_SYSTRAY_BOX (plugin->box)) + && plugin->show_frame; + + switch (prop_id) + { + case PROP_SQUARE_ICONS: + systray_box_set_squared (XFCE_SYSTRAY_BOX (plugin->box), boolean_val); + break; + + case PROP_SHOW_FRAME: + plugin->show_frame = boolean_val; + break; + } + + boolean_val = !systray_box_get_squared (XFCE_SYSTRAY_BOX (plugin->box)) + && plugin->show_frame; + + if (old_boolean_val != boolean_val) { - plugin->show_frame = show_frame; gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), - show_frame ? GTK_SHADOW_ETCHED_IN : GTK_SHADOW_NONE); + boolean_val ? GTK_SHADOW_ETCHED_IN : GTK_SHADOW_NONE); // FIXME //style = gtk_rc_style_new (); - //style->xthickness = style->ythickness = show_frame ? 1 : 0; + //style->xthickness = style->ythickness = boolean_val ? 1 : 0; //gtk_widget_modify_style (plugin->frame, style); //g_object_unref (G_OBJECT (style)); systray_plugin_size_changed (XFCE_PANEL_PLUGIN (plugin), - xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin))); + xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin))); } break; @@ -471,6 +501,7 @@ systray_plugin_construct (XfcePanelPlugin *panel_plugin) const PanelProperty properties[] = { { "size-max", G_TYPE_UINT }, + { "square-icons", G_TYPE_BOOLEAN }, { "show-frame", G_TYPE_BOOLEAN }, { "names-ordered", PANEL_PROPERTIES_TYPE_VALUE_ARRAY }, { "names-hidden", PANEL_PROPERTIES_TYPE_VALUE_ARRAY }, @@ -553,8 +584,11 @@ systray_plugin_size_changed (XfcePanelPlugin *panel_plugin, GtkBorder padding; /* set the frame border */ - if (plugin->show_frame && size > 26) - border = 1; + if (!systray_box_get_squared (XFCE_SYSTRAY_BOX (plugin->box)) && + plugin->show_frame && size > 26) + { + border = 1; + } gtk_container_set_border_width (GTK_CONTAINER (frame), border); /* because the allocated size, used in size_requested is always 1 step @@ -565,8 +599,9 @@ systray_plugin_size_changed (XfcePanelPlugin *panel_plugin, ctx = gtk_widget_get_style_context (frame); gtk_style_context_get_padding (ctx, gtk_widget_get_state_flags (frame), &padding); - border += MAX (padding.left+padding.right, padding.top+padding.bottom); - systray_box_set_size_alloc (XFCE_SYSTRAY_BOX (plugin->box), size - border); + border += MAX (padding.left + padding.right, padding.top + padding.bottom); + systray_box_set_size_alloc (XFCE_SYSTRAY_BOX (plugin->box), size - 2 * border, + xfce_panel_plugin_get_nrows (panel_plugin)); return TRUE; } @@ -597,11 +632,20 @@ systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin) G_OBJECT (object), "value", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + object = gtk_builder_get_object (builder, "square-icons"); + panel_return_if_fail (GTK_IS_WIDGET (object)); + g_object_bind_property (G_OBJECT (plugin), "square-icons", + G_OBJECT (object), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + object = gtk_builder_get_object (builder, "show-frame"); panel_return_if_fail (GTK_IS_WIDGET (object)); g_object_bind_property (G_OBJECT (plugin), "show-frame", G_OBJECT (object), "active", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property (G_OBJECT (plugin), "square-icons", + G_OBJECT (object), "sensitive", + G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); store = gtk_builder_get_object (builder, "applications-store"); panel_return_if_fail (GTK_IS_LIST_STORE (store)); -- 2.13.1