[gtksourceview/wip/fix-completion-sizing: 2/2] completion sizing: better implementation
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/fix-completion-sizing: 2/2] completion sizing: better implementation
- Date: Sun, 1 Jun 2014 00:18:54 +0000 (UTC)
commit e2e68932b34b70a0e8b5a68e608128977e13429a
Author: Sébastien Wilmet <swilmet gnome org>
Date: Sun Jun 1 01:26:08 2014 +0200
completion sizing: better implementation
On each "size-allocate" signal on the GtkTreeView, resize the scrolled
window. The functions to calculate the size is more or less the same as
the previous implementation in the custom container, with a bug fix.
https://bugzilla.gnome.org/show_bug.cgi?id=720823
gtksourceview/gtksourcecompletion.c | 178 ++++++++++++++++++++++++++++++++++-
1 files changed, 177 insertions(+), 1 deletions(-)
---
diff --git a/gtksourceview/gtksourcecompletion.c b/gtksourceview/gtksourcecompletion.c
index 17d80bc..1f645b1 100644
--- a/gtksourceview/gtksourcecompletion.c
+++ b/gtksourceview/gtksourcecompletion.c
@@ -91,6 +91,9 @@
#include "gtksourceview-marshal.h"
#include "gtksourceview-i18n.h"
+#define MAX_WIDTH 350
+#define MAX_HEIGHT 180
+
/* Signals */
enum
{
@@ -141,8 +144,8 @@ struct _GtkSourceCompletionPrivate
GtkToggleButton *info_button;
/* List of proposals */
+ GtkScrolledWindow *scrolled_window;
GtkTreeView *tree_view_proposals;
-
GtkCellRenderer *cell_renderer_proposal;
/* Completion management */
@@ -591,6 +594,176 @@ gtk_source_completion_hide_default (GtkSourceCompletion *completion)
gtk_widget_hide (GTK_WIDGET (completion->priv->main_window));
}
+static gint
+get_max_width (GtkSourceCompletion *completion)
+{
+ if (gtk_widget_get_realized (GTK_WIDGET (completion->priv->main_window)))
+ {
+ GdkWindow *window;
+ GdkScreen *screen;
+ gint max_width;
+ gint xorigin;
+
+ window = gtk_widget_get_window (GTK_WIDGET (completion->priv->main_window));
+ screen = gdk_window_get_screen (window);
+
+ gdk_window_get_origin (window, &xorigin, NULL);
+ max_width = gdk_screen_get_width (screen) - xorigin;
+
+ return MAX (max_width, MAX_WIDTH);
+ }
+
+ return MAX_WIDTH;
+}
+
+static gint
+get_vertical_scrollbar_width (void)
+{
+ gint width;
+ GtkWidget *scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, NULL);
+ g_object_ref_sink (scrollbar);
+ gtk_widget_show (scrollbar);
+
+ gtk_widget_get_preferred_width (scrollbar, NULL, &width);
+
+ g_object_unref (scrollbar);
+ return width;
+}
+
+static gint
+get_horizontal_scrollbar_height (void)
+{
+ gint height;
+ GtkWidget *scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, NULL);
+ g_object_ref_sink (scrollbar);
+ gtk_widget_show (scrollbar);
+
+ gtk_widget_get_preferred_height (scrollbar, NULL, &height);
+
+ g_object_unref (scrollbar);
+ return height;
+}
+
+/* This condition is used at several places, and it is important that it is the
+ * same condition. So a function is better.
+ */
+static gboolean
+needs_vertical_scrollbar (gint tree_view_height)
+{
+ return MAX_HEIGHT < tree_view_height;
+}
+
+static void
+get_scrolled_window_width (GtkSourceCompletion *completion,
+ gint tree_view_width,
+ gint tree_view_height,
+ gint *scrolled_window_width,
+ gint *tree_view_available_width)
+{
+ gint width = tree_view_width;
+ gint scrollbar_width = 0;
+
+ g_assert (scrolled_window_width != NULL);
+ g_assert (tree_view_available_width != NULL);
+
+ if (needs_vertical_scrollbar (tree_view_height))
+ {
+ scrollbar_width = get_vertical_scrollbar_width ();
+ width += scrollbar_width;
+ }
+
+ width = MIN (width, get_max_width (completion));
+
+ *scrolled_window_width = width;
+ *tree_view_available_width = width - scrollbar_width;
+}
+
+static gint
+get_row_height (GtkSourceCompletion *completion)
+{
+ GList *columns = gtk_tree_view_get_columns (completion->priv->tree_view_proposals);
+ GList *l;
+ gint max_row_height = 0;
+ gint vertical_separator = 0;
+
+ for (l = columns; l != NULL; l = l->next)
+ {
+ GtkTreeViewColumn *column = l->data;
+ gint row_height;
+
+ gtk_tree_view_column_cell_get_size (column, NULL, NULL, NULL, NULL, &row_height);
+
+ if (row_height > max_row_height)
+ {
+ max_row_height = row_height;
+ }
+ }
+
+ gtk_widget_style_get (GTK_WIDGET (completion->priv->tree_view_proposals),
+ "vertical-separator", &vertical_separator,
+ NULL);
+
+ max_row_height += vertical_separator;
+
+ g_list_free (columns);
+ return max_row_height;
+}
+
+/* Returns a height at a row boundary of the GtkTreeView. */
+static gint
+get_scrolled_window_height (GtkSourceCompletion *completion,
+ gint tree_view_width,
+ gint tree_view_height,
+ gint tree_view_available_width)
+{
+ gint total_height = tree_view_height;
+ gint scrollbar_height = 0;
+
+ if (tree_view_available_width < tree_view_width)
+ {
+ scrollbar_height = get_horizontal_scrollbar_height ();
+ total_height += scrollbar_height;
+ }
+
+ if (needs_vertical_scrollbar (tree_view_height))
+ {
+ gint row_height = get_row_height (completion);
+ gint nb_rows_allowed = MAX_HEIGHT / row_height;
+
+ return nb_rows_allowed * row_height + scrollbar_height;
+ }
+
+ return total_height;
+}
+
+static void
+resize_scrolled_window (GtkSourceCompletion *completion)
+{
+ GtkRequisition nat_size;
+ gint scrolled_window_width = 0;
+ gint scrolled_window_height = 0;
+ gint tree_view_available_width = 0;
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (completion->priv->tree_view_proposals),
+ NULL,
+ &nat_size);
+
+ get_scrolled_window_width (completion,
+ nat_size.width,
+ nat_size.height,
+ &scrolled_window_width,
+ &tree_view_available_width);
+
+ scrolled_window_height = get_scrolled_window_height (completion,
+ nat_size.width,
+ nat_size.height,
+ tree_view_available_width);
+
+ gtk_widget_set_size_request (GTK_WIDGET (completion->priv->scrolled_window),
+ scrolled_window_width,
+ scrolled_window_height);
+}
+
static void
gtk_source_completion_proposals_size_allocate (GtkSourceCompletion *completion,
GtkAllocation *allocation,
@@ -635,6 +808,8 @@ gtk_source_completion_proposals_size_allocate (GtkSourceCompletion *completion,
NULL);
_gtk_source_completion_info_set_xoffset (completion->priv->main_window, -x_offset);
+
+ resize_scrolled_window (completion);
}
static void
@@ -1911,6 +2086,7 @@ init_tree_view (GtkSourceCompletion *completion,
GdkRGBA background_color;
GdkRGBA foreground_color;
+ completion->priv->scrolled_window = GTK_SCROLLED_WINDOW (gtk_builder_get_object (builder,
"scrolled_window"));
completion->priv->tree_view_proposals = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"tree_view_proposals"));
g_signal_connect_swapped (completion->priv->tree_view_proposals,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]