diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2013-10-26 23:53:16 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2013-10-27 00:04:39 +0800 |
commit | 40b868004c9267a77daefc6f3eee4979ebe3a376 (patch) | |
tree | 281da6ab517752aaebbdc0305ca5ed0c711dff94 | |
parent | 22fb5d5f21d9ad8cb0f04cdfafdbe2d079c6d2f8 (diff) | |
download | gsoc2013-evolution-40b868004c9267a77daefc6f3eee4979ebe3a376.tar gsoc2013-evolution-40b868004c9267a77daefc6f3eee4979ebe3a376.tar.gz gsoc2013-evolution-40b868004c9267a77daefc6f3eee4979ebe3a376.tar.bz2 gsoc2013-evolution-40b868004c9267a77daefc6f3eee4979ebe3a376.tar.lz gsoc2013-evolution-40b868004c9267a77daefc6f3eee4979ebe3a376.tar.xz gsoc2013-evolution-40b868004c9267a77daefc6f3eee4979ebe3a376.tar.zst gsoc2013-evolution-40b868004c9267a77daefc6f3eee4979ebe3a376.zip |
Bug 709428 - Searchbar widgets should not wrap
Instead of wrapping the searchbar for small screens (which looks ugly
and breaks the initial window size on large screens), hide the filter
combo box in views that would otherwise be too wide for the screen.
There's no loss of functionality when hiding the filter combo box.
It's just a set of convenient pre-defined searches, all of which can
be reproduced through the Advanced Search interface.
New functions:
e_shell_searchbar_get_filter_visible()
e_shell_searchbar_set_filter_visible()
-rw-r--r-- | doc/reference/evolution-shell/evolution-shell-sections.txt | 2 | ||||
-rw-r--r-- | shell/e-shell-searchbar.c | 318 | ||||
-rw-r--r-- | shell/e-shell-searchbar.h | 9 | ||||
-rw-r--r-- | shell/e-shell-window-private.h | 1 | ||||
-rw-r--r-- | shell/e-shell-window.c | 57 |
5 files changed, 150 insertions, 237 deletions
diff --git a/doc/reference/evolution-shell/evolution-shell-sections.txt b/doc/reference/evolution-shell/evolution-shell-sections.txt index 80d7752f14..0fbe973792 100644 --- a/doc/reference/evolution-shell/evolution-shell-sections.txt +++ b/doc/reference/evolution-shell/evolution-shell-sections.txt @@ -105,6 +105,8 @@ EShellSearchbar e_shell_searchbar_new e_shell_searchbar_get_shell_view e_shell_searchbar_get_filter_combo_box +e_shell_searchbar_get_filter_visible +e_shell_searchbar_set_filter_visible e_shell_searchbar_get_search_hint e_shell_searchbar_set_search_hint e_shell_searchbar_get_search_option diff --git a/shell/e-shell-searchbar.c b/shell/e-shell-searchbar.c index cb04b56e92..9f6adebbcf 100644 --- a/shell/e-shell-searchbar.c +++ b/shell/e-shell-searchbar.c @@ -40,9 +40,6 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_SHELL_SEARCHBAR, EShellSearchbarPrivate)) -/* spacing between "groups" on the search bar */ -#define COLUMN_SPACING 24 - #define SEARCH_OPTION_ADVANCED (-1) /* Default "state key file" group: [Search Bar] */ @@ -68,11 +65,11 @@ struct _EShellSearchbarPrivate { /* Child widget containers (referenced) */ GQueue child_containers; - guint resize_idle_id; /* State Key File */ gchar *state_group; + gboolean filter_visible; gboolean scope_visible; gboolean state_dirty; }; @@ -80,6 +77,7 @@ struct _EShellSearchbarPrivate { enum { PROP_0, PROP_FILTER_COMBO_BOX, + PROP_FILTER_VISIBLE, PROP_SEARCH_HINT, PROP_SEARCH_OPTION, PROP_SEARCH_TEXT, @@ -92,7 +90,7 @@ enum { G_DEFINE_TYPE_WITH_CODE ( EShellSearchbar, e_shell_searchbar, - GTK_TYPE_GRID, + GTK_TYPE_BOX, G_IMPLEMENT_INTERFACE ( E_TYPE_EXTENSIBLE, NULL)) @@ -491,125 +489,6 @@ shell_searchbar_option_changed_cb (GtkRadioAction *action, } static gboolean -shell_searchbar_resize_idle_cb (gpointer user_data) -{ - GtkWidget *widget; - EShellSearchbar *searchbar; - GQueue *child_containers; - GList *head, *link; - GArray *widths; - gint row = 0; - gint column = 0; - gint roww = 0; - gint maxw = 0; - gint child_left; - gint child_top; - gint allocated_width; - gboolean needs_reposition = FALSE; - - widget = GTK_WIDGET (user_data); - allocated_width = gtk_widget_get_allocated_width (widget); - - searchbar = E_SHELL_SEARCHBAR (widget); - child_containers = &searchbar->priv->child_containers; - head = g_queue_peek_head_link (child_containers); - - widths = g_array_new (FALSE, FALSE, sizeof (gint)); - - for (link = head; link != NULL; link = g_list_next (link)) { - GtkWidget *child = GTK_WIDGET (link->data); - gint minw = -1; - - if (!gtk_widget_get_visible (child)) - minw = 0; - else - gtk_widget_get_preferred_width (child, &minw, NULL); - - g_array_append_val (widths, minw); - - if (roww && minw) { - roww += COLUMN_SPACING; - column++; - } - - roww += minw; - - if (minw > maxw) - maxw = minw; - - if (roww > allocated_width) { - row++; - roww = minw; - column = 0; - } - - gtk_container_child_get ( - GTK_CONTAINER (widget), child, - "left-attach", &child_left, - "top-attach", &child_top, - NULL); - - needs_reposition |= - (child_left != column) || - (child_top != row); - - if (column == 0 && row > 0 && roww < maxw) { - /* Columns have the same width, so use - * the wider widget for calculations. */ - roww = maxw; - } - } - - if (needs_reposition) { - guint ii = 0; - - row = 0; - column = 0; - roww = 0; - - g_warn_if_fail (child_containers->length == widths->len); - - for (link = head; link != NULL; link = g_list_next (link)) - gtk_container_remove ( - GTK_CONTAINER (widget), - GTK_WIDGET (link->data)); - - for (link = head; link != NULL; link = g_list_next (link)) { - GtkWidget *child; - gint w; - - child = GTK_WIDGET (link->data); - w = g_array_index (widths, gint, ii++); - - if (roww && w) { - roww += COLUMN_SPACING; - column++; - } - - roww += w; - - if (roww > allocated_width) { - row++; - roww = w; - column = 0; - } - - gtk_grid_attach ( - GTK_GRID (widget), child, column, row, 1, 1); - - if (column == 0 && row > 0 && roww < maxw) - roww = maxw; - } - } - - g_array_free (widths, TRUE); - - searchbar->priv->resize_idle_id = 0; - - return FALSE; -} - -static gboolean shell_searchbar_entry_focus_in_cb (GtkWidget *entry, GdkEvent *event, EShellSearchbar *searchbar) @@ -650,6 +529,12 @@ shell_searchbar_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_FILTER_VISIBLE: + e_shell_searchbar_set_filter_visible ( + E_SHELL_SEARCHBAR (object), + g_value_get_boolean (value)); + return; + case PROP_SEARCH_HINT: e_shell_searchbar_set_search_hint ( E_SHELL_SEARCHBAR (object), @@ -703,6 +588,12 @@ shell_searchbar_get_property (GObject *object, E_SHELL_SEARCHBAR (object))); return; + case PROP_FILTER_VISIBLE: + g_value_set_boolean ( + value, e_shell_searchbar_get_filter_visible ( + E_SHELL_SEARCHBAR (object))); + return; + case PROP_SEARCH_HINT: g_value_set_string ( value, e_shell_searchbar_get_search_hint ( @@ -756,11 +647,6 @@ shell_searchbar_dispose (GObject *object) priv = E_SHELL_SEARCHBAR_GET_PRIVATE (object); - if (priv->resize_idle_id > 0) { - g_source_remove (priv->resize_idle_id); - priv->resize_idle_id = 0; - } - if (priv->shell_view != NULL) { g_object_remove_weak_pointer ( G_OBJECT (priv->shell_view), &priv->shell_view); @@ -776,9 +662,6 @@ shell_searchbar_dispose (GObject *object) g_clear_object (&priv->css_provider); - while (!g_queue_is_empty (&priv->child_containers)) - g_object_unref (g_queue_pop_head (&priv->child_containers)); - /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_shell_searchbar_parent_class)->dispose (object); } @@ -895,51 +778,6 @@ shell_searchbar_map (GtkWidget *widget) } static void -shell_searchbar_size_allocate (GtkWidget *widget, - GdkRectangle *allocation) -{ - EShellSearchbarPrivate *priv; - - priv = E_SHELL_SEARCHBAR_GET_PRIVATE (widget); - - /* Chain up to parent's size_allocate() method. */ - GTK_WIDGET_CLASS (e_shell_searchbar_parent_class)-> - size_allocate (widget, allocation); - - if (priv->resize_idle_id == 0) - priv->resize_idle_id = g_idle_add ( - shell_searchbar_resize_idle_cb, widget); -} - -static void -shell_searchbar_get_preferred_width (GtkWidget *widget, - gint *minimum_width, - gint *natural_width) -{ - GList *children, *iter; - gint max_minimum = 0, max_natural = 0; - - children = gtk_container_get_children (GTK_CONTAINER (widget)); - for (iter = children; iter != NULL; iter = iter->next) { - GtkWidget *child = iter->data; - gint minimum = 0, natural = 0; - - if (gtk_widget_get_visible (child)) { - gtk_widget_get_preferred_width (child, &minimum, &natural); - if (minimum > max_minimum) - max_minimum = minimum; - if (natural > max_natural) - max_natural = natural; - } - } - - g_list_free (children); - - *minimum_width = max_minimum + COLUMN_SPACING; - *natural_width = max_natural + COLUMN_SPACING; -} - -static void e_shell_searchbar_class_init (EShellSearchbarClass *class) { GObjectClass *object_class; @@ -956,8 +794,6 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) widget_class = GTK_WIDGET_CLASS (class); widget_class->map = shell_searchbar_map; - widget_class->size_allocate = shell_searchbar_size_allocate; - widget_class->get_preferred_width = shell_searchbar_get_preferred_width; g_object_class_install_property ( object_class, @@ -972,6 +808,18 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) g_object_class_install_property ( object_class, + PROP_FILTER_VISIBLE, + g_param_spec_boolean ( + "filter-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, PROP_SEARCH_HINT, g_param_spec_string ( "search-hint", @@ -1064,89 +912,66 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) static void e_shell_searchbar_init (EShellSearchbar *searchbar) { - GtkGrid *grid; + GtkBox *box; GtkLabel *label; GtkWidget *widget; - GQueue *child_containers; searchbar->priv = E_SHELL_SEARCHBAR_GET_PRIVATE (searchbar); - child_containers = &searchbar->priv->child_containers; - - gtk_grid_set_column_spacing (GTK_GRID (searchbar), COLUMN_SPACING); - gtk_grid_set_row_spacing (GTK_GRID (searchbar), 4); + gtk_box_set_spacing (GTK_BOX (searchbar), 6); /* Filter Combo Widgets */ - grid = GTK_GRID (searchbar); + box = GTK_BOX (searchbar); - widget = gtk_grid_new (); - g_object_set ( - G_OBJECT (widget), - "orientation", GTK_ORIENTATION_HORIZONTAL, - "border-width", 3, - "column-spacing", 3, - "valign", GTK_ALIGN_CENTER, - NULL); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); - gtk_widget_show (widget); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); - g_queue_push_tail (child_containers, g_object_ref (widget)); + g_object_bind_property ( + searchbar, "filter-visible", + widget, "visible", + G_BINDING_SYNC_CREATE); - grid = GTK_GRID (widget); + box = GTK_BOX (widget); /* Translators: The "Show:" label precedes a combo box that * allows the user to filter the current view. Examples of * items that appear in the combo box are "Unread Messages", * "Important Messages", or "Active Appointments". */ widget = gtk_label_new_with_mnemonic (_("Sho_w:")); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); label = GTK_LABEL (widget); widget = e_action_combo_box_new (); gtk_label_set_mnemonic_widget (label, widget); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); searchbar->priv->filter_combo_box = widget; gtk_widget_show (widget); /* Search Entry Widgets */ - grid = GTK_GRID (searchbar); + box = GTK_BOX (searchbar); - widget = gtk_grid_new (); - g_object_set ( - G_OBJECT (widget), - "orientation", GTK_ORIENTATION_HORIZONTAL, - "column-spacing", 3, - "valign", GTK_ALIGN_CENTER, - "halign", GTK_ALIGN_FILL, - "hexpand", TRUE, - NULL); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + gtk_widget_set_margin_left (widget, 12); + gtk_box_pack_start (box, widget, TRUE, TRUE, 0); gtk_widget_show (widget); - g_queue_push_tail (child_containers, g_object_ref (widget)); - - grid = GTK_GRID (widget); + box = GTK_BOX (widget); /* Translators: This is part of the quick search interface. * example: Search: [_______________] in [ Current Folder ] */ widget = gtk_label_new_with_mnemonic (_("Sear_ch:")); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); label = GTK_LABEL (widget); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (label, widget); - g_object_set ( - G_OBJECT (widget), - "halign", GTK_ALIGN_FILL, - "hexpand", TRUE, - NULL); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + gtk_box_pack_start (box, widget, TRUE, TRUE, 0); searchbar->priv->search_entry = widget; gtk_widget_show (widget); @@ -1192,37 +1017,29 @@ e_shell_searchbar_init (EShellSearchbar *searchbar) /* Scope Combo Widgets */ - grid = GTK_GRID (searchbar); - - widget = gtk_grid_new (); - g_object_set ( - G_OBJECT (widget), - "orientation", GTK_ORIENTATION_HORIZONTAL, - "column-spacing", 3, - "valign", GTK_ALIGN_CENTER, - NULL); - gtk_grid_attach (grid, widget, 2, 0, 1, 1); + box = GTK_BOX (searchbar); - g_queue_push_tail (child_containers, g_object_ref (widget)); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); g_object_bind_property ( searchbar, "scope-visible", widget, "visible", G_BINDING_SYNC_CREATE); - grid = GTK_GRID (widget); + box = GTK_BOX (widget); /* Translators: This is part of the quick search interface. * example: Search: [_______________] in [ Current Folder ] */ widget = gtk_label_new_with_mnemonic (_("i_n")); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); label = GTK_LABEL (widget); widget = e_action_combo_box_new (); gtk_label_set_mnemonic_widget (label, widget); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); searchbar->priv->scope_combo_box = widget; gtk_widget_show (widget); @@ -1280,6 +1097,37 @@ e_shell_searchbar_get_filter_combo_box (EShellSearchbar *searchbar) return E_ACTION_COMBO_BOX (searchbar->priv->filter_combo_box); } +gboolean +e_shell_searchbar_get_filter_visible (EShellSearchbar *searchbar) +{ + g_return_val_if_fail (E_IS_SHELL_SEARCHBAR (searchbar), FALSE); + + return searchbar->priv->filter_visible; +} + +void +e_shell_searchbar_set_filter_visible (EShellSearchbar *searchbar, + gboolean filter_visible) +{ + g_return_if_fail (E_IS_SHELL_SEARCHBAR (searchbar)); + + if (searchbar->priv->filter_visible == filter_visible) + return; + + searchbar->priv->filter_visible = filter_visible; + + /* If we're hiding the filter combo box, reset it to its + * first item so that no content gets permanently hidden. */ + if (!filter_visible) { + EActionComboBox *combo_box; + + combo_box = e_shell_searchbar_get_filter_combo_box (searchbar); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); + } + + g_object_notify (G_OBJECT (searchbar), "filter-visible"); +} + const gchar * e_shell_searchbar_get_search_hint (EShellSearchbar *searchbar) { diff --git a/shell/e-shell-searchbar.h b/shell/e-shell-searchbar.h index f8b34c2f9c..2d4ada5397 100644 --- a/shell/e-shell-searchbar.h +++ b/shell/e-shell-searchbar.h @@ -57,12 +57,12 @@ typedef struct _EShellSearchbarPrivate EShellSearchbarPrivate; * functions below. **/ struct _EShellSearchbar { - GtkGrid parent; + GtkBox parent; EShellSearchbarPrivate *priv; }; struct _EShellSearchbarClass { - GtkGridClass parent_class; + GtkBoxClass parent_class; }; GType e_shell_searchbar_get_type (void); @@ -72,6 +72,11 @@ EShellView * e_shell_searchbar_get_shell_view EActionComboBox * e_shell_searchbar_get_filter_combo_box (EShellSearchbar *searchbar); +gboolean e_shell_searchbar_get_filter_visible + (EShellSearchbar *searchbar); +void e_shell_searchbar_set_filter_visible + (EShellSearchbar *searchbar, + gboolean filter_visible); const gchar * e_shell_searchbar_get_search_hint (EShellSearchbar *searchbar); void e_shell_searchbar_set_search_hint diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h index 3572bf5000..31d9b77af0 100644 --- a/shell/e-shell-window-private.h +++ b/shell/e-shell-window-private.h @@ -32,6 +32,7 @@ #include <e-shell.h> #include <e-shell-content.h> #include <e-shell-view.h> +#include <e-shell-searchbar.h> #include <e-shell-switcher.h> #include <e-shell-window-actions.h> #include <e-shell-utils.h> diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c index f19af058cf..20af727664 100644 --- a/shell/e-shell-window.c +++ b/shell/e-shell-window.c @@ -172,6 +172,21 @@ shell_window_update_close_action_cb (EShellWindow *shell_window) } static void +shell_window_tweak_for_small_screen (EShellWindow *shell_window) +{ + EShellView *shell_view; + GtkWidget *shell_searchbar; + const gchar *active_view; + + active_view = e_shell_window_get_active_view (shell_window); + shell_view = e_shell_window_get_shell_view (shell_window, active_view); + shell_searchbar = e_shell_view_get_searchbar (shell_view); + + e_shell_searchbar_set_filter_visible ( + E_SHELL_SEARCHBAR (shell_searchbar), FALSE); +} + +static void shell_window_set_geometry (EShellWindow *shell_window, const gchar *geometry) { @@ -377,6 +392,40 @@ shell_window_constructed (GObject *object) } static void +shell_window_get_preferred_width (GtkWidget *widget, + gint *out_minimum_width, + gint *out_natural_width) +{ + GdkScreen *screen; + gint screen_width; + gint minimum_width = 0; + gint natural_width = 0; + gboolean tweaked = FALSE; + + screen = gtk_widget_get_screen (widget); + screen_width = gdk_screen_get_width (screen); + +try_again: + /* Chain up to parent's get_preferred_width() method. */ + GTK_WIDGET_CLASS (e_shell_window_parent_class)-> + get_preferred_width (widget, &minimum_width, &natural_width); + + if (!tweaked && minimum_width > screen_width) { + EShellWindow *shell_window; + + shell_window = E_SHELL_WINDOW (widget); + shell_window_tweak_for_small_screen (shell_window); + + tweaked = TRUE; /* prevents looping */ + + goto try_again; + } + + *out_minimum_width = minimum_width; + *out_natural_width = natural_width; +} + +static void shell_window_close_alert (EShellWindow *shell_window) { EShellView *shell_view; @@ -746,6 +795,7 @@ static void e_shell_window_class_init (EShellWindowClass *class) { GObjectClass *object_class; + GtkWidgetClass *widget_class; GtkBindingSet *binding_set; g_type_class_add_private (class, sizeof (EShellWindowPrivate)); @@ -757,6 +807,9 @@ e_shell_window_class_init (EShellWindowClass *class) object_class->finalize = shell_window_finalize; object_class->constructed = shell_window_constructed; + widget_class = GTK_WIDGET_CLASS (class); + widget_class->get_preferred_width = shell_window_get_preferred_width; + class->close_alert = shell_window_close_alert; class->construct_menubar = shell_window_construct_menubar; class->construct_toolbar = shell_window_construct_toolbar; @@ -1330,6 +1383,10 @@ e_shell_window_set_active_view (EShellWindow *shell_window, action = e_shell_view_get_action (shell_view); gtk_action_activate (action); + + /* Renegotiate the shell window size in case a newly-created + * shell view needs tweaked to accommodate a smaller screen. */ + gtk_widget_queue_resize (GTK_WIDGET (shell_window)); } /** |