forked from AuroraMiddleware/gtk
Make the GtkComboBox in list mode scroll if the list is too large to fit
Mon Jul 26 00:38:27 2004 Matthias Clasen <maclas@gmx.de> Make the GtkComboBox in list mode scroll if the list is too large to fit in the popup. (#135543) * gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Add a scrolled window to the popup in list mode. (gtk_combo_box_list_position): Calculate the height of the popup so that it fits on the screen, set the scrollbar policy of the scrolled window appropriately. (gtk_combo_box_popup): Use the height calculated by gtk_combo_box_list_position(). (gtk_combo_box_remeasure): Don't add unnecessary padding. (gtk_combo_box_size_request): But add the focus with here. (gtk_combo_box_list_setup): Connect to enter notify on the popup window to activate auto scrolling. (gtk_combo_box_list_enter_notify): Activate auto scrolling. (gtk_combo_box_list_button_pressed): Setup a timeout for auto scrolling. (gtk_combo_box_list_scroll_timeout): Timeout function for auto scrolling. (gtk_combo_box_list_auto_scroll): Scroll the list when the pointer leaves the window.
This commit is contained in:
parent
7ecccfdcb4
commit
9ccad0c92a
24
ChangeLog
24
ChangeLog
@ -1,3 +1,27 @@
|
||||
Mon Jul 26 00:38:27 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Make the GtkComboBox in list mode scroll if the list is too
|
||||
large to fit in the popup. (#135543)
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Add a
|
||||
scrolled window to the popup in list mode.
|
||||
(gtk_combo_box_list_position): Calculate the height of the
|
||||
popup so that it fits on the screen, set the scrollbar policy
|
||||
of the scrolled window appropriately.
|
||||
(gtk_combo_box_popup): Use the height calculated by
|
||||
gtk_combo_box_list_position().
|
||||
(gtk_combo_box_remeasure): Don't add unnecessary padding.
|
||||
(gtk_combo_box_size_request): But add the focus with here.
|
||||
(gtk_combo_box_list_setup): Connect to enter notify on the
|
||||
popup window to activate auto scrolling.
|
||||
(gtk_combo_box_list_enter_notify): Activate auto scrolling.
|
||||
(gtk_combo_box_list_button_pressed): Setup a timeout for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_scroll_timeout): Timeout function for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_auto_scroll): Scroll the list when the
|
||||
pointer leaves the window.
|
||||
|
||||
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
||||
|
@ -1,3 +1,27 @@
|
||||
Mon Jul 26 00:38:27 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Make the GtkComboBox in list mode scroll if the list is too
|
||||
large to fit in the popup. (#135543)
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Add a
|
||||
scrolled window to the popup in list mode.
|
||||
(gtk_combo_box_list_position): Calculate the height of the
|
||||
popup so that it fits on the screen, set the scrollbar policy
|
||||
of the scrolled window appropriately.
|
||||
(gtk_combo_box_popup): Use the height calculated by
|
||||
gtk_combo_box_list_position().
|
||||
(gtk_combo_box_remeasure): Don't add unnecessary padding.
|
||||
(gtk_combo_box_size_request): But add the focus with here.
|
||||
(gtk_combo_box_list_setup): Connect to enter notify on the
|
||||
popup window to activate auto scrolling.
|
||||
(gtk_combo_box_list_enter_notify): Activate auto scrolling.
|
||||
(gtk_combo_box_list_button_pressed): Setup a timeout for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_scroll_timeout): Timeout function for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_auto_scroll): Scroll the list when the
|
||||
pointer leaves the window.
|
||||
|
||||
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
||||
|
@ -1,3 +1,27 @@
|
||||
Mon Jul 26 00:38:27 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Make the GtkComboBox in list mode scroll if the list is too
|
||||
large to fit in the popup. (#135543)
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Add a
|
||||
scrolled window to the popup in list mode.
|
||||
(gtk_combo_box_list_position): Calculate the height of the
|
||||
popup so that it fits on the screen, set the scrollbar policy
|
||||
of the scrolled window appropriately.
|
||||
(gtk_combo_box_popup): Use the height calculated by
|
||||
gtk_combo_box_list_position().
|
||||
(gtk_combo_box_remeasure): Don't add unnecessary padding.
|
||||
(gtk_combo_box_size_request): But add the focus with here.
|
||||
(gtk_combo_box_list_setup): Connect to enter notify on the
|
||||
popup window to activate auto scrolling.
|
||||
(gtk_combo_box_list_enter_notify): Activate auto scrolling.
|
||||
(gtk_combo_box_list_button_pressed): Setup a timeout for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_scroll_timeout): Timeout function for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_auto_scroll): Scroll the list when the
|
||||
pointer leaves the window.
|
||||
|
||||
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
||||
|
@ -1,3 +1,27 @@
|
||||
Mon Jul 26 00:38:27 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Make the GtkComboBox in list mode scroll if the list is too
|
||||
large to fit in the popup. (#135543)
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Add a
|
||||
scrolled window to the popup in list mode.
|
||||
(gtk_combo_box_list_position): Calculate the height of the
|
||||
popup so that it fits on the screen, set the scrollbar policy
|
||||
of the scrolled window appropriately.
|
||||
(gtk_combo_box_popup): Use the height calculated by
|
||||
gtk_combo_box_list_position().
|
||||
(gtk_combo_box_remeasure): Don't add unnecessary padding.
|
||||
(gtk_combo_box_size_request): But add the focus with here.
|
||||
(gtk_combo_box_list_setup): Connect to enter notify on the
|
||||
popup window to activate auto scrolling.
|
||||
(gtk_combo_box_list_enter_notify): Activate auto scrolling.
|
||||
(gtk_combo_box_list_button_pressed): Setup a timeout for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_scroll_timeout): Timeout function for
|
||||
auto scrolling.
|
||||
(gtk_combo_box_list_auto_scroll): Scroll the list when the
|
||||
pointer leaves the window.
|
||||
|
||||
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "gtkliststore.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkmenu.h"
|
||||
#include "gtkscrolledwindow.h"
|
||||
#include "gtkseparatormenuitem.h"
|
||||
#include "gtktearoffmenuitem.h"
|
||||
#include "gtktogglebutton.h"
|
||||
@ -93,12 +94,14 @@ struct _GtkComboBoxPrivate
|
||||
GtkWidget *popup_widget;
|
||||
GtkWidget *popup_window;
|
||||
GtkWidget *popup_frame;
|
||||
GtkWidget *scrolled_window;
|
||||
|
||||
guint inserted_id;
|
||||
guint deleted_id;
|
||||
guint reordered_id;
|
||||
guint changed_id;
|
||||
guint popup_idle_id;
|
||||
guint scroll_timer;
|
||||
|
||||
gint width;
|
||||
GSList *cells;
|
||||
@ -109,6 +112,7 @@ struct _GtkComboBoxPrivate
|
||||
guint has_frame : 1;
|
||||
guint is_cell_renderer : 1;
|
||||
guint editing_canceled : 1;
|
||||
guint auto_scroll : 1;
|
||||
};
|
||||
|
||||
/* While debugging this evil code, I have learned that
|
||||
@ -126,6 +130,7 @@ struct _GtkComboBoxPrivate
|
||||
* popup_widget -> GtkMenu
|
||||
* popup_window -> NULL
|
||||
* popup_frame -> NULL
|
||||
* scrolled_window -> NULL
|
||||
*
|
||||
* 2) menu mode, child added
|
||||
*
|
||||
@ -138,6 +143,7 @@ struct _GtkComboBoxPrivate
|
||||
* popup_widget -> GtkMenu
|
||||
* popup_window -> NULL
|
||||
* popup_frame -> NULL
|
||||
* scrolled_window -> NULL
|
||||
*
|
||||
* 3) list mode, no child added
|
||||
*
|
||||
@ -150,6 +156,7 @@ struct _GtkComboBoxPrivate
|
||||
* popup_widget -> tree_view
|
||||
* popup_window -> GtkWindow
|
||||
* popup_frame -> GtkFrame, child of popup_window
|
||||
* scrolled_window -> GtkScrolledWindow, child of popup_frame
|
||||
*
|
||||
* 4) list mode, child added
|
||||
*
|
||||
@ -162,6 +169,7 @@ struct _GtkComboBoxPrivate
|
||||
* popup_widget -> tree_view
|
||||
* popup_window -> GtkWindow
|
||||
* popup_frame -> GtkFrame, child of popup_window
|
||||
* scrolled_window -> GtkScrolledWindow, child of popup_frame
|
||||
*
|
||||
*/
|
||||
|
||||
@ -186,7 +194,7 @@ static GtkBinClass *parent_class = NULL;
|
||||
static guint combo_box_signals[LAST_SIGNAL] = {0,};
|
||||
|
||||
#define BONUS_PADDING 4
|
||||
|
||||
#define SCROLL_TIME 100
|
||||
|
||||
/* common */
|
||||
static void gtk_combo_box_class_init (GtkComboBoxClass *klass);
|
||||
@ -303,6 +311,13 @@ static gboolean gtk_combo_box_list_button_released (GtkWidget *widget,
|
||||
static gboolean gtk_combo_box_list_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer data);
|
||||
static gboolean gtk_combo_box_list_enter_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *event,
|
||||
gpointer data);
|
||||
static void gtk_combo_box_list_auto_scroll (GtkComboBox *combo,
|
||||
gint x,
|
||||
gint y);
|
||||
static gboolean gtk_combo_box_list_scroll_timeout (GtkComboBox *combo);
|
||||
static gboolean gtk_combo_box_list_button_pressed (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer data);
|
||||
@ -1015,10 +1030,24 @@ gtk_combo_box_set_popup_widget (GtkComboBox *combo_box,
|
||||
combo_box->priv->popup_frame);
|
||||
|
||||
gtk_widget_show (combo_box->priv->popup_frame);
|
||||
|
||||
combo_box->priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (combo_box->priv->scrolled_window),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_NEVER);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (combo_box->priv->scrolled_window),
|
||||
GTK_SHADOW_NONE);
|
||||
|
||||
gtk_widget_show (combo_box->priv->scrolled_window);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (combo_box->priv->popup_frame),
|
||||
combo_box->priv->scrolled_window);
|
||||
}
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (combo_box->priv->popup_frame),
|
||||
gtk_container_add (GTK_CONTAINER (combo_box->priv->scrolled_window),
|
||||
popup);
|
||||
|
||||
gtk_widget_show (popup);
|
||||
g_object_ref (G_OBJECT (popup));
|
||||
combo_box->priv->popup_widget = popup;
|
||||
@ -1191,15 +1220,20 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
|
||||
gint monitor_num;
|
||||
GdkRectangle monitor;
|
||||
GtkRequisition popup_req;
|
||||
GtkPolicyType hpolicy, vpolicy;
|
||||
|
||||
sample = GTK_BIN (combo_box)->child;
|
||||
|
||||
*width = sample->allocation.width;
|
||||
gtk_widget_size_request (combo_box->priv->popup_window, &popup_req);
|
||||
*height = popup_req.height;
|
||||
|
||||
gdk_window_get_origin (sample->window, x, y);
|
||||
|
||||
if (GTK_WIDGET_NO_WINDOW (sample))
|
||||
{
|
||||
*x += sample->allocation.x;
|
||||
*y += sample->allocation.y;
|
||||
}
|
||||
|
||||
*width = sample->allocation.width;
|
||||
|
||||
if (combo_box->priv->cell_view_frame && combo_box->priv->has_frame)
|
||||
{
|
||||
*x -= GTK_CONTAINER (combo_box->priv->cell_view_frame)->border_width +
|
||||
@ -1208,17 +1242,26 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
|
||||
GTK_WIDGET (combo_box->priv->cell_view_frame)->style->xthickness);
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_NO_WINDOW (sample))
|
||||
hpolicy = vpolicy = GTK_POLICY_NEVER;
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (combo_box->priv->scrolled_window),
|
||||
hpolicy, vpolicy);
|
||||
gtk_widget_size_request (combo_box->priv->popup_frame, &popup_req);
|
||||
|
||||
if (popup_req.width > *width)
|
||||
{
|
||||
*x += sample->allocation.x;
|
||||
*y += sample->allocation.y;
|
||||
hpolicy = GTK_POLICY_ALWAYS;
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (combo_box->priv->scrolled_window),
|
||||
hpolicy, vpolicy);
|
||||
gtk_widget_size_request (combo_box->priv->popup_frame, &popup_req);
|
||||
}
|
||||
|
||||
|
||||
*height = popup_req.height;
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (combo_box));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||
GTK_WIDGET (combo_box)->window);
|
||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||
|
||||
|
||||
if (*x < monitor.x)
|
||||
*x = monitor.x;
|
||||
else if (*x + *width > monitor.x + monitor.width)
|
||||
@ -1226,8 +1269,26 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
|
||||
|
||||
if (*y + sample->allocation.height + *height <= monitor.y + monitor.height)
|
||||
*y += sample->allocation.height;
|
||||
else
|
||||
else if (*y - *height >= monitor.y)
|
||||
*y -= *height;
|
||||
else if (monitor.y + monitor.height - (*y + sample->allocation.height) > *y - monitor.y)
|
||||
{
|
||||
*y += sample->allocation.height;
|
||||
*height = monitor.y + monitor.height - *y;
|
||||
}
|
||||
else
|
||||
{
|
||||
*height = *y - monitor.y;
|
||||
*y = monitor.y;
|
||||
}
|
||||
|
||||
if (popup_req.height > *height)
|
||||
{
|
||||
vpolicy = GTK_POLICY_ALWAYS;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (combo_box->priv->scrolled_window),
|
||||
hpolicy, vpolicy);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1428,7 +1489,7 @@ gtk_combo_box_popup (GtkComboBox *combo_box)
|
||||
gtk_widget_show_all (combo_box->priv->popup_frame);
|
||||
gtk_combo_box_list_position (combo_box, &x, &y, &width, &height);
|
||||
|
||||
gtk_widget_set_size_request (combo_box->priv->popup_window, width, -1);
|
||||
gtk_widget_set_size_request (combo_box->priv->popup_window, width, height);
|
||||
gtk_window_move (GTK_WINDOW (combo_box->priv->popup_window), x, y);
|
||||
|
||||
/* popup */
|
||||
@ -1451,8 +1512,6 @@ gtk_combo_box_popup (GtkComboBox *combo_box)
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK,
|
||||
NULL, NULL, GDK_CURRENT_TIME);
|
||||
|
||||
gtk_grab_add (combo_box->priv->tree_view);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1518,7 +1577,6 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
gint padding = 0;
|
||||
|
||||
if (!combo_box->priv->model ||
|
||||
!gtk_tree_model_get_iter_first (combo_box->priv->model, &iter))
|
||||
@ -1528,16 +1586,6 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box)
|
||||
|
||||
path = gtk_tree_path_new_from_indices (0, -1);
|
||||
|
||||
if (combo_box->priv->cell_view)
|
||||
gtk_widget_style_get (combo_box->priv->cell_view,
|
||||
"focus-line-width", &padding,
|
||||
NULL);
|
||||
else
|
||||
padding = 0;
|
||||
|
||||
/* add some pixels for good measure */
|
||||
padding += BONUS_PADDING;
|
||||
|
||||
do
|
||||
{
|
||||
GtkRequisition req;
|
||||
@ -1548,8 +1596,7 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box)
|
||||
else
|
||||
req.width = 0;
|
||||
|
||||
combo_box->priv->width = MAX (combo_box->priv->width,
|
||||
req.width + padding);
|
||||
combo_box->priv->width = MAX (combo_box->priv->width, req.width);
|
||||
|
||||
gtk_tree_path_next (path);
|
||||
}
|
||||
@ -1626,6 +1673,8 @@ gtk_combo_box_size_request (GtkWidget *widget,
|
||||
/* sample + frame */
|
||||
*requisition = bin_req;
|
||||
|
||||
requisition->width += 2 * focus_width;
|
||||
|
||||
if (combo_box->priv->cell_view_frame)
|
||||
{
|
||||
gtk_widget_size_request (combo_box->priv->cell_view_frame, &frame_req);
|
||||
@ -2066,7 +2115,7 @@ gtk_combo_box_menu_fill (GtkComboBox *combo_box)
|
||||
gtk_widget_show (GTK_WIDGET (cell_view));
|
||||
|
||||
tmp = gtk_menu_item_new ();
|
||||
gtk_container_add (GTK_CONTAINER (tmp), cell_view);
|
||||
gtk_container_add (GTK_CONTAINER (tmp), GTK_WIDGET (cell_view));
|
||||
|
||||
g_signal_connect (tmp, "activate",
|
||||
G_CALLBACK (gtk_combo_box_menu_item_activate),
|
||||
@ -2597,16 +2646,6 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box)
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||
combo_box->priv->model);
|
||||
|
||||
g_signal_connect (combo_box->priv->tree_view, "button_press_event",
|
||||
G_CALLBACK (gtk_combo_box_list_button_pressed),
|
||||
combo_box);
|
||||
g_signal_connect (combo_box->priv->tree_view, "button_release_event",
|
||||
G_CALLBACK (gtk_combo_box_list_button_released),
|
||||
combo_box);
|
||||
g_signal_connect (combo_box->priv->tree_view, "key_press_event",
|
||||
G_CALLBACK (gtk_combo_box_list_key_press),
|
||||
combo_box);
|
||||
|
||||
combo_box->priv->column = gtk_tree_view_column_new ();
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||
combo_box->priv->column);
|
||||
@ -2653,6 +2692,19 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box)
|
||||
/* set sample/popup widgets */
|
||||
gtk_combo_box_set_popup_widget (combo_box, combo_box->priv->tree_view);
|
||||
|
||||
g_signal_connect (combo_box->priv->tree_view, "key_press_event",
|
||||
G_CALLBACK (gtk_combo_box_list_key_press),
|
||||
combo_box);
|
||||
g_signal_connect (combo_box->priv->tree_view, "enter_notify_event",
|
||||
G_CALLBACK (gtk_combo_box_list_enter_notify),
|
||||
combo_box);
|
||||
g_signal_connect (combo_box->priv->popup_window, "button_press_event",
|
||||
G_CALLBACK (gtk_combo_box_list_button_pressed),
|
||||
combo_box);
|
||||
g_signal_connect (combo_box->priv->popup_window, "button_release_event",
|
||||
G_CALLBACK (gtk_combo_box_list_button_released),
|
||||
combo_box);
|
||||
|
||||
gtk_widget_show (combo_box->priv->tree_view);
|
||||
}
|
||||
|
||||
@ -2668,6 +2720,16 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
||||
0, 0, NULL,
|
||||
gtk_combo_box_list_button_pressed,
|
||||
NULL);
|
||||
g_signal_handlers_disconnect_matched (combo_box->priv->popup_window,
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
0, 0, NULL,
|
||||
gtk_combo_box_list_button_pressed,
|
||||
NULL);
|
||||
g_signal_handlers_disconnect_matched (combo_box->priv->popup_window,
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
0, 0, NULL,
|
||||
gtk_combo_box_list_button_released,
|
||||
NULL);
|
||||
if (combo_box->priv->box)
|
||||
g_signal_handlers_disconnect_matched (combo_box->priv->box,
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
@ -2696,6 +2758,12 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
||||
combo_box->priv->box = NULL;
|
||||
}
|
||||
|
||||
if (combo_box->priv->scroll_timer)
|
||||
{
|
||||
g_source_remove (combo_box->priv->scroll_timer);
|
||||
combo_box->priv->scroll_timer = 0;
|
||||
}
|
||||
|
||||
gtk_widget_destroy (combo_box->priv->tree_view);
|
||||
|
||||
combo_box->priv->tree_view = NULL;
|
||||
@ -2706,12 +2774,6 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
||||
static void
|
||||
gtk_combo_box_list_remove_grabs (GtkComboBox *combo_box)
|
||||
{
|
||||
if (combo_box->priv->tree_view &&
|
||||
GTK_WIDGET_HAS_GRAB (combo_box->priv->tree_view))
|
||||
{
|
||||
gtk_grab_remove (combo_box->priv->tree_view);
|
||||
}
|
||||
|
||||
if (combo_box->priv->popup_window &&
|
||||
GTK_WIDGET_HAS_GRAB (combo_box->priv->popup_window))
|
||||
{
|
||||
@ -2730,7 +2792,7 @@ gtk_combo_box_list_button_pressed (GtkWidget *widget,
|
||||
|
||||
GtkWidget *ewidget = gtk_get_event_widget ((GdkEvent *)event);
|
||||
|
||||
if (ewidget == combo_box->priv->tree_view)
|
||||
if (ewidget == combo_box->priv->popup_window)
|
||||
return TRUE;
|
||||
|
||||
if ((ewidget != combo_box->priv->button && ewidget != combo_box->priv->box) ||
|
||||
@ -2742,6 +2804,12 @@ gtk_combo_box_list_button_pressed (GtkWidget *widget,
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (combo_box->priv->button),
|
||||
TRUE);
|
||||
|
||||
combo_box->priv->auto_scroll = FALSE;
|
||||
if (combo_box->priv->scroll_timer == 0)
|
||||
combo_box->priv->scroll_timer = g_timeout_add (SCROLL_TIME,
|
||||
(GSourceFunc) gtk_combo_box_list_scroll_timeout,
|
||||
combo_box);
|
||||
|
||||
combo_box->priv->popup_in_progress = TRUE;
|
||||
|
||||
return TRUE;
|
||||
@ -2767,6 +2835,12 @@ gtk_combo_box_list_button_released (GtkWidget *widget,
|
||||
combo_box->priv->popup_in_progress = FALSE;
|
||||
}
|
||||
|
||||
if (combo_box->priv->scroll_timer)
|
||||
{
|
||||
g_source_remove (combo_box->priv->scroll_timer);
|
||||
combo_box->priv->scroll_timer = 0;
|
||||
}
|
||||
|
||||
if (ewidget != combo_box->priv->tree_view)
|
||||
{
|
||||
if (ewidget == combo_box->priv->button &&
|
||||
@ -2789,7 +2863,7 @@ gtk_combo_box_list_button_released (GtkWidget *widget,
|
||||
}
|
||||
|
||||
/* select something cool */
|
||||
ret = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
|
||||
ret = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||
event->x, event->y,
|
||||
&path,
|
||||
NULL, NULL, NULL);
|
||||
@ -2944,6 +3018,84 @@ gtk_combo_box_list_key_press (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_combo_box_list_auto_scroll (GtkComboBox *combo_box,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GtkWidget *tree_view = combo_box->priv->tree_view;
|
||||
GtkAdjustment *adj;
|
||||
gdouble value;
|
||||
|
||||
adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (combo_box->priv->scrolled_window));
|
||||
if (adj && adj->upper - adj->lower > adj->page_size)
|
||||
{
|
||||
if (x <= tree_view->allocation.x &&
|
||||
adj->lower < adj->value)
|
||||
{
|
||||
value = adj->value - (tree_view->allocation.x - x + 1);
|
||||
gtk_adjustment_set_value (adj, CLAMP (value, adj->lower, adj->upper - adj->page_size));
|
||||
}
|
||||
else if (x >= tree_view->allocation.x + tree_view->allocation.width &&
|
||||
adj->upper - adj->page_size > adj->value)
|
||||
{
|
||||
value = adj->value + (x - tree_view->allocation.x - tree_view->allocation.width + 1);
|
||||
gtk_adjustment_set_value (adj, CLAMP (value, 0.0, adj->upper - adj->page_size));
|
||||
}
|
||||
}
|
||||
|
||||
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (combo_box->priv->scrolled_window));
|
||||
if (adj && adj->upper - adj->lower > adj->page_size)
|
||||
{
|
||||
if (y <= tree_view->allocation.y &&
|
||||
adj->lower < adj->value)
|
||||
{
|
||||
value = adj->value - (tree_view->allocation.y - y + 1);
|
||||
gtk_adjustment_set_value (adj, CLAMP (value, adj->lower, adj->upper - adj->page_size));
|
||||
}
|
||||
else if (y >= tree_view->allocation.y + tree_view->allocation.height &&
|
||||
adj->upper - adj->page_size > adj->value)
|
||||
{
|
||||
value = adj->value + (y - tree_view->allocation.y - tree_view->allocation.height + 1);
|
||||
gtk_adjustment_set_value (adj, CLAMP (value, 0.0, adj->upper - adj->page_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_combo_box_list_scroll_timeout (GtkComboBox *combo_box)
|
||||
{
|
||||
gboolean result;
|
||||
gint x, y;
|
||||
GtkWidget *tv;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
if (combo_box->priv->auto_scroll)
|
||||
{
|
||||
gdk_window_get_pointer (combo_box->priv->tree_view->window,
|
||||
&x, &y, NULL);
|
||||
gtk_combo_box_list_auto_scroll (combo_box, x, y);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_combo_box_list_enter_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkComboBox *combo_box = GTK_COMBO_BOX (data);
|
||||
|
||||
combo_box->priv->auto_scroll = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_combo_box_list_row_changed (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
|
Loading…
Reference in New Issue
Block a user