summaryrefslogtreecommitdiff
path: root/gtk/gtktextview.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2000-11-20 23:51:51 +0000
committerHavoc Pennington <hp@src.gnome.org>2000-11-20 23:51:51 +0000
commit6f7dd53b801d21692744ac3c445307391225686d (patch)
tree2457a929ff4aa529ed84d55b5e61e316f042202c /gtk/gtktextview.c
parent2999f465b4db274a9d2301c7d3653d134bd79adb (diff)
downloadgtk+-6f7dd53b801d21692744ac3c445307391225686d.tar.gz
Semi-finish widget embedding. Need guffaw scrolling to be implemented in
2000-11-20 Havoc Pennington <hp@redhat.com> * gtk/gtktextview.c, gtk/gtktextlayout.c, gtk/gtktextchild.c, gtk/testtext.c: Semi-finish widget embedding. Need guffaw scrolling to be implemented in GDK to finish. Also, right now we just size_allocate all children on every layout change, which is pretty lame. Test commented out of testtext.c, until it works better.
Diffstat (limited to 'gtk/gtktextview.c')
-rw-r--r--gtk/gtktextview.c141
1 files changed, 130 insertions, 11 deletions
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 19185a2d2d..46bee56780 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -244,6 +244,9 @@ struct _GtkTextViewChild
GtkTextChildAnchor *anchor;
+ gint from_top_of_line;
+ gint from_left_of_buffer;
+
/* These are ignored if anchor != NULL */
GtkTextWindowType type;
gint x;
@@ -1613,9 +1616,12 @@ static void
gtk_text_view_destroy (GtkObject *object)
{
GtkTextView *text_view;
-
+ GtkTextLayout *layout;
+
text_view = GTK_TEXT_VIEW (object);
+ layout = text_view->layout;
+
gtk_text_view_destroy_layout (text_view);
gtk_text_view_set_buffer (text_view, NULL);
@@ -1835,11 +1841,62 @@ gtk_text_view_size_request (GtkWidget *widget,
}
static void
-gtk_text_view_allocate_children (GtkTextView *text_view)
+gtk_text_view_update_child_allocation (GtkTextView *text_view,
+ GtkTextViewChild *vc)
{
- GSList *tmp_list;
+ gint buffer_y;
+ GtkTextIter iter;
+ GtkAllocation allocation;
+
+ gtk_text_buffer_get_iter_at_child_anchor (get_buffer (text_view),
+ &iter,
+ vc->anchor);
+
+ gtk_text_layout_get_line_yrange (text_view->layout, &iter,
+ &buffer_y, NULL);
+
+ buffer_y += vc->from_top_of_line;
+
+ allocation.x = vc->from_left_of_buffer;
+ allocation.y = buffer_y;
+ allocation.width = vc->widget->requisition.width;
+ allocation.height = vc->widget->requisition.height;
+
+ gtk_widget_size_allocate (vc->widget, &allocation);
+}
- return;
+static void
+gtk_text_view_child_allocated (GtkTextLayout *layout,
+ GtkWidget *child,
+ gint x,
+ gint y,
+ gpointer data)
+{
+ GtkTextViewChild *vc = NULL;
+ GtkTextView *text_view = data;
+
+ /* x,y is the position of the child from the top of the line, and
+ * from the left of the buffer. We have to translate that into text
+ * window coordinates, then size_allocate the child.
+ */
+
+ vc = gtk_object_get_data (GTK_OBJECT (child),
+ "gtk-text-view-child");
+
+ g_assert (vc != NULL);
+
+ printf ("child allocated at %d,%d\n", x, y);
+
+ vc->from_left_of_buffer = x;
+ vc->from_top_of_line = y;
+
+ gtk_text_view_update_child_allocation (text_view, vc);
+}
+
+static void
+gtk_text_view_validate_children (GtkTextView *text_view)
+{
+ GSList *tmp_list;
tmp_list = text_view->children;
while (tmp_list != NULL)
@@ -1982,7 +2039,7 @@ gtk_text_view_size_allocate (GtkWidget *widget,
gtk_text_layout_set_screen_width (text_view->layout,
SCREEN_WIDTH (text_view));
- gtk_text_view_allocate_children (text_view);
+ gtk_text_view_validate_children (text_view);
gtk_text_view_validate_onscreen (text_view);
gtk_text_view_scroll_calc_now (text_view);
@@ -2146,7 +2203,8 @@ changed_handler (GtkTextLayout *layout,
if (old_height != new_height)
{
gboolean yoffset_changed = FALSE;
-
+ GSList *tmp_list;
+
if (start_y + old_height <= text_view->yoffset - text_view->first_para_pixels)
{
text_view->yoffset += new_height - old_height;
@@ -2156,6 +2214,19 @@ changed_handler (GtkTextLayout *layout,
if (yoffset_changed)
gtk_adjustment_value_changed (get_vadjustment (text_view));
+
+ /* FIXME be smarter about which anchored widgets we update */
+
+ tmp_list = text_view->children;
+ while (tmp_list != NULL)
+ {
+ GtkTextViewChild *child = tmp_list->data;
+
+ if (child->anchor)
+ gtk_text_view_update_child_allocation (text_view, child);
+
+ tmp_list = g_slist_next (tmp_list);
+ }
}
gtk_text_view_scroll_calc_now (text_view);
@@ -2167,7 +2238,8 @@ gtk_text_view_realize (GtkWidget *widget)
GtkTextView *text_view;
GdkWindowAttr attributes;
gint attributes_mask;
-
+ GSList *tmp_list;
+
text_view = GTK_TEXT_VIEW (widget);
GTK_WIDGET_SET_FLAGS (text_view, GTK_REALIZED);
@@ -2218,7 +2290,8 @@ static void
gtk_text_view_unrealize (GtkWidget *widget)
{
GtkTextView *text_view;
-
+ GSList *tmp_list;
+
text_view = GTK_TEXT_VIEW (widget);
if (text_view->first_validate_idle)
@@ -2254,7 +2327,7 @@ gtk_text_view_unrealize (GtkWidget *widget)
text_window_unrealize (text_view->bottom_window);
gtk_text_view_destroy_layout (text_view);
-
+
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
}
@@ -3685,7 +3758,8 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
{
GtkTextAttributes *style;
PangoContext *ltr_context, *rtl_context;
-
+ GSList *tmp_list;
+
text_view->layout = gtk_text_layout_new ();
gtk_signal_connect (GTK_OBJECT (text_view->layout),
@@ -3698,6 +3772,11 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
GTK_SIGNAL_FUNC (changed_handler),
text_view);
+ gtk_signal_connect (GTK_OBJECT (text_view->layout),
+ "allocate_child",
+ GTK_SIGNAL_FUNC (gtk_text_view_child_allocated),
+ text_view);
+
if (get_buffer (text_view))
gtk_text_layout_set_buffer (text_view->layout, get_buffer (text_view));
@@ -3737,6 +3816,23 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
gtk_text_layout_set_default_style (text_view->layout, style);
gtk_text_attributes_unref (style);
+
+ /* Set layout for all anchored children */
+
+ tmp_list = text_view->children;
+ while (tmp_list != NULL)
+ {
+ GtkTextViewChild *vc = tmp_list->data;
+
+ if (vc->anchor)
+ {
+ gtk_text_anchored_child_set_layout (vc->widget,
+ text_view->layout);
+ /* vc may now be invalid! */
+ }
+
+ tmp_list = g_slist_next (tmp_list);
+ }
}
}
@@ -3745,6 +3841,23 @@ gtk_text_view_destroy_layout (GtkTextView *text_view)
{
if (text_view->layout)
{
+ /* Remove layout from all anchored children */
+ GSList *tmp_list;
+
+ tmp_list = text_view->children;
+ while (tmp_list != NULL)
+ {
+ GtkTextViewChild *vc = tmp_list->data;
+
+ if (vc->anchor)
+ {
+ gtk_text_anchored_child_set_layout (vc->widget, NULL);
+ /* vc may now be invalid! */
+ }
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
gtk_text_view_stop_cursor_blink (text_view);
gtk_text_view_end_selection_drag (text_view, NULL);
@@ -5178,6 +5291,9 @@ text_view_child_new_anchored (GtkWidget *child,
vc->widget = child;
vc->anchor = anchor;
+ vc->from_top_of_line = 0;
+ vc->from_left_of_buffer = 0;
+
g_object_ref (G_OBJECT (vc->widget));
g_object_ref (G_OBJECT (vc->anchor));
@@ -5186,7 +5302,7 @@ text_view_child_new_anchored (GtkWidget *child,
vc);
gtk_text_child_anchor_register_child (anchor, child, layout);
-
+
return vc;
}
@@ -5203,6 +5319,9 @@ text_view_child_new_window (GtkWidget *child,
vc->widget = child;
vc->anchor = NULL;
+ vc->from_top_of_line = 0;
+ vc->from_left_of_buffer = 0;
+
g_object_ref (G_OBJECT (vc->widget));
vc->type = type;