diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 18 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 18 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 18 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 18 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 18 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 18 | ||||
-rw-r--r-- | docs/reference/gtk/tmpl/gtkmenu.sgml | 6 | ||||
-rw-r--r-- | gtk/gtktextview.c | 85 | ||||
-rw-r--r-- | tests/testtext.c | 160 |
10 files changed, 359 insertions, 18 deletions
@@ -1,3 +1,21 @@ +2001-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextview.c (gtk_text_view_size_request): add border width + to requisition, request non-anchored children + (gtk_text_view_size_allocate): handle border width, allocate + non-anchored children + (text_view_child_new_window): set the child as object data + (gtk_text_view_move_child): allow children at negative + coordinates, no reason why not + (gtk_text_view_forall): make it copy the list of children before + walking it, to avoid reentrancy issues + (gtk_text_view_move_child): short-circuit if position is unchanged + (changed_handler): only queue_resize if requisition has changed + (gtk_text_view_init): don't redraw_on_allocate, since we can do + a better job of invalidation ourselves + + * tests/testtext.c: add tests for the fixed-position children + Tue Nov 13 19:51:43 2001 Tim Janik <timj@gtk.org> * gtk/gtkwindow.c (handle_accels_changed): protect idle handle diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index f9b16a881e..d6d4973582 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,21 @@ +2001-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextview.c (gtk_text_view_size_request): add border width + to requisition, request non-anchored children + (gtk_text_view_size_allocate): handle border width, allocate + non-anchored children + (text_view_child_new_window): set the child as object data + (gtk_text_view_move_child): allow children at negative + coordinates, no reason why not + (gtk_text_view_forall): make it copy the list of children before + walking it, to avoid reentrancy issues + (gtk_text_view_move_child): short-circuit if position is unchanged + (changed_handler): only queue_resize if requisition has changed + (gtk_text_view_init): don't redraw_on_allocate, since we can do + a better job of invalidation ourselves + + * tests/testtext.c: add tests for the fixed-position children + Tue Nov 13 19:51:43 2001 Tim Janik <timj@gtk.org> * gtk/gtkwindow.c (handle_accels_changed): protect idle handle diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index f9b16a881e..d6d4973582 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,21 @@ +2001-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextview.c (gtk_text_view_size_request): add border width + to requisition, request non-anchored children + (gtk_text_view_size_allocate): handle border width, allocate + non-anchored children + (text_view_child_new_window): set the child as object data + (gtk_text_view_move_child): allow children at negative + coordinates, no reason why not + (gtk_text_view_forall): make it copy the list of children before + walking it, to avoid reentrancy issues + (gtk_text_view_move_child): short-circuit if position is unchanged + (changed_handler): only queue_resize if requisition has changed + (gtk_text_view_init): don't redraw_on_allocate, since we can do + a better job of invalidation ourselves + + * tests/testtext.c: add tests for the fixed-position children + Tue Nov 13 19:51:43 2001 Tim Janik <timj@gtk.org> * gtk/gtkwindow.c (handle_accels_changed): protect idle handle diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index f9b16a881e..d6d4973582 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,21 @@ +2001-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextview.c (gtk_text_view_size_request): add border width + to requisition, request non-anchored children + (gtk_text_view_size_allocate): handle border width, allocate + non-anchored children + (text_view_child_new_window): set the child as object data + (gtk_text_view_move_child): allow children at negative + coordinates, no reason why not + (gtk_text_view_forall): make it copy the list of children before + walking it, to avoid reentrancy issues + (gtk_text_view_move_child): short-circuit if position is unchanged + (changed_handler): only queue_resize if requisition has changed + (gtk_text_view_init): don't redraw_on_allocate, since we can do + a better job of invalidation ourselves + + * tests/testtext.c: add tests for the fixed-position children + Tue Nov 13 19:51:43 2001 Tim Janik <timj@gtk.org> * gtk/gtkwindow.c (handle_accels_changed): protect idle handle diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index f9b16a881e..d6d4973582 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,21 @@ +2001-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextview.c (gtk_text_view_size_request): add border width + to requisition, request non-anchored children + (gtk_text_view_size_allocate): handle border width, allocate + non-anchored children + (text_view_child_new_window): set the child as object data + (gtk_text_view_move_child): allow children at negative + coordinates, no reason why not + (gtk_text_view_forall): make it copy the list of children before + walking it, to avoid reentrancy issues + (gtk_text_view_move_child): short-circuit if position is unchanged + (changed_handler): only queue_resize if requisition has changed + (gtk_text_view_init): don't redraw_on_allocate, since we can do + a better job of invalidation ourselves + + * tests/testtext.c: add tests for the fixed-position children + Tue Nov 13 19:51:43 2001 Tim Janik <timj@gtk.org> * gtk/gtkwindow.c (handle_accels_changed): protect idle handle diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index f9b16a881e..d6d4973582 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,21 @@ +2001-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextview.c (gtk_text_view_size_request): add border width + to requisition, request non-anchored children + (gtk_text_view_size_allocate): handle border width, allocate + non-anchored children + (text_view_child_new_window): set the child as object data + (gtk_text_view_move_child): allow children at negative + coordinates, no reason why not + (gtk_text_view_forall): make it copy the list of children before + walking it, to avoid reentrancy issues + (gtk_text_view_move_child): short-circuit if position is unchanged + (changed_handler): only queue_resize if requisition has changed + (gtk_text_view_init): don't redraw_on_allocate, since we can do + a better job of invalidation ourselves + + * tests/testtext.c: add tests for the fixed-position children + Tue Nov 13 19:51:43 2001 Tim Janik <timj@gtk.org> * gtk/gtkwindow.c (handle_accels_changed): protect idle handle diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index f9b16a881e..d6d4973582 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,21 @@ +2001-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextview.c (gtk_text_view_size_request): add border width + to requisition, request non-anchored children + (gtk_text_view_size_allocate): handle border width, allocate + non-anchored children + (text_view_child_new_window): set the child as object data + (gtk_text_view_move_child): allow children at negative + coordinates, no reason why not + (gtk_text_view_forall): make it copy the list of children before + walking it, to avoid reentrancy issues + (gtk_text_view_move_child): short-circuit if position is unchanged + (changed_handler): only queue_resize if requisition has changed + (gtk_text_view_init): don't redraw_on_allocate, since we can do + a better job of invalidation ourselves + + * tests/testtext.c: add tests for the fixed-position children + Tue Nov 13 19:51:43 2001 Tim Janik <timj@gtk.org> * gtk/gtkwindow.c (handle_accels_changed): protect idle handle diff --git a/docs/reference/gtk/tmpl/gtkmenu.sgml b/docs/reference/gtk/tmpl/gtkmenu.sgml index eb37062f02..16c0e66f96 100644 --- a/docs/reference/gtk/tmpl/gtkmenu.sgml +++ b/docs/reference/gtk/tmpl/gtkmenu.sgml @@ -96,9 +96,9 @@ Creates a new #GtkMenu. Adds a new #GtkMenuItem to the end of the menu's item list. </para> +<!-- # Unused Parameters # --> @menu: a #GtkMenu. @child: The #GtkMenuItem to add. -<!-- # Unused Parameters # --> @m: @c: @@ -108,9 +108,9 @@ Adds a new #GtkMenuItem to the end of the menu's item list. Adds a new #GtkMenuItem to the beginning of the menu's item list. </para> +<!-- # Unused Parameters # --> @menu: a #GtkMenu. @child: The #GtkMenuItem to add. -<!-- # Unused Parameters # --> @menu_child: @m: @c: @@ -122,10 +122,10 @@ Adds a new #GtkMenuItem to the menu's item list at the position indicated by @position. </para> +<!-- # Unused Parameters # --> @menu: a #GtkMenu. @child: The #GtkMenuItem to add. @pos: -<!-- # Unused Parameters # --> @position: The position in the item list where @child is added. Positions are numbered from 0 to n-1. diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 464fc50df9..95834e9fae 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -978,6 +978,9 @@ gtk_text_view_init (GtkTextView *text_view) text_view->drag_start_y = -1; text_view->pending_place_cursor_button = 0; + + /* We handle all our own redrawing */ + gtk_widget_set_redraw_on_allocate (widget, FALSE); } /** @@ -2408,6 +2411,9 @@ gtk_text_view_size_request (GtkWidget *widget, if (text_view->bottom_window) requisition->height += text_view->bottom_window->requisition.height; + requisition->width += GTK_CONTAINER (text_view)->border_width * 2; + requisition->height += GTK_CONTAINER (text_view)->border_width * 2; + tmp_list = text_view->children; while (tmp_list != NULL) { @@ -2433,7 +2439,9 @@ gtk_text_view_size_request (GtkWidget *widget, } else { - + GtkRequisition child_req; + + gtk_widget_size_request (child->widget, &child_req); } tmp_list = g_slist_next (tmp_list); @@ -2514,7 +2522,7 @@ gtk_text_view_child_allocated (GtkTextLayout *layout, } static void -gtk_text_view_validate_children (GtkTextView *text_view) +gtk_text_view_allocate_children (GtkTextView *text_view) { GSList *tmp_list; @@ -2541,7 +2549,20 @@ gtk_text_view_validate_children (GtkTextView *text_view) } else { + GtkAllocation allocation; + GtkRequisition child_req; + + g_assert (child != NULL); + + allocation.x = child->x; + allocation.y = child->y; + gtk_widget_get_child_requisition (child->widget, &child_req); + + allocation.width = child_req.width; + allocation.height = child_req.height; + + gtk_widget_size_allocate (child->widget, &allocation); } tmp_list = g_slist_next (tmp_list); @@ -2565,10 +2586,15 @@ gtk_text_view_size_allocate (GtkWidget *widget, GdkRectangle bottom_rect; gint focus_edge_width; gboolean interior_focus; + gboolean size_changed; text_view = GTK_TEXT_VIEW (widget); DV(g_print(G_STRLOC"\n")); + + size_changed = + widget->allocation.width != allocation->width || + widget->allocation.height != allocation->height; widget->allocation = *allocation; @@ -2590,7 +2616,7 @@ gtk_text_view_size_allocate (GtkWidget *widget, else focus_edge_width = 1; - width = allocation->width - focus_edge_width * 2; + width = allocation->width - focus_edge_width * 2 - GTK_CONTAINER (text_view)->border_width * 2; if (text_view->left_window) left_rect.width = text_view->left_window->requisition.width; @@ -2612,7 +2638,7 @@ gtk_text_view_size_allocate (GtkWidget *widget, bottom_rect.width = text_rect.width; - height = allocation->height - focus_edge_width * 2; + height = allocation->height - focus_edge_width * 2 - GTK_CONTAINER (text_view)->border_width * 2; if (text_view->top_window) top_rect.height = text_view->top_window->requisition.height; @@ -2634,8 +2660,8 @@ gtk_text_view_size_allocate (GtkWidget *widget, right_rect.height = text_rect.height; /* Origins */ - left_rect.x = focus_edge_width; - top_rect.y = focus_edge_width; + left_rect.x = focus_edge_width + GTK_CONTAINER (text_view)->border_width; + top_rect.y = focus_edge_width + GTK_CONTAINER (text_view)->border_width; text_rect.x = left_rect.x + left_rect.width; text_rect.y = top_rect.y + top_rect.height; @@ -2670,8 +2696,8 @@ gtk_text_view_size_allocate (GtkWidget *widget, gtk_text_view_update_layout_width (text_view); - /* This is because validating children ends up size allocating them. */ - gtk_text_view_validate_children (text_view); + /* Note that this will do some layout validation */ + gtk_text_view_allocate_children (text_view); /* Now adjust the value of the adjustment to keep the cursor at the * same place in the buffer @@ -2725,6 +2751,12 @@ gtk_text_view_size_allocate (GtkWidget *widget, if (!gtk_text_view_flush_scroll (text_view)) gtk_text_view_validate_onscreen (text_view); } + + /* widget->window doesn't get auto-redrawn as the layout is computed, so has to + * be invalidated + */ + if (size_changed && GTK_WIDGET_REALIZED (widget)) + gdk_window_invalidate_rect (widget->window, NULL, FALSE); } static void @@ -2989,7 +3021,17 @@ changed_handler (GtkTextLayout *layout, } } - gtk_widget_queue_resize (widget); + { + GtkRequisition old_req; + GtkRequisition new_req; + + old_req = widget->requisition; + gtk_widget_size_request (widget, &new_req); + + if (old_req.width != new_req.width || + old_req.height != new_req.height) + gtk_widget_queue_resize (widget); + } } static void @@ -3841,13 +3883,15 @@ gtk_text_view_forall (GtkContainer *container, { GSList *iter; GtkTextView *text_view; + GSList *copy; g_return_if_fail (GTK_IS_TEXT_VIEW (container)); g_return_if_fail (callback != NULL); text_view = GTK_TEXT_VIEW (container); - iter = text_view->children; + copy = g_slist_copy (text_view->children); + iter = copy; while (iter != NULL) { @@ -3857,6 +3901,8 @@ gtk_text_view_forall (GtkContainer *container, iter = g_slist_next (iter); } + + g_slist_free (copy); } #define CURSOR_ON_MULTIPLIER 0.66 @@ -6597,6 +6643,10 @@ text_view_child_new_window (GtkWidget *child, vc->x = x; vc->y = y; + g_object_set_data (G_OBJECT (child), + "gtk-text-view-child", + vc); + return vc; } @@ -6665,6 +6715,9 @@ gtk_text_view_add_child_at_anchor (GtkTextView *text_view, text_view->layout); add_child (text_view, vc); + + g_assert (vc->widget == child); + g_assert (gtk_widget_get_parent (child) == GTK_WIDGET (text_view)); } void @@ -6678,14 +6731,15 @@ gtk_text_view_add_child_in_window (GtkTextView *text_view, g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (xpos >= 0); - g_return_if_fail (ypos >= 0); g_return_if_fail (child->parent == NULL); vc = text_view_child_new_window (child, which_window, xpos, ypos); add_child (text_view, vc); + + g_assert (vc->widget == child); + g_assert (gtk_widget_get_parent (child) == GTK_WIDGET (text_view)); } void @@ -6698,8 +6752,6 @@ gtk_text_view_move_child (GtkTextView *text_view, g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); g_return_if_fail (GTK_IS_WIDGET (child)); - g_return_if_fail (xpos >= 0); - g_return_if_fail (ypos >= 0); g_return_if_fail (child->parent == (GtkWidget*) text_view); vc = g_object_get_data (G_OBJECT (child), @@ -6707,6 +6759,10 @@ gtk_text_view_move_child (GtkTextView *text_view, g_assert (vc != NULL); + if (vc->x == xpos && + vc->y == ypos) + return; + vc->x = xpos; vc->y = ypos; @@ -6715,7 +6771,6 @@ gtk_text_view_move_child (GtkTextView *text_view, } - /* Iterator operations */ gboolean diff --git a/tests/testtext.c b/tests/testtext.c index ba79fafb6a..7f6292b47f 100644 --- a/tests/testtext.c +++ b/tests/testtext.c @@ -1209,6 +1209,165 @@ do_search (gpointer callback_data, gtk_widget_show_all (dialog); } +typedef struct +{ + /* position is in coordinate system of text_view_move_child */ + int click_x; + int click_y; + int start_x; + int start_y; + int button; +} ChildMoveInfo; + +static gboolean +movable_child_callback (GtkWidget *child, + GdkEvent *event, + gpointer data) +{ + ChildMoveInfo *info; + GtkTextView *text_view; + + text_view = GTK_TEXT_VIEW (data); + + g_return_val_if_fail (GTK_IS_EVENT_BOX (child), FALSE); + g_return_val_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (text_view), FALSE); + + info = g_object_get_data (G_OBJECT (child), + "testtext-move-info"); + + if (info == NULL) + { + info = g_new (ChildMoveInfo, 1); + info->start_x = -1; + info->start_y = -1; + info->button = -1; + g_object_set_data_full (G_OBJECT (child), + "testtext-move-info", + info, + g_free); + } + + switch (event->type) + { + case GDK_BUTTON_PRESS: + if (info->button < 0) + { + if (gdk_pointer_grab (event->button.window, + FALSE, + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_RELEASE_MASK, + NULL, + NULL, + event->button.time) != GDK_GRAB_SUCCESS) + return FALSE; + + info->button = event->button.button; + + info->start_x = child->allocation.x; + info->start_y = child->allocation.y; + info->click_x = child->allocation.x + event->button.x; + info->click_y = child->allocation.y + event->button.y; + } + break; + + case GDK_BUTTON_RELEASE: + if (info->button < 0) + return FALSE; + + if (info->button == event->button.button) + { + int x, y; + + gdk_pointer_ungrab (event->button.time); + info->button = -1; + + /* convert to window coords from event box coords */ + x = info->start_x + (event->button.x + child->allocation.x - info->click_x); + y = info->start_y + (event->button.y + child->allocation.y - info->click_y); + + gtk_text_view_move_child (text_view, + child, + x, y); + } + break; + + case GDK_MOTION_NOTIFY: + { + int x, y; + + if (info->button < 0) + return FALSE; + + gdk_window_get_pointer (child->window, &x, &y, NULL); /* ensure more events */ + + /* to window coords from event box coords */ + x += child->allocation.x; + y += child->allocation.y; + + x = info->start_x + (x - info->click_x); + y = info->start_y + (y - info->click_y); + + gtk_text_view_move_child (text_view, + child, + x, y); + } + break; + + default: + break; + } + + return FALSE; +} + +static void +add_movable_child (GtkTextView *text_view, + GtkTextWindowType window) +{ + GtkWidget *event_box; + GtkWidget *label; + GdkColor color; + + label = gtk_label_new ("Drag me around"); + + event_box = gtk_event_box_new (); + gtk_widget_add_events (event_box, + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); + + color.red = 0xffff; + color.green = color.blue = 0; + gtk_widget_modify_bg (event_box, GTK_STATE_NORMAL, &color); + + gtk_container_add (GTK_CONTAINER (event_box), label); + + gtk_widget_show_all (event_box); + + g_signal_connect (G_OBJECT (event_box), "event", + G_CALLBACK (movable_child_callback), + text_view); + + gtk_text_view_add_child_in_window (text_view, + event_box, + window, + 0, 0); +} + +static void +do_add_children (gpointer callback_data, + guint callback_action, + GtkWidget *widget) +{ + View *view = view_from_widget (widget); + + add_movable_child (GTK_TEXT_VIEW (view->text_view), + GTK_TEXT_WINDOW_WIDGET); + add_movable_child (GTK_TEXT_VIEW (view->text_view), + GTK_TEXT_WINDOW_LEFT); + add_movable_child (GTK_TEXT_VIEW (view->text_view), + GTK_TEXT_WINDOW_RIGHT); +} + static void view_init_menus (View *view) { @@ -1301,6 +1460,7 @@ static GtkItemFactoryEntry menu_items[] = { "/_Test", NULL, 0, 0, "<Branch>" }, { "/Test/_Example", NULL, do_example, 0, NULL }, { "/Test/_Insert and scroll", NULL, do_insert_and_scroll, 0, NULL }, + { "/Test/_Add fixed children", NULL, do_add_children, 0, NULL }, }; static gboolean |