diff options
author | Tim Janik <timj@gimp.org> | 1998-03-13 17:45:16 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-03-13 17:45:16 +0000 |
commit | cc4dc8339db35bb48bed2a3059e6c8f474d551da (patch) | |
tree | 661bbd526dd5f7094a7232c2ffcd4eab5b5b8d31 /gtk/gtkcombo.c | |
parent | c57f1e318eeb549d2c1c6f5ced5a508780a6a973 (diff) | |
download | gtk+-cc4dc8339db35bb48bed2a3059e6c8f474d551da.tar.gz |
fix popup calculations (removal of FIXMEs), changes from Lars Hamann.
Fri Mar 13 18:25:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtkcombo.c: fix popup calculations (removal
of FIXMEs), changes from Lars Hamann.
Fri Mar 13 10:25:16 1998 Tim Janik <timj@gimp.org>
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: renamed gtk_widget_delete_hides to
gtk_widget_hide_on_delete at owens request, and because the
new name is much more descriptive.
Diffstat (limited to 'gtk/gtkcombo.c')
-rw-r--r-- | gtk/gtkcombo.c | 154 |
1 files changed, 135 insertions, 19 deletions
diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c index 8e22038093..bbd0acc808 100644 --- a/gtk/gtkcombo.c +++ b/gtk/gtkcombo.c @@ -32,6 +32,7 @@ #include "gtkwindow.h" #include "gdk/gdkkeysyms.h" #include "gtkcombo.h" +#include "gtkframe.h" const gchar *gtk_combo_string_key = "gtk-combo-string-value"; @@ -67,6 +68,8 @@ static gint gtk_combo_entry_key_press (GtkEntry *widget, GdkEventKey *event, GtkCombo *combo); static void gtk_combo_item_destroy (GtkObject *object); +static void gtk_combo_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); static GtkHBoxClass *parent_class = NULL; @@ -74,11 +77,15 @@ void gtk_combo_class_init (GtkComboClass * klass) { GtkObjectClass *oclass; + GtkWidgetClass *widget_class; parent_class = gtk_type_class (gtk_hbox_get_type ()); oclass = (GtkObjectClass *) klass; + widget_class = (GtkWidgetClass *) klass; oclass->destroy = gtk_combo_destroy; + + widget_class->size_allocate = gtk_combo_size_allocate; } static void @@ -223,42 +230,117 @@ gtk_combo_entry_focus_out (GtkEntry * entry, GdkEventFocus * event, GtkCombo * c static void gtk_combo_get_pos (GtkCombo * combo, gint * x, gint * y, gint * height, gint * width) { - GtkAllocation *pos = &(GTK_WIDGET (combo->entry)->allocation); - GtkRequisition req1; - GtkRequisition req3; - gint some_more = 10 + GTK_CONTAINER (combo->popup)->border_width * 2; /* FIXME: calc from border_width ... */ - - gtk_widget_size_request (combo->popup, &req1); - gtk_widget_size_request (combo->list, &req3); - - *width = pos->width; - gdk_window_get_origin (GTK_WIDGET (combo->entry)->window, x, y); - *y += pos->height; - *height = MIN (COMBO_LIST_MAX_HEIGHT, gdk_screen_height () - *y); + GtkBin *popwin; + GtkWidget *widget; + GtkScrolledWindow *popup; + + gint real_height; + GtkRequisition list_requisition; + gboolean show_hscroll = FALSE; + gboolean show_vscroll = FALSE; + gint avail_height; + gint min_height; + gint alloc_width; + gint work_height; + gint old_height; + gint old_width; + + widget = GTK_WIDGET(combo); + popup = GTK_SCROLLED_WINDOW (combo->popup); + popwin = GTK_BIN (combo->popwin); + + gdk_window_get_origin (combo->entry->window, x, y); + real_height = MIN (combo->entry->requisition.height, + combo->entry->allocation.height); + *y += real_height; + avail_height = gdk_screen_height () - *y; + + gtk_widget_size_request (combo->list, &list_requisition); + min_height = MIN (list_requisition.height, + popup->vscrollbar->requisition.height); + + + alloc_width = widget->allocation.width - + 2 * popwin->child->style->klass->xthickness - + 2 * GTK_CONTAINER (popwin->child)->border_width - + 2 * GTK_CONTAINER (combo->popup)->border_width - + 2 * GTK_CONTAINER (popup->viewport)->border_width - + 2 * popup->viewport->style->klass->xthickness; + + work_height = + 2 * popwin->child->style->klass->ythickness + + 2 * GTK_CONTAINER (popwin->child)->border_width + + 2 * GTK_CONTAINER (combo->popup)->border_width + + 2 * GTK_CONTAINER (popup->viewport)->border_width + + 2 * popup->viewport->style->klass->xthickness; + + do + { + old_width = alloc_width; + old_height = work_height; - if (some_more + req3.width > *width) - some_more += 11 + 2 * 2; /* FIXME: get from the scrollbar and scrollbar_spacing */ - if (some_more + req3.height < *height) - *height = some_more + req3.height; + if (!show_hscroll && + alloc_width < list_requisition.width) + { + work_height += popup->hscrollbar->requisition.height + + GTK_SCROLLED_WINDOW_CLASS + (GTK_OBJECT (combo->popup)->klass)->scrollbar_spacing; + show_hscroll = TRUE; + } + if (!show_vscroll && + work_height + list_requisition.height > avail_height) + { + if (work_height + min_height > avail_height && + *y - real_height > avail_height) + { + *y -= (work_height +list_requisition.height + real_height); + break; + } + alloc_width -= + popup->vscrollbar->requisition.width + + GTK_SCROLLED_WINDOW_CLASS + (GTK_OBJECT (combo->popup)->klass)->scrollbar_spacing; + show_vscroll = TRUE; + } + } while (old_width != alloc_width || old_height != work_height); + *width = widget->allocation.width; + if (show_vscroll) + *height = avail_height; + else + *height = work_height + list_requisition.height; + + if (*x < 0) + *x = 0; } static void gtk_combo_popup_list (GtkButton * button, GtkCombo * combo) { gint height, width, x, y; + gint old_width, old_height; if (!GTK_LIST (combo->list)->children) return; + + old_width = combo->popwin->allocation.width; + old_height = combo->popwin->allocation.height; + gtk_combo_get_pos (combo, &x, &y, &height, &width); + /* workaround for gtk_scrolled_window_size_allocate bug */ + if (old_width != width || old_height != height) + { + gtk_widget_hide (GTK_SCROLLED_WINDOW (combo->popup)->hscrollbar); + gtk_widget_hide (GTK_SCROLLED_WINDOW (combo->popup)->vscrollbar); + } + gtk_widget_set_uposition (combo->popwin, x, y); gtk_widget_set_usize (combo->popwin, width, height); gtk_widget_realize (combo->popwin); - /* gdk_window_set_cursor (combo->popwin->window, gdk_cursor_new (GDK_TOP_LEFT_ARROW)); - */ gdk_window_resize (combo->popwin->window, width, height); gtk_widget_show (combo->popwin); + gtk_widget_grab_focus (combo->popwin); gtk_grab_add (combo->popwin); gdk_pointer_grab (combo->popwin->window, TRUE, @@ -361,6 +443,7 @@ void gtk_combo_init (GtkCombo * combo) { GtkWidget *arrow; + GtkWidget *frame; combo->case_sensitive = 0; combo->value_in_list = 0; @@ -392,12 +475,18 @@ gtk_combo_init (GtkCombo * combo) combo->popwin = gtk_window_new (GTK_WINDOW_POPUP); gtk_widget_ref (combo->popwin); gtk_window_set_policy (GTK_WINDOW (combo->popwin), 1, 1, 0); + + frame = gtk_frame_new (NULL); + gtk_container_add (GTK_CONTAINER (combo->popwin), frame); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); + gtk_widget_show (frame); + combo->popup = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (combo->popup), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); combo->list = gtk_list_new (); gtk_list_set_selection_mode(GTK_LIST(combo->list), GTK_SELECTION_BROWSE); - gtk_container_add (GTK_CONTAINER (combo->popwin), combo->popup); + gtk_container_add (GTK_CONTAINER (frame), combo->popup); gtk_container_add (GTK_CONTAINER (combo->popup), combo->list); gtk_widget_show (combo->list); gtk_widget_show (combo->popup); @@ -539,3 +628,30 @@ gtk_combo_set_item_string (GtkCombo * combo, GtkItem * item, const gchar * item_ gtk_signal_disconnect_by_data(GTK_OBJECT (item), val); } } + +static void +gtk_combo_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkCombo *combo; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_COMBO (widget)); + g_return_if_fail (allocation != NULL); + + GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); + + combo = GTK_COMBO (widget); + + if (combo->entry->allocation.height > combo->entry->requisition.height) + { + GtkAllocation button_allocation; + + button_allocation = combo->button->allocation; + button_allocation.height = combo->entry->requisition.height; + button_allocation.y = combo->entry->allocation.y + + (combo->entry->allocation.height - combo->entry->requisition.height) + / 2; + gtk_widget_size_allocate (combo->button, &button_allocation); + } +} |