Commit da485b05 authored by Jon K Hellan's avatar Jon K Hellan Committed by Jon Kåre Hellan

Add titles for torn off combos.

2000-03-29  Jon K Hellan  <hellan@acm.org>

	* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
	Add titles for torn off combos.

	* src/workbook.c (workbook_create_standard_toobar): Ditto

2000-03-29  Jon K Hellan  <hellan@acm.org>

	* src/widgets/gtk-combo-box.h (gtk_combo_box_set_title): Declare

	* src/widgets/gtk-combo-box.c (struct _GtkComboBoxPrivate):
	New/renamed members: toplevel, tearoff_window: Popup's
	toplevel when torn_off/not torn off. torn_off: Tearoff status
	flag. Names are the same as in gtk/gtkmenu.c. tearable: The tearoff
	"button". popup: The widget which gets torn off. This is actually
	the event box.
	(gtk_combo_box_finalize): Destroy tearoff window.
	(gtk_combo_box_popup_hide): Turned into a wrapper which does
	nothing if popup is torn off, and calls
	gtk_combo_box_popup_hide_unconditional if it isn't.
	(gtk_combo_box_popup_hide_unconditional): Contains the logic which
	used to be in gtk_combo_box_popup_hide. If torn off, the popup is
	reattached after hiding.
	(gtk_combo_box_popup_display): Realize popup as well as toplevel.
	(gtk_combo_toggle_pressed): Use
	gtk_combo_box_popup_hide_unconditional.
	(gtk_combo_box_key_press): New function. Dismiss popup on escape.
	(gtk_combo_box_init): Various renamings. Connect key press handler.
	(gtk_combo_get_parent_toplevel):
	(gtk_combo_popup_tear_off): New function. Tear off the popup.
	(cb_tearable_button_release): Toggle tearoff state.
	(gtk_combo_box_construct): Make tearoff menu item no fill, no
	expand.
	(gtk_combo_box_set_title): New function. Set a title to display
	over the tearoff window.
parent 648605fa
2000-03-29 Jon K Hellan <hellan@acm.org>
* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
Add titles for torn off combos.
* src/workbook.c (workbook_create_standard_toobar): Ditto
2000-03-28 Jon K Hellan <hellan@acm.org>
* src/xml-io.c (xml_arg_get): Really silence warnings.
......
2000-03-29 Jon K Hellan <hellan@acm.org>
* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
Add titles for torn off combos.
* src/workbook.c (workbook_create_standard_toobar): Ditto
2000-03-28 Jon K Hellan <hellan@acm.org>
* src/xml-io.c (xml_arg_get): Really silence warnings.
......
Gnumeric 0.52
Jon:
* Tearoff combo boxes
Gnumeric 0.49
Jukka:
......
2000-03-29 Jon K Hellan <hellan@acm.org>
* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
Add titles for torn off combos.
* src/workbook.c (workbook_create_standard_toobar): Ditto
2000-03-28 Jon K Hellan <hellan@acm.org>
* src/xml-io.c (xml_arg_get): Really silence warnings.
......
2000-03-29 Jon K Hellan <hellan@acm.org>
* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
Add titles for torn off combos.
* src/workbook.c (workbook_create_standard_toobar): Ditto
2000-03-28 Jon K Hellan <hellan@acm.org>
* src/xml-io.c (xml_arg_get): Really silence warnings.
......
2000-03-29 Jon K Hellan <hellan@acm.org>
* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
Add titles for torn off combos.
* src/workbook.c (workbook_create_standard_toobar): Ditto
2000-03-28 Jon K Hellan <hellan@acm.org>
* src/xml-io.c (xml_arg_get): Really silence warnings.
......
2000-03-29 Jon K Hellan <hellan@acm.org>
* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
Add titles for torn off combos.
* src/workbook.c (workbook_create_standard_toobar): Ditto
2000-03-28 Jon K Hellan <hellan@acm.org>
* src/xml-io.c (xml_arg_get): Really silence warnings.
......
2000-03-29 Jon K Hellan <hellan@acm.org>
* src/workbook-format-toolbar.c (workbook_create_format_toolbar):
Add titles for torn off combos.
* src/workbook.c (workbook_create_standard_toobar): Ditto
2000-03-28 Jon K Hellan <hellan@acm.org>
* src/xml-io.c (xml_arg_get): Really silence warnings.
......
......@@ -15,8 +15,6 @@ Description Difficulty Integration
functions to samples/regress.gnumeric so we can be
sure that we are returning the right error code.
- Finish making the new combo boxes tear-off-able Medium Low
- Save/Restore the values of the last selected colours Low Low
from the toolbar for background or font.
......
......@@ -5,7 +5,9 @@
* Miguel de Icaza (miguel@gnu.org)
* Adrian E Feiguin (feiguin@ifir.edu.ar)
* Paolo Molnaro (lupus@debian.org).
* Jon K Hellan (hellan@acm.org)
*/
#include <config.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtktogglebutton.h>
......@@ -17,11 +19,20 @@
#include <gtk/gtkframe.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtktearoffmenuitem.h>
#include <gdk/gdkkeysyms.h>
#include "gtk-combo-box.h"
static GtkHBoxClass *gtk_combo_box_parent_class;
static int gtk_combo_toggle_pressed (GtkToggleButton *tbutton,
GtkComboBox *combo_box);
static void gtk_combo_set_tearoff_state (GtkComboBox *combo,
gboolean torn_off);
static void gtk_combo_popup_reparent (GtkWidget *popup, GtkWidget *new_parent,
gboolean unrealize);
static gboolean cb_popup_delete (GtkWidget *w, GdkEventAny *event,
GtkComboBox *combo);
static void gtk_combo_tearoff_bg_copy (GtkComboBox *combo);
enum {
POP_DOWN_WIDGET,
POP_DOWN_DONE,
......@@ -38,9 +49,15 @@ struct _GtkComboBoxPrivate {
* Internal widgets used to implement the ComboBox
*/
GtkWidget *frame;
GtkWidget *popwin;
GtkWidget *arrow_button;
GtkWidget *toplevel; /* Popup's toplevel when not torn off */
GtkWidget *tearoff_window; /* Popup's toplevel when torn off */
guint torn_off;
GtkWidget *tearable; /* The tearoff "button" */
GtkWidget *popup; /* Popup */
/*
* Closure for invoking the callbacks above
*/
......@@ -52,8 +69,14 @@ gtk_combo_box_finalize (GtkObject *object)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (object);
gtk_object_destroy (GTK_OBJECT (combo_box->priv->popwin));
gtk_object_unref (GTK_OBJECT (combo_box->priv->popwin));
gtk_object_destroy (GTK_OBJECT (combo_box->priv->toplevel));
gtk_object_unref (GTK_OBJECT (combo_box->priv->toplevel));
if (combo_box->priv->tearoff_window) {
gtk_object_destroy
(GTK_OBJECT (combo_box->priv->tearoff_window));
gtk_object_unref
(GTK_OBJECT (combo_box->priv->tearoff_window)); // ??
}
g_free (combo_box->priv);
GTK_OBJECT_CLASS (gtk_combo_box_parent_class)->finalize (object);
......@@ -100,8 +123,14 @@ gtk_combo_box_class_init (GtkObjectClass *object_class)
gtk_object_class_add_signals (object_class, gtk_combo_box_signals, LAST_SIGNAL);
}
void
gtk_combo_box_popup_hide (GtkComboBox *combo_box)
/**
* gtk_combo_box_popup_hide_unconditional
* @combo_box Combo box
*
* Hide popup, whether or not it is torn off.
*/
static void
gtk_combo_box_popup_hide_unconditional (GtkComboBox *combo_box)
{
GtkWidget *arrow;
gboolean popup_info_destroyed = FALSE;
......@@ -109,11 +138,17 @@ gtk_combo_box_popup_hide (GtkComboBox *combo_box)
g_return_if_fail (combo_box != NULL);
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
gtk_widget_hide (combo_box->priv->popwin);
gtk_grab_remove (combo_box->priv->popwin);
gtk_widget_hide (combo_box->priv->toplevel);
gtk_widget_hide (combo_box->priv->popup);
if (combo_box->priv->torn_off) {
GTK_TEAROFF_MENU_ITEM (combo_box->priv->tearable)->torn_off
= FALSE;
gtk_combo_set_tearoff_state (combo_box, FALSE);
}
gtk_grab_remove (combo_box->priv->toplevel);
gdk_pointer_ungrab (GDK_CURRENT_TIME);
gtk_object_ref (GTK_OBJECT (combo_box->priv->pop_down_widget));
gtk_signal_emit (GTK_OBJECT (combo_box),
gtk_combo_box_signals [POP_DOWN_DONE],
......@@ -141,6 +176,21 @@ gtk_combo_box_popup_hide (GtkComboBox *combo_box)
}
/**
* gtk_combo_box_popup_hide
* @combo_box Combo box
*
* Hide popup, but not when it is torn off.
* This is the external interface - for subclasses and apps which expect a
* regular combo which doesn't do tearoffs.
*/
void
gtk_combo_box_popup_hide (GtkComboBox *combo_box)
{
if (!combo_box->priv->torn_off)
gtk_combo_box_popup_hide_unconditional (combo_box);
}
/*
* Find best location for displaying
*/
......@@ -154,8 +204,8 @@ gtk_combo_box_get_pos (GtkComboBox *combo_box, int *x, int *y)
*y += wcombo->allocation.height + wcombo->allocation.y;
*x += wcombo->allocation.x;
ph = combo_box->priv->popwin->allocation.height;
pw = combo_box->priv->popwin->allocation.width;
ph = combo_box->priv->popup->allocation.height;
pw = combo_box->priv->popup->allocation.width;
if ((*y + ph) > gdk_screen_height ())
*y = gdk_screen_height () - ph;
......@@ -171,7 +221,8 @@ gtk_combo_box_popup_display (GtkComboBox *combo_box)
g_return_if_fail (combo_box != NULL);
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
g_assert (!combo_box->priv->torn_off);
/*
* If we have no widget to display on the popdown,
* create it
......@@ -187,13 +238,15 @@ gtk_combo_box_popup_display (GtkComboBox *combo_box)
}
gtk_combo_box_get_pos (combo_box, &x, &y);
gtk_widget_set_uposition (combo_box->priv->popwin, x, y);
gtk_widget_realize (combo_box->priv->popwin);
gtk_widget_show (combo_box->priv->popwin);
gtk_grab_add (combo_box->priv->popwin);
gdk_pointer_grab (combo_box->priv->popwin->window, TRUE,
gtk_widget_set_uposition (combo_box->priv->toplevel, x, y);
gtk_widget_realize (combo_box->priv->popup);
gtk_widget_show (combo_box->priv->popup);
gtk_widget_realize (combo_box->priv->toplevel);
gtk_widget_show (combo_box->priv->toplevel);
gtk_grab_add (combo_box->priv->toplevel);
gdk_pointer_grab (combo_box->priv->toplevel->window, TRUE,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK,
......@@ -206,7 +259,7 @@ gtk_combo_toggle_pressed (GtkToggleButton *tbutton, GtkComboBox *combo_box)
if (tbutton->active)
gtk_combo_box_popup_display (combo_box);
else
gtk_combo_box_popup_hide (combo_box);
gtk_combo_box_popup_hide_unconditional (combo_box);
return TRUE;
}
......@@ -229,6 +282,26 @@ gtk_combo_box_button_press (GtkWidget *widget, GdkEventButton *event, GtkComboBo
return TRUE;
}
/**
* gtk_combo_box_key_press
* @widget Widget
* @event Event
* @combo_box Combo box
*
* Key press handler which dismisses popup on escape.
* Popup is dismissed whether or not popup is torn off.
*/
static gint
gtk_combo_box_key_press (GtkWidget *widget, GdkEventKey *event,
GtkComboBox *combo_box)
{
if (event->keyval == GDK_Escape) {
gtk_combo_box_popup_hide_unconditional (combo_box);
return TRUE;
} else
return FALSE;
}
static void
cb_state_change (GtkWidget *widget, GtkStateType old_state, GtkComboBox *combo_box)
{
......@@ -239,7 +312,7 @@ cb_state_change (GtkWidget *widget, GtkStateType old_state, GtkComboBox *combo_b
static void
gtk_combo_box_init (GtkComboBox *combo_box)
{
GtkWidget *arrow, *event_box;
GtkWidget *arrow;
GdkCursor *cursor;
combo_box->priv = g_new0 (GtkComboBoxPrivate, 1);
......@@ -268,27 +341,37 @@ gtk_combo_box_init (GtkComboBox *combo_box)
/*
* The pop-down container
*/
combo_box->priv->popwin = gtk_window_new (GTK_WINDOW_POPUP);
gtk_object_sink (GTK_OBJECT (combo_box->priv->popwin));
gtk_widget_ref (combo_box->priv->popwin);
gtk_window_set_policy (GTK_WINDOW (combo_box->priv->popwin), TRUE, TRUE, FALSE);
event_box = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (combo_box->priv->popwin), event_box);
gtk_widget_show (event_box);
combo_box->priv->toplevel = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_ref (combo_box->priv->toplevel);
gtk_object_sink (GTK_OBJECT (combo_box->priv->toplevel));
gtk_window_set_policy (GTK_WINDOW (combo_box->priv->toplevel),
FALSE, TRUE, FALSE);
gtk_widget_realize (event_box);
combo_box->priv->popup = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (combo_box->priv->toplevel),
combo_box->priv->popup);
gtk_widget_show (combo_box->priv->popup);
gtk_widget_realize (combo_box->priv->popup);
cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
gdk_window_set_cursor (event_box->window, cursor);
gdk_window_set_cursor (combo_box->priv->popup->window, cursor);
gdk_cursor_destroy (cursor);
combo_box->priv->torn_off = FALSE;
combo_box->priv->tearoff_window = NULL;
combo_box->priv->frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (event_box), combo_box->priv->frame);
gtk_container_add (GTK_CONTAINER (combo_box->priv->popup),
combo_box->priv->frame);
gtk_frame_set_shadow_type (GTK_FRAME (combo_box->priv->frame), GTK_SHADOW_OUT);
gtk_signal_connect (
GTK_OBJECT (combo_box->priv->popwin), "button_press_event",
GTK_OBJECT (combo_box->priv->toplevel), "button_press_event",
GTK_SIGNAL_FUNC (gtk_combo_box_button_press), combo_box);
gtk_signal_connect (
GTK_OBJECT (combo_box->priv->toplevel), "key_press_event",
GTK_SIGNAL_FUNC (gtk_combo_box_key_press), combo_box);
}
GtkType
......@@ -346,11 +429,219 @@ cb_tearable_enter_leave (GtkWidget *w, GdkEventCrossing *event, gpointer data)
gtk_widget_set_state (w, flag ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
return FALSE;
}
/**
* gtk_combo_popup_tear_off
* @combo Combo box
*
* Tear off the popup
*
* FIXME:
* Select DIALOG or TOPLEVEL via a method on GtkComboBox
* We can do this after creating:
* GTK_WINDOW (tearoff)->type = GTK_WINDOW_TOPLEVEL;
*/
static void
gtk_combo_popup_tear_off (GtkComboBox *combo)
{
int x, y;
if (!combo->priv->tearoff_window) {
GtkWidget *tearoff;
gchar *title;
tearoff = gtk_window_new (GTK_WINDOW_DIALOG);
gtk_widget_ref (tearoff);
gtk_object_sink (GTK_OBJECT (tearoff));
combo->priv->tearoff_window = tearoff;
gtk_widget_set_app_paintable (tearoff, TRUE);
gtk_signal_connect (GTK_OBJECT (tearoff), "key_press_event",
GTK_SIGNAL_FUNC (gtk_combo_box_key_press),
GTK_OBJECT (combo));
gtk_widget_realize (tearoff);
title = gtk_object_get_data (GTK_OBJECT (combo),
"gtk-combo-title");
if (title)
gdk_window_set_title (tearoff->window, title);
gtk_window_set_policy (GTK_WINDOW (tearoff),
FALSE, TRUE, FALSE);
gtk_window_set_transient_for
(GTK_WINDOW (tearoff),
GTK_WINDOW (gtk_widget_get_toplevel (combo)));
}
if (GTK_WIDGET_VISIBLE (combo->priv->popup)) {
gtk_widget_hide (combo->priv->toplevel);
gtk_grab_remove (combo->priv->toplevel);
gdk_pointer_ungrab (GDK_CURRENT_TIME);
}
gtk_combo_popup_reparent (combo->priv->popup,
combo->priv->tearoff_window, FALSE);
gtk_combo_box_get_pos (combo, &x, &y);
gtk_widget_set_uposition (combo->priv->tearoff_window, x, y);
gtk_widget_show (GTK_WIDGET (combo->priv->popup));
gtk_widget_show (combo->priv->tearoff_window);
}
/**
* gtk_combo_set_tearoff_state
* @combo_box Combo box
* @torn_off TRUE: Tear off. FALSE: Pop down and reattach
*
* Set the tearoff state of the popup
*
* Compare with gtk_menu_set_tearoff_state in gtk/gtkmenu.c
*/
static void
gtk_combo_set_tearoff_state (GtkComboBox *combo,
gboolean torn_off)
{
g_return_if_fail (combo != NULL);
g_return_if_fail (GTK_IS_COMBO_BOX (combo));
if (combo->priv->torn_off != torn_off) {
combo->priv->torn_off = torn_off;
if (combo->priv->torn_off)
gtk_combo_popup_tear_off (combo);
else {
gtk_widget_hide (combo->priv->tearoff_window);
gtk_combo_popup_reparent (combo->priv->popup,
combo->priv->toplevel,
FALSE);
}
}
}
/**
* gtk_combo_tearoff_bg_copy
* @combo_box Combo box
*
* Copy popup background to the tearoff window.
*
* Compare with gtk_menu_tearoff_bg_copy in gtk/gtkmenu.c
*/
static void
gtk_combo_tearoff_bg_copy (GtkComboBox *combo)
{
GdkPixmap *pixmap;
GdkGC *gc;
GdkGCValues gc_values;
GtkWidget *widget = combo->priv->popup;
if (combo->priv->torn_off) {
gc_values.subwindow_mode = GDK_INCLUDE_INFERIORS;
gc = gdk_gc_new_with_values (widget->window,
&gc_values, GDK_GC_SUBWINDOW);
pixmap = gdk_pixmap_new (widget->window,
widget->requisition.width,
widget->requisition.height,
-1);
gdk_draw_pixmap (pixmap, gc,
widget->window,
0, 0, 0, 0, -1, -1);
gdk_gc_unref (gc);
gtk_widget_set_usize (combo->priv->tearoff_window,
widget->requisition.width,
widget->requisition.height);
gdk_window_set_back_pixmap
(combo->priv->tearoff_window->window, pixmap, FALSE);
gdk_pixmap_unref (pixmap);
}
}
/**
* gtk_combo_popup_reparent
* @popup Popup
* @new_parent New parent
* @unrealize Unrealize popup if TRUE.
*
* Reparent the popup, taking care of the refcounting
*
* Compare with gtk_menu_reparent in gtk/gtkmenu.c
*/
static void
gtk_combo_popup_reparent (GtkWidget *popup,
GtkWidget *new_parent,
gboolean unrealize)
{
GtkObject *object = GTK_OBJECT (popup);
gboolean was_floating = GTK_OBJECT_FLOATING (object);
gtk_object_ref (object);
gtk_object_sink (object);
if (unrealize) {
gtk_object_ref (object);
gtk_container_remove (GTK_CONTAINER (popup->parent), popup);
gtk_container_add (GTK_CONTAINER (new_parent), popup);
gtk_object_unref (object);
}
else
gtk_widget_reparent (GTK_WIDGET (popup), new_parent);
gtk_widget_set_usize (new_parent, -1, -1);
if (was_floating)
GTK_OBJECT_SET_FLAGS (object, GTK_FLOATING);
else
gtk_object_unref (object);
}
/**
* cb_tearable_button_release
* @w Widget
* @event Event
* @combo Combo box
*
* Toggle tearoff state.
*/
static gboolean
cb_tearable_button_release (GtkWidget *w, GdkEventButton *event,
GtkComboBox *combo)
{
GtkTearoffMenuItem *tearable;
g_return_val_if_fail (w != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TEAROFF_MENU_ITEM (w), FALSE);
tearable = GTK_TEAROFF_MENU_ITEM (w);
tearable->torn_off = !tearable->torn_off;
if (GTK_IS_VBOX (GTK_WIDGET (w)->parent)) {
if (!combo->priv->torn_off) {
gboolean need_connect;
need_connect = (!combo->priv->torn_off &&
!combo->priv->tearoff_window);
gtk_combo_set_tearoff_state (combo,
!combo->priv->torn_off);
if (need_connect)
gtk_signal_connect
(GTK_OBJECT
(combo->priv->tearoff_window),
"delete_event",
GTK_SIGNAL_FUNC (cb_popup_delete),
combo);
} else
gtk_combo_box_popup_hide_unconditional (combo);
}
return TRUE;
}
static gboolean
cb_tearable_button_release (GtkWidget *w, GdkEventButton *event, gpointer data)
cb_popup_delete (GtkWidget *w, GdkEventAny *event, GtkComboBox *combo)
{
/* FIXME : TODO finish this */
g_warning ("Tearoff is unfinished");
gtk_combo_box_popup_hide_unconditional (combo);
return TRUE;
}
......@@ -381,9 +672,10 @@ gtk_combo_box_construct (GtkComboBox *combo_box, GtkWidget *display_widget, GtkW
GINT_TO_POINTER (FALSE));
gtk_signal_connect (GTK_OBJECT (tearable), "button-release-event",
GTK_SIGNAL_FUNC (cb_tearable_button_release),
GINT_TO_POINTER (FALSE));
gtk_box_pack_start (GTK_BOX (vbox), tearable, TRUE, TRUE, 0);
(gpointer) combo_box);
gtk_box_pack_start (GTK_BOX (vbox), tearable, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), pop_down_widget, TRUE, TRUE, 0);
combo_box->priv->tearable = tearable;
/*
* Finish setup
......@@ -415,3 +707,28 @@ gtk_combo_box_set_arrow_relief (GtkComboBox *cc, GtkReliefStyle relief)
gtk_button_set_relief (GTK_BUTTON (cc->priv->arrow_button), relief);
}
/**
* gtk_combo_box_set_title
* @combo Combo box
* @title Title
*
* Set a title to display over the tearoff window.
*
* FIXME:
*
* This should really change the title even when the popup is already torn off.
* I guess the tearoff window could attach a listener to title change or
* something. But I don't think we need the functionality, so I didn't bother
* to investigate.
*/
void
gtk_combo_box_set_title (GtkComboBox *combo,
const gchar *title)
{
g_return_if_fail (combo != NULL);
g_return_if_fail (GTK_IS_COMBO_BOX (combo));
gtk_object_set_data_full (GTK_OBJECT (combo), "gtk-combo-title",
g_strdup (title), (GtkDestroyNotify) g_free);
}
......@@ -49,6 +49,7 @@ GtkWidget *gtk_combo_box_new (GtkWidget *display_widget,
void gtk_combo_box_popup_hide (GtkComboBox *combo_box);
void gtk_combo_box_set_arrow_relief (GtkComboBox *cc, GtkReliefStyle relief);
void gtk_combo_box_set_title (GtkComboBox *combo, const gchar *title);
#ifdef __cplusplus
};
......
2000-03-29 Jon K Hellan <hellan@acm.org>
* gtk-combo-box.h (gtk_combo_box_set_title): Declare
* gtk-combo-box.c (struct _GtkComboBoxPrivate): New/renamed
members: toplevel, tearoff_window: Popup's toplevel when
torn_off/not torn off. torn_off: Tearoff status flag. Names are
the same as in gtk/gtkmenu.c. tearable: The tearoff
"button". popup: The widget which gets torn off. This is actually
the event box.
(gtk_combo_box_finalize): Destroy tearoff window.
(gtk_combo_box_popup_hide): Turned into a wrapper which does
nothing if popup is torn off, and calls
gtk_combo_box_popup_hide_unconditional if it isn't.
(gtk_combo_box_popup_hide_unconditional): Contains the logic which
used to be in gtk_combo_box_popup_hide. If torn off, the popup is
reattached after hiding.
(gtk_combo_box_popup_display): Realize popup as well as toplevel.
(gtk_combo_toggle_pressed): Use
gtk_combo_box_popup_hide_unconditional.
(gtk_combo_box_key_press): New function. Dismiss popup on escape.
(gtk_combo_box_init): Various renamings. Connect key press handler.
(gtk_combo_get_parent_toplevel):
(gtk_combo_popup_tear_off): New function. Tear off the popup.
(cb_tearable_button_release): Toggle tearoff state.
(gtk_combo_box_construct): Make tearoff menu item no fill, no
expand.
(gtk_combo_box_set_title): New function. Set a title to display
over the tearoff window.
2000-03-26 Jody Goldberg <jgoldberg@home.com>
* gtk-combo-text.c : Add a hash to be used for proper lookup of
......
......@@ -5,7 +5,9 @@
* Miguel de Icaza (miguel@gnu.org)
* Adrian E Feiguin (feiguin@ifir.edu.ar)
* Paolo Molnaro (lupus@debian.org).
* Jon K Hellan (hellan@acm.org)
*/
#include <config.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtktogglebutton.h>
......@@ -17,11 +19,20 @@
#include <gtk/gtkframe.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtktearoffmenuitem.h>
#include <gdk/gdkkeysyms.h>
#include "gtk-combo-box.h"
static GtkHBoxClass *gtk_combo_box_parent_class;
static int gtk_combo_toggle_pressed (GtkToggleButton *tbutton,
GtkComboBox *combo_box);
static void gtk_combo_set_tearoff_state (GtkComboBox *combo,
gboolean torn_off);
static void gtk_combo_popup_reparent (GtkWidget *popup, GtkWidget *new_parent,
gboolean unrealize);
static gboolean cb_popup_delete (GtkWidget *w, GdkEventAny *event,
GtkComboBox *combo);
static void gtk_combo_tearoff_bg_copy (GtkComboBox *combo);
enum {
POP_DOWN_WIDGET,
POP_DOWN_DONE,
......@@ -38,9 +49,15 @@ struct _GtkComboBoxPrivate {
* Internal widgets used to implement the ComboBox
*/
GtkWidget *frame;
GtkWidget *popwin;
GtkWidget *arrow_button;
GtkWidget *toplevel; /* Popup's toplevel when not torn off */
GtkWidget *tearoff_window; /* Popup's toplevel when torn off */
guint torn_off;
GtkWidget *tearable; /* The tearoff "button" */
GtkWidget *popup; /* Popup */
/*
* Closure for invoking the callbacks above
*/
......@@ -52,8 +69,14 @@ gtk_combo_box_finalize (GtkObject *object)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (object);
gtk_object_destroy (GTK_OBJECT (combo_box->priv->popwin));
gtk_object_unref (GTK_OBJECT (combo_box->priv->popwin));
gtk_object_destroy (GTK_OBJECT (combo_box->priv->toplevel));
gtk_object_unref (GTK_OBJECT (combo_box->priv->toplevel));
if (combo_box->priv->tearoff_window) {
gtk_object_destroy
(GTK_OBJECT (combo_box->priv->tearoff_window));
gtk_object_unref
(GTK_OBJECT (combo_box->priv->tearoff_window)); // ??
}