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:

committed by
Matthias Clasen

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>
|
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
* 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>
|
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
* 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>
|
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
* 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>
|
Sun Jul 25 19:51:17 2004 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
* gtk/gtknotebook.c (gtk_notebook_scroll): Ignore scroll
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "gtkliststore.h"
|
#include "gtkliststore.h"
|
||||||
#include "gtkmain.h"
|
#include "gtkmain.h"
|
||||||
#include "gtkmenu.h"
|
#include "gtkmenu.h"
|
||||||
|
#include "gtkscrolledwindow.h"
|
||||||
#include "gtkseparatormenuitem.h"
|
#include "gtkseparatormenuitem.h"
|
||||||
#include "gtktearoffmenuitem.h"
|
#include "gtktearoffmenuitem.h"
|
||||||
#include "gtktogglebutton.h"
|
#include "gtktogglebutton.h"
|
||||||
@ -93,12 +94,14 @@ struct _GtkComboBoxPrivate
|
|||||||
GtkWidget *popup_widget;
|
GtkWidget *popup_widget;
|
||||||
GtkWidget *popup_window;
|
GtkWidget *popup_window;
|
||||||
GtkWidget *popup_frame;
|
GtkWidget *popup_frame;
|
||||||
|
GtkWidget *scrolled_window;
|
||||||
|
|
||||||
guint inserted_id;
|
guint inserted_id;
|
||||||
guint deleted_id;
|
guint deleted_id;
|
||||||
guint reordered_id;
|
guint reordered_id;
|
||||||
guint changed_id;
|
guint changed_id;
|
||||||
guint popup_idle_id;
|
guint popup_idle_id;
|
||||||
|
guint scroll_timer;
|
||||||
|
|
||||||
gint width;
|
gint width;
|
||||||
GSList *cells;
|
GSList *cells;
|
||||||
@ -109,6 +112,7 @@ struct _GtkComboBoxPrivate
|
|||||||
guint has_frame : 1;
|
guint has_frame : 1;
|
||||||
guint is_cell_renderer : 1;
|
guint is_cell_renderer : 1;
|
||||||
guint editing_canceled : 1;
|
guint editing_canceled : 1;
|
||||||
|
guint auto_scroll : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* While debugging this evil code, I have learned that
|
/* While debugging this evil code, I have learned that
|
||||||
@ -126,6 +130,7 @@ struct _GtkComboBoxPrivate
|
|||||||
* popup_widget -> GtkMenu
|
* popup_widget -> GtkMenu
|
||||||
* popup_window -> NULL
|
* popup_window -> NULL
|
||||||
* popup_frame -> NULL
|
* popup_frame -> NULL
|
||||||
|
* scrolled_window -> NULL
|
||||||
*
|
*
|
||||||
* 2) menu mode, child added
|
* 2) menu mode, child added
|
||||||
*
|
*
|
||||||
@ -138,6 +143,7 @@ struct _GtkComboBoxPrivate
|
|||||||
* popup_widget -> GtkMenu
|
* popup_widget -> GtkMenu
|
||||||
* popup_window -> NULL
|
* popup_window -> NULL
|
||||||
* popup_frame -> NULL
|
* popup_frame -> NULL
|
||||||
|
* scrolled_window -> NULL
|
||||||
*
|
*
|
||||||
* 3) list mode, no child added
|
* 3) list mode, no child added
|
||||||
*
|
*
|
||||||
@ -150,6 +156,7 @@ struct _GtkComboBoxPrivate
|
|||||||
* popup_widget -> tree_view
|
* popup_widget -> tree_view
|
||||||
* popup_window -> GtkWindow
|
* popup_window -> GtkWindow
|
||||||
* popup_frame -> GtkFrame, child of popup_window
|
* popup_frame -> GtkFrame, child of popup_window
|
||||||
|
* scrolled_window -> GtkScrolledWindow, child of popup_frame
|
||||||
*
|
*
|
||||||
* 4) list mode, child added
|
* 4) list mode, child added
|
||||||
*
|
*
|
||||||
@ -162,6 +169,7 @@ struct _GtkComboBoxPrivate
|
|||||||
* popup_widget -> tree_view
|
* popup_widget -> tree_view
|
||||||
* popup_window -> GtkWindow
|
* popup_window -> GtkWindow
|
||||||
* popup_frame -> GtkFrame, child of popup_window
|
* 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,};
|
static guint combo_box_signals[LAST_SIGNAL] = {0,};
|
||||||
|
|
||||||
#define BONUS_PADDING 4
|
#define BONUS_PADDING 4
|
||||||
|
#define SCROLL_TIME 100
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
static void gtk_combo_box_class_init (GtkComboBoxClass *klass);
|
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,
|
static gboolean gtk_combo_box_list_key_press (GtkWidget *widget,
|
||||||
GdkEventKey *event,
|
GdkEventKey *event,
|
||||||
gpointer data);
|
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,
|
static gboolean gtk_combo_box_list_button_pressed (GtkWidget *widget,
|
||||||
GdkEventButton *event,
|
GdkEventButton *event,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
@ -1015,10 +1030,24 @@ gtk_combo_box_set_popup_widget (GtkComboBox *combo_box,
|
|||||||
combo_box->priv->popup_frame);
|
combo_box->priv->popup_frame);
|
||||||
|
|
||||||
gtk_widget_show (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);
|
popup);
|
||||||
|
|
||||||
gtk_widget_show (popup);
|
gtk_widget_show (popup);
|
||||||
g_object_ref (G_OBJECT (popup));
|
g_object_ref (G_OBJECT (popup));
|
||||||
combo_box->priv->popup_widget = popup;
|
combo_box->priv->popup_widget = popup;
|
||||||
@ -1191,15 +1220,20 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
|
|||||||
gint monitor_num;
|
gint monitor_num;
|
||||||
GdkRectangle monitor;
|
GdkRectangle monitor;
|
||||||
GtkRequisition popup_req;
|
GtkRequisition popup_req;
|
||||||
|
GtkPolicyType hpolicy, vpolicy;
|
||||||
|
|
||||||
sample = GTK_BIN (combo_box)->child;
|
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);
|
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)
|
if (combo_box->priv->cell_view_frame && combo_box->priv->has_frame)
|
||||||
{
|
{
|
||||||
*x -= GTK_CONTAINER (combo_box->priv->cell_view_frame)->border_width +
|
*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);
|
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;
|
hpolicy = GTK_POLICY_ALWAYS;
|
||||||
*y += sample->allocation.y;
|
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));
|
screen = gtk_widget_get_screen (GTK_WIDGET (combo_box));
|
||||||
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
monitor_num = gdk_screen_get_monitor_at_window (screen,
|
||||||
GTK_WIDGET (combo_box)->window);
|
GTK_WIDGET (combo_box)->window);
|
||||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||||
|
|
||||||
if (*x < monitor.x)
|
if (*x < monitor.x)
|
||||||
*x = monitor.x;
|
*x = monitor.x;
|
||||||
else if (*x + *width > monitor.x + monitor.width)
|
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)
|
if (*y + sample->allocation.height + *height <= monitor.y + monitor.height)
|
||||||
*y += sample->allocation.height;
|
*y += sample->allocation.height;
|
||||||
else
|
else if (*y - *height >= monitor.y)
|
||||||
*y -= *height;
|
*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
|
static gboolean
|
||||||
@ -1428,7 +1489,7 @@ gtk_combo_box_popup (GtkComboBox *combo_box)
|
|||||||
gtk_widget_show_all (combo_box->priv->popup_frame);
|
gtk_widget_show_all (combo_box->priv->popup_frame);
|
||||||
gtk_combo_box_list_position (combo_box, &x, &y, &width, &height);
|
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);
|
gtk_window_move (GTK_WINDOW (combo_box->priv->popup_window), x, y);
|
||||||
|
|
||||||
/* popup */
|
/* popup */
|
||||||
@ -1451,8 +1512,6 @@ gtk_combo_box_popup (GtkComboBox *combo_box)
|
|||||||
GDK_BUTTON_RELEASE_MASK |
|
GDK_BUTTON_RELEASE_MASK |
|
||||||
GDK_POINTER_MOTION_MASK,
|
GDK_POINTER_MOTION_MASK,
|
||||||
NULL, NULL, GDK_CURRENT_TIME);
|
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;
|
GtkTreeIter iter;
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
gint padding = 0;
|
|
||||||
|
|
||||||
if (!combo_box->priv->model ||
|
if (!combo_box->priv->model ||
|
||||||
!gtk_tree_model_get_iter_first (combo_box->priv->model, &iter))
|
!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);
|
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
|
do
|
||||||
{
|
{
|
||||||
GtkRequisition req;
|
GtkRequisition req;
|
||||||
@ -1548,8 +1596,7 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box)
|
|||||||
else
|
else
|
||||||
req.width = 0;
|
req.width = 0;
|
||||||
|
|
||||||
combo_box->priv->width = MAX (combo_box->priv->width,
|
combo_box->priv->width = MAX (combo_box->priv->width, req.width);
|
||||||
req.width + padding);
|
|
||||||
|
|
||||||
gtk_tree_path_next (path);
|
gtk_tree_path_next (path);
|
||||||
}
|
}
|
||||||
@ -1626,6 +1673,8 @@ gtk_combo_box_size_request (GtkWidget *widget,
|
|||||||
/* sample + frame */
|
/* sample + frame */
|
||||||
*requisition = bin_req;
|
*requisition = bin_req;
|
||||||
|
|
||||||
|
requisition->width += 2 * focus_width;
|
||||||
|
|
||||||
if (combo_box->priv->cell_view_frame)
|
if (combo_box->priv->cell_view_frame)
|
||||||
{
|
{
|
||||||
gtk_widget_size_request (combo_box->priv->cell_view_frame, &frame_req);
|
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));
|
gtk_widget_show (GTK_WIDGET (cell_view));
|
||||||
|
|
||||||
tmp = gtk_menu_item_new ();
|
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_signal_connect (tmp, "activate",
|
||||||
G_CALLBACK (gtk_combo_box_menu_item_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),
|
gtk_tree_view_set_model (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||||
combo_box->priv->model);
|
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 ();
|
combo_box->priv->column = gtk_tree_view_column_new ();
|
||||||
gtk_tree_view_append_column (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
gtk_tree_view_append_column (GTK_TREE_VIEW (combo_box->priv->tree_view),
|
||||||
combo_box->priv->column);
|
combo_box->priv->column);
|
||||||
@ -2653,6 +2692,19 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box)
|
|||||||
/* set sample/popup widgets */
|
/* set sample/popup widgets */
|
||||||
gtk_combo_box_set_popup_widget (combo_box, combo_box->priv->tree_view);
|
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);
|
gtk_widget_show (combo_box->priv->tree_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2668,6 +2720,16 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
|||||||
0, 0, NULL,
|
0, 0, NULL,
|
||||||
gtk_combo_box_list_button_pressed,
|
gtk_combo_box_list_button_pressed,
|
||||||
NULL);
|
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)
|
if (combo_box->priv->box)
|
||||||
g_signal_handlers_disconnect_matched (combo_box->priv->box,
|
g_signal_handlers_disconnect_matched (combo_box->priv->box,
|
||||||
G_SIGNAL_MATCH_DATA,
|
G_SIGNAL_MATCH_DATA,
|
||||||
@ -2696,6 +2758,12 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
|||||||
combo_box->priv->box = NULL;
|
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);
|
gtk_widget_destroy (combo_box->priv->tree_view);
|
||||||
|
|
||||||
combo_box->priv->tree_view = NULL;
|
combo_box->priv->tree_view = NULL;
|
||||||
@ -2706,12 +2774,6 @@ gtk_combo_box_list_destroy (GtkComboBox *combo_box)
|
|||||||
static void
|
static void
|
||||||
gtk_combo_box_list_remove_grabs (GtkComboBox *combo_box)
|
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 &&
|
if (combo_box->priv->popup_window &&
|
||||||
GTK_WIDGET_HAS_GRAB (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);
|
GtkWidget *ewidget = gtk_get_event_widget ((GdkEvent *)event);
|
||||||
|
|
||||||
if (ewidget == combo_box->priv->tree_view)
|
if (ewidget == combo_box->priv->popup_window)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if ((ewidget != combo_box->priv->button && ewidget != combo_box->priv->box) ||
|
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),
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (combo_box->priv->button),
|
||||||
TRUE);
|
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;
|
combo_box->priv->popup_in_progress = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -2767,6 +2835,12 @@ gtk_combo_box_list_button_released (GtkWidget *widget,
|
|||||||
combo_box->priv->popup_in_progress = FALSE;
|
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->tree_view)
|
||||||
{
|
{
|
||||||
if (ewidget == combo_box->priv->button &&
|
if (ewidget == combo_box->priv->button &&
|
||||||
@ -2789,7 +2863,7 @@ gtk_combo_box_list_button_released (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* select something cool */
|
/* 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,
|
event->x, event->y,
|
||||||
&path,
|
&path,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
@ -2944,6 +3018,84 @@ gtk_combo_box_list_key_press (GtkWidget *widget,
|
|||||||
return FALSE;
|
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
|
static void
|
||||||
gtk_combo_box_list_row_changed (GtkTreeModel *model,
|
gtk_combo_box_list_row_changed (GtkTreeModel *model,
|
||||||
GtkTreePath *path,
|
GtkTreePath *path,
|
||||||
|
Reference in New Issue
Block a user