[gtksourceview/wip/fix-completion-sizing: 1/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: 1/2] completion sizing: better implementation
- Date: Sun, 1 Jun 2014 15:19:57 +0000 (UTC)
commit 96ae0925648f228d573b71dd6d566ac7e333cca6
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, but with bug fixes.
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]