aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2004-05-05 23:36:37 +0800
committerDan Winship <danw@src.gnome.org>2004-05-05 23:36:37 +0800
commit12fb773502ff61c55d40f78a513f6e8bb9b30380 (patch)
tree9cd9695b52697a13a82b3bd0e6aaf3451ffce616
parent6cb88a7819367f8ece5b563a2910571d3c46f77e (diff)
downloadgsoc2013-evolution-12fb773502ff61c55d40f78a513f6e8bb9b30380.tar.gz
gsoc2013-evolution-12fb773502ff61c55d40f78a513f6e8bb9b30380.tar.zst
gsoc2013-evolution-12fb773502ff61c55d40f78a513f6e8bb9b30380.zip
Change the algorithm so that if the buttons can't be laid out perfectly
* e-sidebar.c (layout_buttons): Change the algorithm so that if the buttons can't be laid out perfectly rectangularly, then the extra space is given to the first button (ie, Mail), rather than the last button (eg, Connector). Also, merge the icons-only and icons-plus-text layout code together since they were nearly identical. (e_sidebar_add_button, e_sidebar_set_mode): Tweak things a bit so that in icons-only mode, the icons are centered in the buttons. svn path=/trunk/; revision=25807
-rw-r--r--shell/ChangeLog11
-rw-r--r--shell/e-sidebar.c199
2 files changed, 75 insertions, 135 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 99c7a79424..658dbc471f 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,14 @@
+2004-05-05 Dan Winship <danw@ximian.com>
+
+ * e-sidebar.c (layout_buttons): Change the algorithm so that if
+ the buttons can't be laid out perfectly rectangularly, then the
+ extra space is given to the first button (ie, Mail), rather than
+ the last button (eg, Connector). Also, merge the icons-only and
+ icons-plus-text layout code together since they were nearly
+ identical.
+ (e_sidebar_add_button, e_sidebar_set_mode): Tweak things a bit so
+ that in icons-only mode, the icons are centered in the buttons.
+
2004-05-03 Dan Winship <danw@ximian.com>
* e-shell-importer.c (e_shell_importer_start_import): Fix warnings
diff --git a/shell/e-sidebar.c b/shell/e-sidebar.c
index d4362066c6..40a45b5581 100644
--- a/shell/e-sidebar.c
+++ b/shell/e-sidebar.c
@@ -40,7 +40,8 @@ static GtkContainerClass *parent_class = NULL;
typedef struct {
GtkWidget *button_widget;
- GtkWidget *label_widget;
+ GtkWidget *label;
+ GtkWidget *icon;
GtkWidget *hbox;
int id;
} Button;
@@ -70,17 +71,20 @@ static unsigned int signals[NUM_SIGNALS] = { 0 };
/* Utility functions. */
static Button *
-button_new (GtkWidget *button_widget, GtkWidget *label_widget, GtkWidget *hbox, int id)
+button_new (GtkWidget *button_widget, GtkWidget *label, GtkWidget *icon,
+ GtkWidget *hbox, int id)
{
Button *button = g_new (Button, 1);
button->button_widget = button_widget;
- button->label_widget = label_widget;
+ button->label = label;
+ button->icon = icon;
button->hbox = hbox;
button->id = id;
g_object_ref (button_widget);
- g_object_ref (label_widget);
+ g_object_ref (label);
+ g_object_ref (icon);
g_object_ref (hbox);
return button;
@@ -90,7 +94,8 @@ static void
button_free (Button *button)
{
g_object_unref (button->button_widget);
- g_object_unref (button->label_widget);
+ g_object_unref (button->label);
+ g_object_unref (button->icon);
g_object_unref (button->hbox);
g_free (button);
}
@@ -146,68 +151,75 @@ button_toggled_callback (GtkToggleButton *toggle_button,
}
-/* Layout. */
+/* Layout. */
static int
-do_layout_text_buttons (ESidebar *sidebar)
+layout_buttons (ESidebar *sidebar)
{
GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation;
- GSList *rows [g_slist_length (sidebar->priv->buttons)];
- GSList *p;
+ gboolean icons_only = (sidebar->priv->mode == E_SIDEBAR_MODE_ICON);
+ int num_btns = g_slist_length (sidebar->priv->buttons), btns_per_row;
+ GSList **rows, *p;
+ Button *button;
int row_number;
- int row_width;
int max_btn_width = 0, max_btn_height = 0;
- int btns_required;
int row_last;
int x, y;
int i;
- /* (Yes, this code calls gtk_widget_size_request() an ungodly number of times, but it's not
- like we care about performance here, and this makes the code simpler.) */
-
+ /* (Yes, this code calls gtk_widget_size_request() an ungodly
+ * number of times, but it's not like we care about
+ * performance here, and this makes the code simpler.)
+ */
- /* 1. Figure out the max width and height */
+ /* Figure out the max width and height */
for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
GtkRequisition requisition;
+ button = p->data;
gtk_widget_size_request (GTK_WIDGET (button->button_widget), &requisition);
- max_btn_height = MAX (max_btn_height, requisition.height);
+ max_btn_height = MAX (max_btn_height, requisition.height);
max_btn_width = MAX (max_btn_width, requisition.width);
+ }
+ /* Figure out how many rows and columns we'll use. */
+ btns_per_row = allocation->width / (max_btn_width + H_PADDING);
+ if (!icons_only) {
+ /* If using text buttons, we want to try to have a
+ * completely filled-in grid, but if we can't, we want
+ * the odd row to have just a single button.
+ */
+ while (num_btns % btns_per_row > 1)
+ btns_per_row--;
}
- /* 2. Split the buttons into rows, depending on the max_btn_width. */
+ /* Assign buttons to rows */
+ rows = g_new0 (GSList *, num_btns / btns_per_row + 1);
- row_number = 0;
- rows [0] = NULL;
- row_width = H_PADDING;
- btns_required = allocation->width / (max_btn_width + H_PADDING);
- for (; btns_required > 2; btns_required--) {
- if (g_slist_length (sidebar->priv->buttons) % btns_required == 0)
- break;
+ if (!icons_only && num_btns % btns_per_row != 0) {
+ button = sidebar->priv->buttons->data;
+ rows [0] = g_slist_append (rows [0], button->button_widget);
+ p = sidebar->priv->buttons->next;
+ row_number = 1;
+ } else {
+ p = sidebar->priv->buttons;
+ row_number = 0;
}
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
- if (g_slist_length (rows[row_number]) % btns_required == 0
- && rows [row_number] != NULL) {
+ for (; p != NULL; p = p->next) {
+ button = p->data;
+
+ if (g_slist_length (rows [row_number]) == btns_per_row)
row_number ++;
- rows [row_number] = NULL;
- row_width = H_PADDING;
- }
- row_width += max_btn_width + H_PADDING;
rows [row_number] = g_slist_append (rows [row_number], button->button_widget);
}
row_last = row_number;
- /* 3. Layout the buttons. */
-
+ /* Layout the buttons. */
y = allocation->y + allocation->height - V_PADDING - 1;
for (i = row_last; i >= 0; i --) {
int len, extra_width;
@@ -215,7 +227,10 @@ do_layout_text_buttons (ESidebar *sidebar)
y -= max_btn_height;
x = H_PADDING + allocation->x;
len = g_slist_length (rows[i]);
- extra_width = (allocation->width - (len * max_btn_width ) - (len * H_PADDING)) / len;
+ if (sidebar->priv->mode == E_SIDEBAR_MODE_TEXT)
+ extra_width = (allocation->width - (len * max_btn_width ) - (len * H_PADDING)) / len;
+ else
+ extra_width = 0;
for (p = rows [i]; p != NULL; p = p->next) {
GtkAllocation child_allocation;
@@ -232,91 +247,9 @@ do_layout_text_buttons (ESidebar *sidebar)
y -= V_PADDING;
}
- /* 4. Free stuff */
-
- for (i = 0; i <= row_last; i ++)
- g_slist_free (rows [i]);
-
- return y;
-}
-
-static int
-do_layout_icon_buttons (ESidebar *sidebar)
-{
- GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation;
- GSList *rows [g_slist_length (sidebar->priv->buttons)];
- GSList *p;
- int row_number;
- int row_width;
- int row_last;
- int x, y;
- int i;
-
- /* (Yes, this code calls gtk_widget_size_request() an ungodly number of times, but it's not
- like we care about performance here, and this makes the code simpler.) */
-
- /* 1. Split the buttons into rows, depending on their width. */
-
- row_number = 0;
- rows [0] = NULL;
- row_width = H_PADDING;
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
- GtkRequisition requisition;
-
- gtk_widget_size_request (GTK_WIDGET (button->button_widget), &requisition);
-
- if (row_width + requisition.width + H_PADDING >= allocation->width
- && rows [row_number] != NULL) {
- row_number ++;
- rows [row_number] = NULL;
- row_width = H_PADDING;
- }
-
- row_width += requisition.width + H_PADDING;
- rows [row_number] = g_slist_append (rows [row_number], button->button_widget);
- }
-
- row_last = row_number;
-
- /* 2. Layout the buttons. */
-
- y = allocation->y + allocation->height - V_PADDING - 1;
- for (i = row_last; i >= 0; i --) {
- int row_height = 0;
-
- for (p = rows [i]; p != NULL; p = p->next) {
- GtkRequisition requisition;
-
- gtk_widget_size_request (GTK_WIDGET (p->data), &requisition);
- row_height = MAX (row_height, requisition.height);
- }
-
- y -= row_height;
- x = H_PADDING;
- for (p = rows [i]; p != NULL; p = p->next) {
- GtkRequisition requisition;
- GtkAllocation child_allocation;
-
- gtk_widget_size_request (GTK_WIDGET (p->data), &requisition);
-
- child_allocation.x = x;
- child_allocation.y = y;
- child_allocation.width = requisition.width;
- child_allocation.height = requisition.height;
-
- gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation);
-
- x += requisition.width + H_PADDING;
- }
-
- y -= V_PADDING;
- }
-
- /* 3. Free stuff */
-
for (i = 0; i <= row_last; i ++)
g_slist_free (rows [i]);
+ g_free (rows);
return y;
}
@@ -328,17 +261,7 @@ do_layout (ESidebar *sidebar)
GtkAllocation child_allocation;
int y;
- switch (sidebar->priv->mode) {
- case E_SIDEBAR_MODE_TEXT:
- y = do_layout_text_buttons (sidebar);
- break;
- case E_SIDEBAR_MODE_ICON:
- y = do_layout_icon_buttons (sidebar);
- break;
- default:
- g_assert_not_reached ();
- return;
- }
+ y = layout_buttons (sidebar);
/* Place the selection widget. */
child_allocation.x = allocation->x;
@@ -546,11 +469,11 @@ e_sidebar_add_button (ESidebar *sidebar,
icon_widget = gtk_image_new_from_pixbuf (icon);
label_widget = gtk_label_new (label);
gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (hbox), icon_widget, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), icon_widget, sidebar->priv->mode == E_SIDEBAR_MODE_ICON, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (button_widget), hbox);
- sidebar->priv->buttons = g_slist_append (sidebar->priv->buttons, button_new (button_widget, label_widget, hbox, id));
+ sidebar->priv->buttons = g_slist_append (sidebar->priv->buttons, button_new (button_widget, label_widget, icon_widget, hbox, id));
gtk_widget_set_parent (button_widget, GTK_WIDGET (sidebar));
if (sidebar->priv->mode == E_SIDEBAR_MODE_ICON)
@@ -587,10 +510,16 @@ e_sidebar_set_mode (ESidebar *sidebar, ESidebarMode mode)
switch (mode) {
case E_SIDEBAR_MODE_TEXT:
- gtk_box_pack_start (GTK_BOX (button->hbox), button->label_widget, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, TRUE, 0);
+ gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon,
+ "expand", FALSE,
+ NULL);
break;
case E_SIDEBAR_MODE_ICON:
- gtk_container_remove (GTK_CONTAINER (button->hbox), button->label_widget);
+ gtk_container_remove (GTK_CONTAINER (button->hbox), button->label);
+ gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon,
+ "expand", TRUE,
+ NULL);
break;
default:
g_assert_not_reached ();