summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2012-12-16 16:45:17 +0100
committerBenjamin Otte <otte@redhat.com>2013-01-05 20:15:16 +0100
commit49a6d85310d1805ee43314a5eb15869f8b8aca80 (patch)
treec291db102f7e86417d131da54b7f8b7e0a401dcd
parent2f691d409725d6363382c2dd68b80a4d9aefb15e (diff)
downloadgtk+-49a6d85310d1805ee43314a5eb15869f8b8aca80.tar.gz
binlayout: Add API needed for progressbars
We need the ability to set size and position with more granularity than align and expand flags give us for things like: (1) sliders (2) progress indicators (3) panes (4) dragged actors (like the switch slider) ... and until we have a good way to do that, this should suffice.
-rw-r--r--gtk/actors/gtkbinlayout.c69
-rw-r--r--gtk/actors/gtkbinlayoutprivate.h7
2 files changed, 75 insertions, 1 deletions
diff --git a/gtk/actors/gtkbinlayout.c b/gtk/actors/gtkbinlayout.c
index 83ad858060..894391e952 100644
--- a/gtk/actors/gtkbinlayout.c
+++ b/gtk/actors/gtkbinlayout.c
@@ -110,6 +110,21 @@ gtk_bin_layout_get_preferred_size (GtkLayoutManager *manager,
*nat_size_p = nat_size;
}
+typedef struct _Alignment Alignment;
+
+struct _Alignment {
+ gfloat xalign;
+ gfloat yalign;
+ gfloat xscale;
+ gfloat yscale;
+};
+
+static const Alignment *
+get_alignment (GtkActor *actor)
+{
+ return g_object_get_data (G_OBJECT (actor), "gtk-bin-layout-alignment");
+}
+
static void
gtk_bin_layout_allocate (GtkLayoutManager *manager,
const cairo_matrix_t *transform,
@@ -124,7 +139,28 @@ gtk_bin_layout_allocate (GtkLayoutManager *manager,
child;
child = _gtk_actor_get_next_sibling (child))
{
- _gtk_actor_allocate (child, transform, width, height);
+ const Alignment *alignment = get_alignment (child);
+
+ if (alignment == NULL)
+ {
+ _gtk_actor_allocate (child, transform, width, height);
+ }
+ else
+ {
+ gfloat min, nat, child_width, child_height;
+ cairo_matrix_t child_transform;
+
+ _gtk_actor_get_preferred_size (child, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat);
+ child_width = (width - min) * alignment->xscale + min;
+ _gtk_actor_get_preferred_size (child, GTK_ORIENTATION_VERTICAL, child_width, &min, &nat);
+ child_height = (height - min) * alignment->yscale + min;
+
+ cairo_matrix_init_translate (&child_transform,
+ (width - child_width) * alignment->xalign,
+ (height - child_height) * alignment->yalign);
+ cairo_matrix_multiply (&child_transform, transform, &child_transform);
+ _gtk_actor_allocate (child, &child_transform, child_width, child_height);
+ }
}
}
@@ -161,3 +197,34 @@ _gtk_bin_layout_new (void)
{
return g_object_new (GTK_TYPE_BIN_LAYOUT, NULL);
}
+
+void
+_gtk_bin_layout_set_child_alignment (GtkBinLayout *layout,
+ GtkActor *child,
+ gfloat xalign,
+ gfloat yalign,
+ gfloat xscale,
+ gfloat yscale)
+{
+ Alignment *alignment;
+
+ g_return_if_fail (GTK_IS_BIN_LAYOUT (layout));
+ g_return_if_fail (GTK_IS_ACTOR (child));
+ g_return_if_fail (xalign >= 0.0 && xalign <= 1.0);
+ g_return_if_fail (yalign >= 0.0 && yalign <= 1.0);
+ g_return_if_fail (xscale >= 0.0 && xscale <= 1.0);
+ g_return_if_fail (yscale >= 0.0 && yscale <= 1.0);
+
+ alignment = g_new (Alignment, 1);
+ alignment->xalign = xalign;
+ alignment->yalign = yalign;
+ alignment->xscale = xscale;
+ alignment->yscale = yscale;
+
+ g_object_set_data_full (G_OBJECT (child),
+ "gtk-bin-layout-alignment",
+ alignment,
+ g_free);
+
+ _gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout));
+}
diff --git a/gtk/actors/gtkbinlayoutprivate.h b/gtk/actors/gtkbinlayoutprivate.h
index c00242373f..c11bca4c30 100644
--- a/gtk/actors/gtkbinlayoutprivate.h
+++ b/gtk/actors/gtkbinlayoutprivate.h
@@ -74,6 +74,13 @@ GType _gtk_bin_layout_get_type (void) G_GNUC_C
GtkLayoutManager * _gtk_bin_layout_new (void);
+void _gtk_bin_layout_set_child_alignment (GtkBinLayout *layout,
+ GtkActor *child,
+ gfloat xalign,
+ gfloat yalign,
+ gfloat xscale,
+ gfloat yscale);
+
G_END_DECLS