Mercurial > pidgin
diff console/libgnt/gntcombobox.c @ 13935:cd2da4b079cf
[gaim-migrate @ 16466]
New widget GntComboBox. I have addde a test file as an example as well.
Rename gntutils.* to gntmarshal.*
I am going to have some util-functions in gntutils.* later.
committer: Tailor Script <tailor@pidgin.im>
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Sat, 08 Jul 2006 23:58:20 +0000 |
parents | |
children | 669898e6aa11 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntcombobox.c Sat Jul 08 23:58:20 2006 +0000 @@ -0,0 +1,220 @@ +#include "gntbox.h" +#include "gntcombobox.h" +#include "gnttree.h" +#include "gntmarshal.h" + +#include <string.h> + +enum +{ + SIG_SELECTION_CHANGED, + SIGS, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; +static void (*widget_lost_focus)(GntWidget *widget); + +static void +set_selection(GntComboBox *box, gpointer key) +{ + if (box->selected != key) + { + gpointer old = box->selected; + box->selected = key; + g_signal_emit(box, signals[SIG_SELECTION_CHANGED], 0, old, key); + gnt_widget_draw(GNT_WIDGET(box)); + } +} + +static void +gnt_combo_box_draw(GntWidget *widget) +{ + GntComboBox *box = GNT_COMBO_BOX(widget); + const char *text = NULL; + GntColorType type; + + if (box->dropdown) + { + text = gnt_tree_get_selection_text(GNT_TREE(box->dropdown)); + box->selected = gnt_tree_get_selection_data(GNT_TREE(box->dropdown)); + } + + if (text == NULL) + text = ""; + + if (gnt_widget_has_focus(widget)) + type = GNT_COLOR_HIGHLIGHT; + else + type = GNT_COLOR_NORMAL; + + wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); + mvwprintw(widget->window, 1, 1, text); + + DEBUG; +} + +static void +gnt_combo_box_size_request(GntWidget *widget) +{ + widget->priv.height = 3; /* For now, a combobox will have border */ + widget->priv.width = 15; +} + +static void +gnt_combo_box_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static gboolean +gnt_combo_box_key_pressed(GntWidget *widget, const char *text) +{ + GntComboBox *box = GNT_COMBO_BOX(widget); + if (GNT_WIDGET_IS_FLAG_SET(box->dropdown->parent, GNT_WIDGET_MAPPED)) + { + if (text[1] == 0) + { + switch (text[0]) + { + case '\r': + case '\t': + /* XXX: Get the selction */ + set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown))); + case 27: + gnt_widget_hide(box->dropdown->parent); + return TRUE; + break; + } + } + if (gnt_widget_key_pressed(box->dropdown, text)) + return TRUE; + } + else + { + if (text[0] == 27) + { + if (strcmp(text + 1, GNT_KEY_UP) == 0 || + strcmp(text + 1, GNT_KEY_DOWN) == 0) + { + gnt_widget_set_size(box->dropdown, widget->priv.width, 9); + gnt_widget_set_position(box->dropdown->parent, + widget->priv.x, widget->priv.y + widget->priv.height - 1); + gnt_widget_draw(box->dropdown->parent); + return TRUE; + } + } + } + + return FALSE; +} + +static void +gnt_combo_box_destroy(GntWidget *widget) +{ + gnt_widget_destroy(GNT_COMBO_BOX(widget)->dropdown->parent); +} + +static void +gnt_combo_box_lost_focus(GntWidget *widget) +{ + GntComboBox *combo = GNT_COMBO_BOX(widget); + if (GNT_WIDGET_IS_FLAG_SET(combo->dropdown->parent, GNT_WIDGET_MAPPED)) + gnt_widget_hide(GNT_COMBO_BOX(widget)->dropdown->parent); + widget_lost_focus(widget); +} + +static void +gnt_combo_box_class_init(GntComboBoxClass *klass) +{ + parent_class = GNT_WIDGET_CLASS(klass); + + parent_class->destroy = gnt_combo_box_destroy; + parent_class->draw = gnt_combo_box_draw; + parent_class->map = gnt_combo_box_map; + parent_class->size_request = gnt_combo_box_size_request; + parent_class->key_pressed = gnt_combo_box_key_pressed; + + widget_lost_focus = parent_class->lost_focus; + parent_class->lost_focus = gnt_combo_box_lost_focus; + + signals[SIG_SELECTION_CHANGED] = + g_signal_new("selection-changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + gnt_closure_marshal_VOID__POINTER_POINTER, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); + + DEBUG; +} + +static void +gnt_combo_box_init(GTypeInstance *instance, gpointer class) +{ + GntWidget *box; + GntComboBox *combo = GNT_COMBO_BOX(instance); + + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), + GNT_WIDGET_GROW_X | GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_NO_SHADOW); + combo->dropdown = gnt_tree_new(); + + box = gnt_box_new(FALSE, FALSE); + GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER); + gnt_box_add_widget(GNT_BOX(box), combo->dropdown); + + DEBUG; +} + +/****************************************************************************** + * GntComboBox API + *****************************************************************************/ +GType +gnt_combo_box_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntComboBoxClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_combo_box_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntComboBox), + 0, /* n_preallocs */ + gnt_combo_box_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntComboBox", + &info, 0); + } + + return type; +} + +GntWidget *gnt_combo_box_new() +{ + GntWidget *widget = g_object_new(GNT_TYPE_COMBO_BOX, NULL); + + return widget; +} + +void gnt_combo_box_add_data(GntComboBox *box, gpointer key, const char *text) +{ + gnt_tree_add_row_after(GNT_TREE(box->dropdown), key, text, NULL, NULL); + if (box->selected == NULL) + set_selection(box, key); +} + +gpointer gnt_combo_box_get_selected_data(GntComboBox *box) +{ + return box->selected; +} +