[gtk+/wip/csoriano/pathbar-prototype: 165/166] more size management
- From: Carlos Soriano Sánchez <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/csoriano/pathbar-prototype: 165/166] more size management
- Date: Mon, 2 Nov 2015 23:23:57 +0000 (UTC)
commit ae3b1747ade231fb0a907816e9147ecbc558acd8
Author: Carlos Soriano <csoriano gnome org>
Date: Fri Oct 30 19:59:13 2015 +0100
more size management
gtk/gtkpathbar.c | 161 +++++++++++++++++++++++-------
gtk/theme/Adwaita/_common.scss | 7 +-
gtk/theme/Adwaita/gtk-contained-dark.css | 7 +-
gtk/theme/Adwaita/gtk-contained.css | 7 +-
gtk/ui/gtkpathbar.ui | 4 +-
tests/testpathbar.c | 4 +-
6 files changed, 140 insertions(+), 50 deletions(-)
---
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index d44bce0..2ce434c 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -24,6 +24,7 @@
#include "gtkbutton.h"
#include "gtktogglebutton.h"
#include "gtklabel.h"
+#include "gtkpopover.h"
#include "gtkbuilder.h"
#include "gtkstylecontext.h"
@@ -37,6 +38,8 @@ struct _GtkPathBarPrivate
GtkWidget *overflow_button;
gchar *path;
+ GList *overflow_path_chunks;
+ GList *path_chunks;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkPathBar, gtk_path_bar, GTK_TYPE_BOX)
@@ -55,6 +58,11 @@ enum {
static GParamSpec *path_bar_properties[LAST_PROP] = { NULL, };
static guint path_bar_signals[LAST_SIGNAL] = { 0 };
+typedef struct {
+ gchar *label;
+ GString *path;
+} PathChunkData;
+
static void
on_path_chunk_button_clicked (GtkPathBar *self,
GtkButton *path_chunk_button)
@@ -74,48 +82,98 @@ create_separator ()
return label;
}
+static void
+free_path_chunk_data (PathChunkData *data)
+{
+ g_free (data->label);
+ g_string_free (data->path, TRUE);
+ g_slice_free (PathChunkData, data);
+}
+
GtkWidget *
create_path_chunk (GtkPathBar *self,
+ const GString *path,
const gchar *label)
{
GtkWidget *button;
GtkStyleContext *style;
+ PathChunkData *path_chunk_data;
button = gtk_toggle_button_new_with_label (label);
+ path_chunk_data = g_slice_new (PathChunkData);
+ path_chunk_data->label = g_strdup (label);
+ path_chunk_data->path = g_string_new (path->str);
+
+ g_object_set_data_full (G_OBJECT (button), "data",
+ path_chunk_data, (GDestroyNotify) free_path_chunk_data);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (on_path_chunk_button_clicked), self);
gtk_widget_show (button);
style = gtk_widget_get_style_context (button);
- gtk_style_context_add_class (style, "image-button");
gtk_style_context_add_class (style, "flat");
- gtk_style_context_add_class (style, "button-simplic");
return button;
}
+static void
+popup_overflow_menu (GtkPathBar *self)
+{
+ GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
+ GList *l;
+ PathChunkData *data;
+ GtkWidget *path_chunk;
+ GtkWidget *overflow_box;
+ GtkWidget *popover;
+
+ overflow_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_widget_show (overflow_box);
+ popover = gtk_popover_new (priv->overflow_button);
+ gtk_container_add (GTK_CONTAINER (popover), overflow_box);
+ for (l = priv->path_chunks; l != NULL; l = l->next)
+ {
+ if (!gtk_widget_get_child_visible (l->data))
+ {
+ data = g_object_get_data (l->data, "data");
+ path_chunk = create_path_chunk (self, (const GString*) data->path, (const gchar*) data->label);
+ gtk_container_add (GTK_CONTAINER (overflow_box), path_chunk);
+ }
+ }
+
+ gtk_widget_show (popover);
+}
+
void
gtk_path_bar_set_path (GtkPathBar *self,
const gchar *path)
{
GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
gchar ** splitted_path;
+ GString *current_path = NULL;
+ GtkWidget *path_chunk;
g_return_if_fail (GTK_IS_PATH_BAR (self));
gtk_container_foreach (GTK_CONTAINER (priv->path_box), (GtkCallback) gtk_widget_destroy, NULL);
+ g_list_free (priv->path_chunks);
+ priv->path_chunks = NULL;
splitted_path = g_strsplit (path, "/", -1);
+ current_path = g_string_new ("/");
for (guint i = 0; i < g_strv_length (splitted_path); i++)
{
if (g_strcmp0 (splitted_path[i], "") == 0)
continue;
- gtk_container_add (GTK_CONTAINER (priv->path_box), create_path_chunk (self, splitted_path[i]));
+ g_string_append (current_path, splitted_path[i]);
+ path_chunk = create_path_chunk (self, current_path, splitted_path[i]);
+ priv->path_chunks = g_list_append (priv->path_chunks, path_chunk);
+ gtk_container_add (GTK_CONTAINER (priv->path_box), path_chunk);
gtk_container_add (GTK_CONTAINER (priv->path_box), create_separator ());
}
g_object_notify_by_pspec (G_OBJECT (self), path_bar_properties[PROP_PATH]);
g_strfreev (splitted_path);
+ g_string_free (current_path, TRUE);
}
GtkWidget *
@@ -192,9 +250,6 @@ get_path_preferred_width (GtkWidget *self,
*min_width += child_min_width;
*nat_width += child_nat_width;
}
-
- g_print ("path nat width %d nat_width %d\n", *nat_width, *min_width);
-
}
static void
@@ -203,16 +258,18 @@ get_preferred_width (GtkWidget *self,
gint *nat_width)
{
GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
- gint child_min_width;
+ gint overflow_button_min_width;
+ gint overflow_button_nat_width;
*min_width = 0;
*nat_width = 0;
get_path_preferred_width (self, min_width, nat_width);
- gtk_widget_get_preferred_width (priv->overflow_button, &child_min_width, NULL);
+ gtk_widget_get_preferred_width (priv->overflow_button, &overflow_button_min_width,
&overflow_button_nat_width);
- *min_width = MIN (child_min_width, *min_width);
- g_print ("nat width %d nat_width %d\n", *nat_width, *min_width);
+ *min_width = MIN (overflow_button_min_width, *min_width);
+ *nat_width = MAX (overflow_button_nat_width, *nat_width);
+ g_print ("PREFERRED WIDTH nat width %d min_width %d\n", *nat_width, *min_width);
}
static void
@@ -245,9 +302,6 @@ get_path_preferred_height (GtkWidget *self,
*min_height = MAX (*min_height, child_min_height);
*nat_height = MAX (*nat_height, child_nat_height);
}
-
- g_print ("path nat height %d min_heigh %d\n", *nat_height, *min_height);
-
}
static void
@@ -309,34 +363,74 @@ allocate_overflow_button (GtkWidget *self,
}
static void
+update_visible_children (GtkWidget *self,
+ GtkAllocation *container_allocation)
+{
+ GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
+ GList *children;
+ GList *l;
+ gint child_nat_width;
+ gint child_min_width;
+ gboolean overflow;
+ gint path_min_width;
+ gint path_nat_width;
+ gint min_width;
+ gint nat_width;
+ gboolean allocate_more_children = TRUE;
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->path_box));
+ children = g_list_reverse (children);
+ min_width = 0;
+ nat_width = 0;
+
+ get_path_preferred_width (self, &path_min_width, &path_nat_width);
+ overflow = container_allocation->width < path_min_width;
+
+ if (overflow)
+ {
+ gint overflow_button_min_width;
+
+ gtk_widget_get_preferred_width (priv->overflow_button, &overflow_button_min_width, NULL);
+ min_width += overflow_button_min_width;
+ nat_width += overflow_button_min_width;
+ }
+
+ for (l = children; l != NULL; l = l->next)
+ {
+ gtk_widget_get_preferred_width (l->data, &child_min_width, &child_nat_width);
+ if (min_width + child_min_width <= container_allocation->width && allocate_more_children)
+ {
+ gtk_widget_set_child_visible (l->data, TRUE);
+ min_width += child_min_width;
+ nat_width += child_nat_width;
+ }
+ else
+ {
+ gtk_widget_set_child_visible (l->data, FALSE);
+ allocate_more_children = FALSE;
+ }
+ }
+}
+
+
+static void
size_allocate (GtkWidget *self,
GtkAllocation *allocation)
{
GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
- GdkWindow *internal_window;
gint child_min_width;
gint child_nat_width;
gint path_min_width;
gint path_nat_width;
- gint overflow_button_min_width;
gint current_x_pos;
GtkAllocation child_allocation;
GtkTextDirection direction;
- gboolean allocate_more_children = TRUE;
gboolean overflow;
GList *children;
GList *l;
gtk_widget_set_allocation (self, allocation);
- internal_window = gtk_widget_get_window (self);
- if (internal_window)
- gdk_window_move_resize (internal_window,
- allocation->x, allocation->y,
- allocation->width, allocation->height);
-
- gtk_widget_set_child_visible (priv->overflow_button, FALSE);
-
children = gtk_container_get_children (GTK_CONTAINER (priv->path_box));
if (g_list_length (children) == 0)
@@ -345,13 +439,15 @@ size_allocate (GtkWidget *self,
get_path_preferred_width (self, &path_min_width, &path_nat_width);
overflow = allocation->width < path_min_width;
direction = gtk_widget_get_direction (self);
- g_print ("text dir %d\n", direction);
current_x_pos = direction == GTK_TEXT_DIR_LTR ? allocation->x : allocation->width;
- gtk_widget_get_preferred_width (priv->overflow_button, &overflow_button_min_width, NULL);
+ if (!overflow)
+ gtk_widget_set_child_visible (priv->overflow_button, FALSE);
+
if (overflow && direction == GTK_TEXT_DIR_LTR)
allocate_overflow_button (self, allocation, ¤t_x_pos);
+ update_visible_children (self, allocation);
for (l = children; l != NULL; l = l->next)
{
gtk_widget_get_preferred_width (l->data, &child_min_width, &child_nat_width);
@@ -359,12 +455,9 @@ size_allocate (GtkWidget *self,
child_allocation.y = allocation->y;
child_allocation.height = allocation->height;
g_print ("current x %d child alloc %d alloc %d\n", current_x_pos, child_allocation.width,
allocation->width);
- if (((direction == GTK_TEXT_DIR_LTR && current_x_pos + child_allocation.width < allocation->width) ||
- (direction == GTK_TEXT_DIR_RTL && current_x_pos - child_allocation.width > allocation->x)) &&
- allocate_more_children)
+ if (gtk_widget_get_child_visible (l->data))
{
child_allocation.x = current_x_pos;
- gtk_widget_set_child_visible (l->data, TRUE);
gtk_widget_size_allocate (l->data, &child_allocation);
if (direction == GTK_TEXT_DIR_LTR)
@@ -372,17 +465,11 @@ size_allocate (GtkWidget *self,
else
current_x_pos -= child_allocation.width;
}
- else
- {
- gtk_widget_set_child_visible (l->data, FALSE);
- allocate_more_children = FALSE;
- }
}
if (overflow && direction == GTK_TEXT_DIR_RTL)
allocate_overflow_button (self, allocation, ¤t_x_pos);
- // allocate box
child_allocation.x = allocation->x;
child_allocation.width = current_x_pos;
child_allocation.y = allocation->y;
@@ -467,7 +554,7 @@ gtk_path_bar_class_init (GtkPathBarClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GtkPathBar, overflow_button);
gtk_widget_class_bind_template_child_private (widget_class, GtkPathBar, path_box);
- gtk_widget_class_bind_template_callback (widget_class, on_path_chunk_button_clicked);
+ gtk_widget_class_bind_template_callback (widget_class, popup_overflow_menu);
gtk_widget_class_set_css_name (widget_class, "path-bar");
}
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 295a4b6..f9f587f 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -1242,18 +1242,19 @@ headerbar {
path-bar .button.flat {
background-image: none;
border-radius: 0px;
- border-color: transparent;
+ border-top-color: transparent;
+ border-width: 2px 0px 2px 0px;
box-shadow: 0px 0px 0px;
margin: 0px;
opacity: 0.55;
padding: 3px 8px 4px;
&:hover {
- box-shadow: 0px 2px 0px mix($selected_bg_color, $selected_fg_color, 75%);
+ border-bottom-color: mix($selected_bg_color, $selected_fg_color, 75%);
}
&:checked {
- box-shadow: 0px 2px 0px $selected_bg_color;
+ border-bottom-color: $selected_bg_color;
}
}
diff --git a/gtk/theme/Adwaita/gtk-contained-dark.css b/gtk/theme/Adwaita/gtk-contained-dark.css
index 73badab..8fddd67 100644
--- a/gtk/theme/Adwaita/gtk-contained-dark.css
+++ b/gtk/theme/Adwaita/gtk-contained-dark.css
@@ -1841,15 +1841,16 @@ headerbar {
path-bar .button.flat {
background-image: none;
border-radius: 0px;
- border-color: transparent;
+ border-top-color: transparent;
+ border-width: 2px 0px 2px 0px;
box-shadow: 0px 0px 0px;
margin: 0px;
opacity: 0.55;
padding: 3px 8px 4px; }
path-bar .button.flat:hover {
- box-shadow: 0px 2px 0px #5986b5; }
+ border-bottom-color: #5986b5; }
path-bar .button.flat:checked {
- box-shadow: 0px 2px 0px #215d9c; }
+ border-bottom-color: #215d9c; }
/**************
* Tree Views *
diff --git a/gtk/theme/Adwaita/gtk-contained.css b/gtk/theme/Adwaita/gtk-contained.css
index 113c1ad..6a478b3 100644
--- a/gtk/theme/Adwaita/gtk-contained.css
+++ b/gtk/theme/Adwaita/gtk-contained.css
@@ -1841,15 +1841,16 @@ headerbar {
path-bar .button.flat {
background-image: none;
border-radius: 0px;
- border-color: transparent;
+ border-top-color: transparent;
+ border-width: 2px 0px 2px 0px;
box-shadow: 0px 0px 0px;
margin: 0px;
opacity: 0.55;
padding: 3px 8px 4px; }
path-bar .button.flat:hover {
- box-shadow: 0px 2px 0px #77ace3; }
+ border-bottom-color: #77ace3; }
path-bar .button.flat:checked {
- box-shadow: 0px 2px 0px #4a90d9; }
+ border-bottom-color: #4a90d9; }
/**************
* Tree Views *
diff --git a/gtk/ui/gtkpathbar.ui b/gtk/ui/gtkpathbar.ui
index ae3fa18..0520809 100644
--- a/gtk/ui/gtkpathbar.ui
+++ b/gtk/ui/gtkpathbar.ui
@@ -4,12 +4,12 @@
<property name="visible">true</property>
<property name="orientation">horizontal</property>
<property name="vexpand">false</property>
- <property name="hexpand">true</property>
<property name="valign">GTK_ALIGN_START</property>
<child>
<object class="GtkButton" id="overflow_button">
<property name="visible">true</property>
<property name="no-show-all">true</property>
+ <signal name="clicked" handler="popup_overflow_menu" object="GtkPathBar" swapped="yes"/>
<child>
<object class="GtkImage">
<property name="visible">true</property>
@@ -18,7 +18,7 @@
</object>
</child>
<style>
- <class name="image-button"/>
+ <class name="flat"/>
</style>
</object>
</child>
diff --git a/tests/testpathbar.c b/tests/testpathbar.c
index 88d80cf..ac1cadd 100644
--- a/tests/testpathbar.c
+++ b/tests/testpathbar.c
@@ -13,7 +13,7 @@ main (int argc, char *argv[])
"type", GTK_WINDOW_TOPLEVEL,
"title", "Test path bar",
"resizable", TRUE,
- "border_width", 10,
+ "default-height", 200,
NULL),
"signal::destroy", gtk_main_quit, NULL,
NULL);
@@ -21,7 +21,7 @@ main (int argc, char *argv[])
g_type_ensure (GTK_TYPE_PATH_BAR);
path_bar = gtk_path_bar_new ();
gtk_container_add (GTK_CONTAINER (window), path_bar);
- gtk_path_bar_set_path (path_bar, "/test/test 2/pppppppppp/asda lkasdl/// alskd/");
+ gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), "/test/test 2/pppppppppp/asda lkasdl/// alskd/");
gtk_widget_show_all (window);
gtk_main ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]