2 * GNT - The GLib Ncurses Toolkit
4 * GNT is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 #include "gntcombobox.h"
26 #include "gntmarshal.h"
33 SIG_SELECTION_CHANGED
,
37 static GntWidgetClass
*parent_class
= NULL
;
38 static guint signals
[SIGS
] = { 0 };
39 static void (*widget_lost_focus
)(GntWidget
*widget
);
42 set_selection(GntComboBox
*box
, gpointer key
)
44 if (box
->selected
!= key
)
46 /* XXX: make sure the key actually does exist */
47 gpointer old
= box
->selected
;
49 if (GNT_WIDGET(box
)->window
)
50 gnt_widget_draw(GNT_WIDGET(box
));
52 gnt_tree_set_selected(GNT_TREE(box
->dropdown
), key
);
53 g_signal_emit(box
, signals
[SIG_SELECTION_CHANGED
], 0, old
, key
);
58 hide_popup(GntComboBox
*box
, gboolean set
)
60 gnt_widget_set_size(box
->dropdown
,
61 box
->dropdown
->priv
.width
- 1, box
->dropdown
->priv
.height
);
63 set_selection(box
, gnt_tree_get_selection_data(GNT_TREE(box
->dropdown
)));
65 gnt_tree_set_selected(GNT_TREE(box
->dropdown
), box
->selected
);
66 gnt_widget_hide(box
->dropdown
->parent
);
70 gnt_combo_box_draw(GntWidget
*widget
)
72 GntComboBox
*box
= GNT_COMBO_BOX(widget
);
73 char *text
= NULL
, *s
;
77 if (box
->dropdown
&& box
->selected
)
78 text
= gnt_tree_get_selection_text(GNT_TREE(box
->dropdown
));
83 if (gnt_widget_has_focus(widget
))
84 type
= GNT_COLOR_HIGHLIGHT
;
86 type
= GNT_COLOR_NORMAL
;
88 wbkgdset(widget
->window
, '\0' | gnt_color_pair(type
));
90 s
= (char*)gnt_util_onscreen_width_to_pointer(text
, widget
->priv
.width
- 4, &len
);
93 mvwaddstr(widget
->window
, 1, 1, text
);
94 whline(widget
->window
, ' ' | gnt_color_pair(type
), widget
->priv
.width
- 4 - len
);
95 mvwaddch(widget
->window
, 1, widget
->priv
.width
- 3, ACS_VLINE
| gnt_color_pair(GNT_COLOR_NORMAL
));
96 mvwaddch(widget
->window
, 1, widget
->priv
.width
- 2, ACS_DARROW
| gnt_color_pair(GNT_COLOR_NORMAL
));
103 gnt_combo_box_size_request(GntWidget
*widget
)
105 if (!GNT_WIDGET_IS_FLAG_SET(widget
, GNT_WIDGET_MAPPED
))
107 GntWidget
*dd
= GNT_COMBO_BOX(widget
)->dropdown
;
108 gnt_widget_size_request(dd
);
109 widget
->priv
.height
= 3; /* For now, a combobox will have border */
110 widget
->priv
.width
= MAX(10, dd
->priv
.width
+ 2);
115 gnt_combo_box_map(GntWidget
*widget
)
117 if (widget
->priv
.width
== 0 || widget
->priv
.height
== 0)
118 gnt_widget_size_request(widget
);
123 popup_dropdown(GntComboBox
*box
)
125 GntWidget
*widget
= GNT_WIDGET(box
);
126 GntWidget
*parent
= box
->dropdown
->parent
;
127 int height
= g_list_length(GNT_TREE(box
->dropdown
)->list
);
128 int y
= widget
->priv
.y
+ widget
->priv
.height
- 1;
129 gnt_widget_set_size(box
->dropdown
, widget
->priv
.width
, height
+ 2);
131 if (y
+ height
+ 2 >= getmaxy(stdscr
))
132 y
= widget
->priv
.y
- height
- 1;
133 gnt_widget_set_position(parent
, widget
->priv
.x
, y
);
136 mvwin(parent
->window
, y
, widget
->priv
.x
);
137 wresize(parent
->window
, height
+2, widget
->priv
.width
);
139 parent
->priv
.width
= widget
->priv
.width
;
140 parent
->priv
.height
= height
+ 2;
142 GNT_WIDGET_UNSET_FLAGS(parent
, GNT_WIDGET_INVISIBLE
);
143 gnt_widget_draw(parent
);
147 gnt_combo_box_key_pressed(GntWidget
*widget
, const char *text
)
149 GntComboBox
*box
= GNT_COMBO_BOX(widget
);
150 if (GNT_WIDGET_IS_FLAG_SET(box
->dropdown
->parent
, GNT_WIDGET_MAPPED
))
159 hide_popup(box
, TRUE
);
162 hide_popup(box
, FALSE
);
166 if (gnt_widget_key_pressed(box
->dropdown
, text
))
173 if (strcmp(text
, GNT_KEY_UP
) == 0 ||
174 strcmp(text
, GNT_KEY_DOWN
) == 0)
186 gnt_combo_box_destroy(GntWidget
*widget
)
188 gnt_widget_destroy(GNT_COMBO_BOX(widget
)->dropdown
->parent
);
192 gnt_combo_box_lost_focus(GntWidget
*widget
)
194 GntComboBox
*combo
= GNT_COMBO_BOX(widget
);
195 if (GNT_WIDGET_IS_FLAG_SET(combo
->dropdown
->parent
, GNT_WIDGET_MAPPED
))
196 hide_popup(combo
, FALSE
);
197 widget_lost_focus(widget
);
201 gnt_combo_box_clicked(GntWidget
*widget
, GntMouseEvent event
, int x
, int y
)
203 GntComboBox
*box
= GNT_COMBO_BOX(widget
);
204 gboolean dshowing
= GNT_WIDGET_IS_FLAG_SET(box
->dropdown
->parent
, GNT_WIDGET_MAPPED
);
206 if (event
== GNT_MOUSE_SCROLL_UP
) {
208 gnt_widget_key_pressed(box
->dropdown
, GNT_KEY_UP
);
209 } else if (event
== GNT_MOUSE_SCROLL_DOWN
) {
211 gnt_widget_key_pressed(box
->dropdown
, GNT_KEY_DOWN
);
212 } else if (event
== GNT_LEFT_MOUSE_DOWN
) {
214 hide_popup(box
, TRUE
);
216 popup_dropdown(GNT_COMBO_BOX(widget
));
224 gnt_combo_box_size_changed(GntWidget
*widget
, int oldw
, int oldh
)
226 GntComboBox
*box
= GNT_COMBO_BOX(widget
);
227 gnt_widget_set_size(box
->dropdown
, widget
->priv
.width
- 1, box
->dropdown
->priv
.height
);
231 gnt_combo_box_class_init(GntComboBoxClass
*klass
)
233 parent_class
= GNT_WIDGET_CLASS(klass
);
235 parent_class
->destroy
= gnt_combo_box_destroy
;
236 parent_class
->draw
= gnt_combo_box_draw
;
237 parent_class
->map
= gnt_combo_box_map
;
238 parent_class
->size_request
= gnt_combo_box_size_request
;
239 parent_class
->key_pressed
= gnt_combo_box_key_pressed
;
240 parent_class
->clicked
= gnt_combo_box_clicked
;
241 parent_class
->size_changed
= gnt_combo_box_size_changed
;
243 widget_lost_focus
= parent_class
->lost_focus
;
244 parent_class
->lost_focus
= gnt_combo_box_lost_focus
;
246 signals
[SIG_SELECTION_CHANGED
] =
247 g_signal_new("selection-changed",
248 G_TYPE_FROM_CLASS(klass
),
252 gnt_closure_marshal_VOID__POINTER_POINTER
,
253 G_TYPE_NONE
, 2, G_TYPE_POINTER
, G_TYPE_POINTER
);
259 gnt_combo_box_init(GTypeInstance
*instance
, gpointer
class)
262 GntWidget
*widget
= GNT_WIDGET(instance
);
263 GntComboBox
*combo
= GNT_COMBO_BOX(instance
);
265 GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance
),
266 GNT_WIDGET_GROW_X
| GNT_WIDGET_CAN_TAKE_FOCUS
| GNT_WIDGET_NO_SHADOW
);
267 combo
->dropdown
= gnt_tree_new();
269 box
= gnt_box_new(FALSE
, FALSE
);
270 GNT_WIDGET_SET_FLAGS(box
, GNT_WIDGET_NO_SHADOW
| GNT_WIDGET_NO_BORDER
| GNT_WIDGET_TRANSIENT
);
271 gnt_box_set_pad(GNT_BOX(box
), 0);
272 gnt_box_add_widget(GNT_BOX(box
), combo
->dropdown
);
274 widget
->priv
.minw
= 4;
275 widget
->priv
.minh
= 3;
279 /******************************************************************************
281 *****************************************************************************/
283 gnt_combo_box_get_gtype(void)
285 static GType type
= 0;
289 static const GTypeInfo info
= {
290 sizeof(GntComboBoxClass
),
291 NULL
, /* base_init */
292 NULL
, /* base_finalize */
293 (GClassInitFunc
)gnt_combo_box_class_init
,
294 NULL
, /* class_finalize */
295 NULL
, /* class_data */
298 gnt_combo_box_init
, /* instance_init */
299 NULL
/* value_table */
302 type
= g_type_register_static(GNT_TYPE_WIDGET
,
310 GntWidget
*gnt_combo_box_new()
312 GntWidget
*widget
= g_object_new(GNT_TYPE_COMBO_BOX
, NULL
);
317 void gnt_combo_box_add_data(GntComboBox
*box
, gpointer key
, const char *text
)
319 gnt_tree_add_row_last(GNT_TREE(box
->dropdown
), key
,
320 gnt_tree_create_row(GNT_TREE(box
->dropdown
), text
), NULL
);
321 if (box
->selected
== NULL
)
322 set_selection(box
, key
);
325 gpointer
gnt_combo_box_get_selected_data(GntComboBox
*box
)
327 return box
->selected
;
330 void gnt_combo_box_set_selected(GntComboBox
*box
, gpointer key
)
332 set_selection(box
, key
);
335 void gnt_combo_box_remove(GntComboBox
*box
, gpointer key
)
337 gnt_tree_remove(GNT_TREE(box
->dropdown
), key
);
338 if (box
->selected
== key
)
339 set_selection(box
, NULL
);
342 void gnt_combo_box_remove_all(GntComboBox
*box
)
344 gnt_tree_remove_all(GNT_TREE(box
->dropdown
));
345 set_selection(box
, NULL
);