# HG changeset patch # User Sadrul Habib Chowdhury # Date 1152575724 0 # Node ID 25be562aaca87b2b100b3116c100b00f1cb37dfe # Parent b14fdab68eacd0ad38359b8d7c8349c2150900e1 [gaim-migrate @ 16480] New widget GntLine to use as a separator. A partial dialog for add-account callback. Updating the dialog as a result of selection-change in the prpl dropdown is way ickier than I had expected it to be. It 'works' now, but quite a bit quirky. I will try to smooth things up later, perhaps next week. committer: Tailor Script diff -r b14fdab68eac -r 25be562aaca8 console/gntaccount.c --- a/console/gntaccount.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/gntaccount.c Mon Jul 10 23:55:24 2006 +0000 @@ -1,11 +1,17 @@ #include #include #include +#include +#include #include +#include #include +#include +#include #include #include +#include #include #include "gntaccount.h" @@ -19,6 +25,166 @@ static GGAccountList accounts; +typedef struct +{ + GaimAccount *account; /* NULL for a new account */ + + GntWidget *window; + + GntWidget *protocol; + GntWidget *screenname; + GntWidget *password; + GntWidget *alias; + + GntWidget *splits; + GList *split_entries; +} AccountEditDialog; + +static void +edit_dialog_destroy(AccountEditDialog *dialog) +{ + g_free(dialog); +} + +static void +save_account_cb(AccountEditDialog *dialog) +{ +} + +static void +update_user_splits(AccountEditDialog *dialog) +{ + GntWidget *hbox; + GaimPlugin *plugin; + GaimPluginProtocolInfo *prplinfo; + GList *iter; + char *username = NULL; + + if (dialog->splits) + { + gnt_box_remove_all(GNT_BOX(dialog->splits)); + g_list_free(dialog->split_entries); + } + else + { + dialog->splits = gnt_box_new(FALSE, TRUE); + gnt_box_set_pad(GNT_BOX(dialog->splits), 0); + } + + dialog->split_entries = NULL; + + plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); + if (!plugin) + return; + prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + username = g_strdup(gaim_account_get_username(dialog->account)); + + for (iter = prplinfo->user_splits; iter; iter = iter->next) + { + GaimAccountUserSplit *split = iter->data; + GntWidget *entry; + char *buf; + + hbox = gnt_box_new(TRUE, FALSE); + gnt_box_add_widget(GNT_BOX(dialog->splits), hbox); + + buf = g_strdup_printf("%s:", gaim_account_user_split_get_text(split)); + gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(buf)); + + entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(hbox), entry); + + dialog->split_entries = g_list_append(dialog->split_entries, entry); + g_free(buf); + } + + /* XXX: Add default/custom values to the splits */ + g_free(username); +} + +static void +prpl_changed_cb(GntWidget *combo, GaimPlugin *old, GaimPlugin *new, AccountEditDialog *dialog) +{ + update_user_splits(dialog); + gnt_box_readjust(GNT_BOX(dialog->window)); + gnt_widget_draw(dialog->window); +} + +static void +add_account(GntWidget *b, gpointer null) +{ + GntWidget *window, *hbox; + GntWidget *combo, *button, *entry; + GList *list, *iter; + AccountEditDialog *dialog; + + dialog = g_new0(AccountEditDialog, 1); + + dialog->window = window = gnt_box_new(FALSE, TRUE); + gnt_box_set_toplevel(GNT_BOX(window), TRUE); + gnt_box_set_title(GNT_BOX(window), _("New Account")); + gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); + gnt_box_set_pad(GNT_BOX(window), 0); + + hbox = gnt_box_new(TRUE, FALSE); + gnt_box_add_widget(GNT_BOX(window), hbox); + gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); + + dialog->protocol = combo = gnt_combo_box_new(); + list = gaim_plugins_get_protocols(); + for (iter = list; iter; iter = iter->next) + { + gnt_combo_box_add_data(GNT_COMBO_BOX(combo), iter->data, + ((GaimPlugin*)iter->data)->info->name); + } + g_signal_connect(G_OBJECT(combo), "selection-changed", G_CALLBACK(prpl_changed_cb), dialog); + gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Protocol:"))); + gnt_box_add_widget(GNT_BOX(hbox), combo); + + hbox = gnt_box_new(TRUE, FALSE); + gnt_box_add_widget(GNT_BOX(window), hbox); + + dialog->screenname = entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Screen name:"))); + gnt_box_add_widget(GNT_BOX(hbox), entry); + + /* User splits */ + update_user_splits(dialog); + gnt_box_add_widget(GNT_BOX(window), dialog->splits); + + hbox = gnt_box_new(TRUE, FALSE); + gnt_box_add_widget(GNT_BOX(window), hbox); + + dialog->password = entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Password:"))); + gnt_box_add_widget(GNT_BOX(hbox), entry); + + hbox = gnt_box_new(TRUE, FALSE); + gnt_box_add_widget(GNT_BOX(window), hbox); + + dialog->alias = entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Alias:"))); + gnt_box_add_widget(GNT_BOX(hbox), entry); + + gnt_box_add_widget(GNT_BOX(window), gnt_line_new(FALSE)); + + hbox = gnt_box_new(FALSE, FALSE); + gnt_box_add_widget(GNT_BOX(window), hbox); + + button = gnt_button_new(_("Cancel")); + gnt_box_add_widget(GNT_BOX(hbox), button); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), window); + + button = gnt_button_new(_("Save")); + gnt_box_add_widget(GNT_BOX(hbox), button); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(save_account_cb), dialog); + + g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(edit_dialog_destroy), dialog); + + gnt_widget_show(window); +} + static void account_toggled(GntWidget *widget, void *key, gpointer null) { @@ -32,15 +198,18 @@ GList *iter; GntWidget *box, *button; - accounts.window = gnt_box_new(TRUE, TRUE); + accounts.window = gnt_box_new(FALSE, TRUE); gnt_box_set_toplevel(GNT_BOX(accounts.window), TRUE); gnt_box_set_title(GNT_BOX(accounts.window), _("Accounts")); gnt_box_set_pad(GNT_BOX(accounts.window), 0); + gnt_box_set_alignment(GNT_BOX(accounts.window), GNT_ALIGN_MID); gnt_widget_set_name(accounts.window, "accounts"); gnt_box_add_widget(GNT_BOX(accounts.window), gnt_label_new(_("You can enable/disable accounts from the following list."))); + gnt_box_add_widget(GNT_BOX(accounts.window), gnt_line_new(FALSE)); + accounts.tree = gnt_tree_new(); GNT_WIDGET_SET_FLAGS(accounts.tree, GNT_WIDGET_NO_BORDER); @@ -62,10 +231,13 @@ gnt_widget_set_size(accounts.tree, 40, 10); gnt_box_add_widget(GNT_BOX(accounts.window), accounts.tree); + gnt_box_add_widget(GNT_BOX(accounts.window), gnt_line_new(FALSE)); + box = gnt_box_new(FALSE, FALSE); button = gnt_button_new(_("Add")); gnt_box_add_widget(GNT_BOX(box), button); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_account), NULL); button = gnt_button_new(_("Modify")); gnt_box_add_widget(GNT_BOX(box), button); diff -r b14fdab68eac -r 25be562aaca8 console/gntblist.c --- a/console/gntblist.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/gntblist.c Mon Jul 10 23:55:24 2006 +0000 @@ -234,6 +234,9 @@ GntTree *tree = GNT_TREE(ggblist->tree); GaimBlistNode *node = gnt_tree_get_selection_data(tree); + if (!node) + return; + if (GAIM_BLIST_NODE_IS_BUDDY(node)) { GaimBuddy *buddy = (GaimBuddy *)node; diff -r b14fdab68eac -r 25be562aaca8 console/gntconv.c --- a/console/gntconv.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/gntconv.c Mon Jul 10 23:55:24 2006 +0000 @@ -119,7 +119,7 @@ type = gaim_conversation_get_type(conv); title = g_strdup_printf(_("%s"), gaim_conversation_get_name(conv)); - ggc->window = gnt_box_new(TRUE, TRUE); + ggc->window = gnt_box_new(FALSE, TRUE); gnt_box_set_title(GNT_BOX(ggc->window), title); gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); gnt_box_set_pad(GNT_BOX(ggc->window), 0); diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/Makefile.am --- a/console/libgnt/Makefile.am Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/Makefile.am Mon Jul 10 23:55:24 2006 +0000 @@ -11,6 +11,7 @@ gntcombobox.c \ gntentry.c \ gntlabel.c \ + gntline.c \ gntmarshal.c \ gnttextview.c \ gnttree.c \ @@ -25,6 +26,7 @@ gntentry.h \ gntkeys.h \ gntlabel.h \ + gntline.h \ gntmarshal.h \ gnttextview.h \ gnttree.h \ diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gnt.h --- a/console/libgnt/gnt.h Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gnt.h Mon Jul 10 23:55:24 2006 +0000 @@ -17,6 +17,8 @@ void gnt_screen_take_focus(GntWidget *widget); +void gnt_screen_resize_widget(GntWidget *widget, int width, int height); + gboolean gnt_widget_has_focus(GntWidget *widget); void gnt_widget_set_urgent(GntWidget *widget); diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntbox.c --- a/console/libgnt/gntbox.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntbox.c Mon Jul 10 23:55:24 2006 +0000 @@ -77,7 +77,7 @@ gboolean has_border = FALSE; w = h = 0; - max = -1; + max = 0; curx = widget->priv.x; cury = widget->priv.y; if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) @@ -93,15 +93,21 @@ gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h); if (box->vertical) { - cury += h + box->pad; - if (max < w) - max = w; + if (h) + { + cury += h + box->pad; + if (max < w) + max = w; + } } else { - curx += w + box->pad; - if (max < h) - max = h; + if (w) + { + curx += w + box->pad; + if (max < h) + max = h; + } } } @@ -112,6 +118,14 @@ max += 2; } + if (box->list) + { + if (box->vertical) + cury -= box->pad; + else + curx -= box->pad; + } + if (box->vertical) { widget->priv.width = max; @@ -127,8 +141,18 @@ static void gnt_box_set_position(GntWidget *widget, int x, int y) { - gnt_widget_size_request(widget); - reposition_children(widget); + GList *iter; + int changex, changey; + + changex = widget->priv.x - x; + changey = widget->priv.y - y; + + for (iter = GNT_BOX(widget)->list; iter; iter = iter->next) + { + GntWidget *w = GNT_WIDGET(iter->data); + gnt_widget_set_position(w, w->priv.x - changex, + w->priv.y - changey); + } } static void @@ -136,25 +160,43 @@ { GntBox *box = GNT_BOX(widget); GList *iter; + int maxw = 0, maxh = 0; g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL); + for (iter = box->list; iter; iter = iter->next) + { + int w, h; + gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h); + if (maxh < h) + maxh = h; + if (maxw < w) + maxw = w; + } + if (box->homogeneous) { - int max = -1, w, h; - - /* XXX: should probably be changed based on vertical-ness */ for (iter = box->list; iter; iter = iter->next) { - gnt_widget_get_size(GNT_WIDGET(iter->data), &w, NULL); - if (max < w) - max = w; + gnt_widget_set_size(GNT_WIDGET(iter->data), maxw, maxh); } - + } + else + { for (iter = box->list; iter; iter = iter->next) { - gnt_widget_get_size(GNT_WIDGET(iter->data), NULL, &h); - gnt_widget_set_size(GNT_WIDGET(iter->data), max, h); + if (box->vertical) + { + int h; + gnt_widget_get_size(GNT_WIDGET(iter->data), NULL, &h); + gnt_widget_set_size(GNT_WIDGET(iter->data), maxw, h); + } + else + { + int w; + gnt_widget_get_size(GNT_WIDGET(iter->data), &w, NULL); + gnt_widget_set_size(GNT_WIDGET(iter->data), w, maxh); + } } } @@ -185,10 +227,21 @@ return box->active; } +static void +find_next_focus(GntBox *box) +{ + GList *iter = g_list_find(box->focus, box->active); + if (iter && iter->next) + box->active = iter->next->data; + else if (box->focus) + box->active = box->focus->data; +} + static gboolean gnt_box_key_pressed(GntWidget *widget, const char *text) { GntBox *box = GNT_BOX(widget); + GntWidget *now; if (box->active == NULL && !find_focusable_widget(box)) return FALSE; @@ -196,9 +249,10 @@ if (gnt_widget_key_pressed(box->active, text)) return TRUE; + now = box->active; + if (text[0] == 27) { - GntWidget *now = box->active; if (strcmp(text+1, GNT_KEY_LEFT) == 0) { GList *iter = g_list_find(box->focus, box->active); @@ -213,23 +267,19 @@ } else if (strcmp(text+1, GNT_KEY_RIGHT) == 0) { - GList *iter = g_list_find(box->focus, box->active); - if (iter && iter->next) - { - box->active = iter->next->data; - } - else if (box->focus) - { - box->active = box->focus->data; - } + find_next_focus(box); } + } + else if (text[0] == '\t') + { + find_next_focus(box); + } - if (now && now != box->active) - { - gnt_widget_set_focus(now, FALSE); - gnt_widget_set_focus(box->active, TRUE); - return TRUE; - } + if (now && now != box->active) + { + gnt_widget_set_focus(now, FALSE); + gnt_widget_set_focus(box->active, TRUE); + return TRUE; } return FALSE; @@ -257,16 +307,9 @@ gnt_box_destroy(GntWidget *w) { GntBox *box = GNT_BOX(w); - GList *iter; - for (iter = box->list; iter; iter = iter->next) - { - gnt_widget_destroy(iter->data); - } - + gnt_box_remove_all(box); gnt_screen_release(w); - - g_list_free(box->list); } static void @@ -285,9 +328,20 @@ GntBox *box = GNT_BOX(widget); int wchange, hchange; + if (widget->priv.width != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X)) + return FALSE; + if (widget->priv.height != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y)) + return FALSE; + + if (!box->list) + return TRUE; + wchange = widget->priv.width - width; hchange = widget->priv.height - height; + if (wchange == 0 && hchange == 0) + return TRUE; /* Quit playing games */ + /* XXX: Right now, I am trying to just apply all the changes to * just one widget. It should be possible to distribute the * changes to all the widgets in the box. */ @@ -298,14 +352,84 @@ gnt_widget_get_size(wid, &w, &h); - if (gnt_widget_set_size(wid, w - wchange, h - hchange)) + if (gnt_widget_confirm_size(wid, w - wchange, h - hchange)) + { + GList *i; + + for (i = box->list; i; i = i->next) + { + int tw, th; + if (i == iter) continue; + gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); + if (box->vertical) + { + if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) + return FALSE; + } + else + { + if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) + return FALSE; + } + } +#if 0 + gnt_widget_set_size(wid, w - wchange, h - hchange); + if (box->vertical) + hchange = 0; + else + wchange = 0; + + for (i = box->list; i; i = i->next) + { + int tw, th; + if (i == iter) continue; + gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); + gnt_widget_set_size(i->data, tw - wchange, th - hchange); + } +#endif + g_object_set_data(G_OBJECT(box), "size-queued", wid); return TRUE; + } } return FALSE; } static void +gnt_box_size_changed(GntWidget *widget, int oldw, int oldh) +{ + int wchange, hchange; + GList *i; + GntBox *box = GNT_BOX(widget); + GntWidget *wid; + int tw, th; + + wchange = widget->priv.width - oldw; + hchange = widget->priv.height - oldh; + + wid = g_object_get_data(G_OBJECT(box), "size-queued"); + if (wid) + { + gnt_widget_get_size(wid, &tw, &th); + gnt_widget_set_size(wid, tw + wchange, th + hchange); + g_object_set_data(G_OBJECT(box), "size-queued", NULL); + } + + if (box->vertical) + hchange = 0; + else + wchange = 0; + + for (i = box->list; i; i = i->next) + { + gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); + gnt_widget_set_size(i->data, tw + wchange, th + hchange); + } + + reposition_children(widget); +} + +static void gnt_box_class_init(GntBoxClass *klass) { parent_class = GNT_WIDGET_CLASS(klass); @@ -319,6 +443,7 @@ parent_class->lost_focus = gnt_box_lost_focus; parent_class->gained_focus = gnt_box_gained_focus; parent_class->confirm_size = gnt_box_confirm_size; + parent_class->size_changed = gnt_box_size_changed; DEBUG; } @@ -428,8 +553,10 @@ { GList *iter; GntWidget *widget = GNT_WIDGET(box); + int pos = 1; - /* XXX: werase first? */ + if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) + pos = 0; for (iter = box->list; iter; iter = iter->next) { @@ -451,8 +578,8 @@ x += widget->priv.width - width; else if (box->alignment == GNT_ALIGN_MID) x += (widget->priv.width - width)/2; - if (x + width > widget->priv.width - 1) - x -= x + width - (widget->priv.width - 1); + if (x + width > widget->priv.width - pos) + x -= x + width - (widget->priv.width - pos); } else { @@ -460,8 +587,8 @@ y += widget->priv.height - height; else if (box->alignment == GNT_ALIGN_MID) y += (widget->priv.height - height)/2; - if (y + height > widget->priv.height - 1) - y -= y + height - (widget->priv.height - 1); + if (y + height >= widget->priv.height - pos) + y = widget->priv.height - height - pos; } copywin(w->window, widget->window, 0, 0, @@ -474,3 +601,71 @@ box->alignment = alignment; } +void gnt_box_remove(GntBox *box, GntWidget *widget) +{ + box->list = g_list_remove(box->list, widget); + if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS) + && GNT_WIDGET(box)->parent == NULL && box->focus) + { + if (widget == box->active) + { + find_next_focus(box); + if (box->active == widget) /* There's only one widget */ + box->active = NULL; + } + box->focus = g_list_remove(box->focus, widget); + } + + if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(box), GNT_WIDGET_MAPPED)) + gnt_widget_draw(GNT_WIDGET(box)); +} + +void gnt_box_remove_all(GntBox *box) +{ + g_list_foreach(box->list, (GFunc)gnt_widget_destroy, NULL); + g_list_free(box->list); + g_list_free(box->focus); + box->list = NULL; + box->focus = NULL; + GNT_WIDGET(box)->priv.width = 0; + GNT_WIDGET(box)->priv.height = 0; +} + +void gnt_box_readjust(GntBox *box) +{ + GList *iter; + GntWidget *wid; + int width, height; + + g_return_if_fail(GNT_WIDGET(box)->parent == NULL); + + for (iter = box->list; iter; iter = iter->next) + { + GntWidget *w = iter->data; + if (GNT_IS_BOX(w)) + gnt_box_readjust(GNT_BOX(w)); + else + { + GNT_WIDGET_UNSET_FLAGS(w, GNT_WIDGET_MAPPED); + w->priv.width = 0; + w->priv.height = 0; + } + } + + wid = GNT_WIDGET(box); + GNT_WIDGET_UNSET_FLAGS(wid, GNT_WIDGET_MAPPED); + wid->priv.width = 0; + wid->priv.height = 0; + + if (wid->parent == NULL) + { + g_list_free(box->focus); + box->focus = NULL; + box->active = NULL; + gnt_widget_size_request(wid); + gnt_widget_get_size(wid, &width, &height); + gnt_screen_resize_widget(wid, width, height); + find_focusable_widget(box); + } +} + diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntbox.h --- a/console/libgnt/gntbox.h Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntbox.h Mon Jul 10 23:55:24 2006 +0000 @@ -62,6 +62,9 @@ GType gnt_box_get_gtype(void); +#define gnt_vbox_new(homo) gnt_box_new(homo, TRUE) +#define gnt_hbox_new(homo) gnt_box_new(homo, FALSE) + GntWidget *gnt_box_new(gboolean homo, gboolean vert); void gnt_box_add_widget(GntBox *box, GntWidget *widget); @@ -76,6 +79,12 @@ void gnt_box_set_alignment(GntBox *box, GntAlignment alignment); +void gnt_box_remove(GntBox *box, GntWidget *widget); /* XXX: does NOT destroy widget */ + +void gnt_box_remove_all(GntBox *box); /* Removes AND destroys all the widgets in it */ + +void gnt_box_readjust(GntBox *box); + G_END_DECLS #endif /* GNT_BOX_H */ diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntbutton.c --- a/console/libgnt/gntbutton.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntbutton.c Mon Jul 10 23:55:24 2006 +0000 @@ -69,10 +69,14 @@ static void gnt_button_init(GTypeInstance *instance, gpointer class) { + GntWidget *widget = GNT_WIDGET(instance); GntButton *button = GNT_BUTTON(instance); button->priv = g_new0(GntButtonPriv, 1); - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(button), GNT_WIDGET_GROW_X); /* Can be resized sideways */ + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X); + + widget->priv.minw = 4; + widget->priv.minh = 3; DEBUG; } diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntcombobox.c --- a/console/libgnt/gntcombobox.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntcombobox.c Mon Jul 10 23:55:24 2006 +0000 @@ -31,13 +31,13 @@ gnt_combo_box_draw(GntWidget *widget) { GntComboBox *box = GNT_COMBO_BOX(widget); - const char *text = NULL; + char *text = NULL; GntColorType type; int len; if (box->dropdown) { - text = gnt_tree_get_selection_text(GNT_TREE(box->dropdown)); + text = (char *)gnt_tree_get_selection_text(GNT_TREE(box->dropdown)); box->selected = gnt_tree_get_selection_data(GNT_TREE(box->dropdown)); } @@ -96,7 +96,6 @@ { 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); @@ -114,10 +113,19 @@ if (strcmp(text + 1, GNT_KEY_UP) == 0 || strcmp(text + 1, GNT_KEY_DOWN) == 0) { + GntWidget *parent = box->dropdown->parent; gnt_widget_set_size(box->dropdown, widget->priv.width, 9); - gnt_widget_set_position(box->dropdown->parent, + gnt_widget_set_position(parent, widget->priv.x, widget->priv.y + widget->priv.height - 1); - gnt_widget_draw(box->dropdown->parent); + if (parent->window) + { + if (mvwin(parent->window, widget->priv.y + widget->priv.height - 1, + widget->priv.x) == ERR) + mvwin(parent->window, + widget->priv.y - 9 + 1, widget->priv.x); + } + + gnt_widget_draw(parent); return TRUE; } } @@ -171,6 +179,7 @@ gnt_combo_box_init(GTypeInstance *instance, gpointer class) { GntWidget *box; + GntWidget *widget = GNT_WIDGET(instance); GntComboBox *combo = GNT_COMBO_BOX(instance); GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), @@ -182,6 +191,8 @@ gnt_box_set_pad(GNT_BOX(box), 0); gnt_box_add_widget(GNT_BOX(box), combo->dropdown); + widget->priv.minw = 4; + widget->priv.minh = 3; DEBUG; } diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntentry.c --- a/console/libgnt/gntentry.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntentry.c Mon Jul 10 23:55:24 2006 +0000 @@ -83,6 +83,10 @@ entry_redraw(widget); } /* XXX: handle other keys, like home/end, and ctrl+ goodness */ + else + return FALSE; + + return TRUE; } else { @@ -136,6 +140,7 @@ entry->scroll--; entry_redraw(widget); + return TRUE; } } } @@ -166,6 +171,7 @@ static void gnt_entry_init(GTypeInstance *instance, gpointer class) { + GntWidget *widget = GNT_WIDGET(instance); GntEntry *entry = GNT_ENTRY(instance); entry->flag = GNT_ENTRY_FLAG_ALL; @@ -174,6 +180,9 @@ GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS); GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_GROW_X); + + widget->priv.minw = 3; + widget->priv.minh = 1; DEBUG; } diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntlabel.c --- a/console/libgnt/gntlabel.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntlabel.c Mon Jul 10 23:55:24 2006 +0000 @@ -70,7 +70,10 @@ static void gnt_label_init(GTypeInstance *instance, gpointer class) { - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); + GntWidget *widget = GNT_WIDGET(instance); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X); + widget->priv.minw = 3; + widget->priv.minh = 1; DEBUG; } diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntline.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntline.c Mon Jul 10 23:55:24 2006 +0000 @@ -0,0 +1,115 @@ +#include "gntline.h" + +enum +{ + SIGS = 1, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_line_draw(GntWidget *widget) +{ + GntLine *line = GNT_LINE(widget); + if (line->vertical) + mvwvline(widget->window, 1, 0, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), + widget->priv.height - 3); + else + mvwhline(widget->window, 0, 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), + widget->priv.width - 3); +} + +static void +gnt_line_size_request(GntWidget *widget) +{ + if (GNT_LINE(widget)->vertical) + { + widget->priv.width = 1; + widget->priv.height = 5; + } + else + { + widget->priv.width = 5; + widget->priv.height = 1; + } +} + +static void +gnt_line_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static void +gnt_line_class_init(GntLineClass *klass) +{ + parent_class = GNT_WIDGET_CLASS(klass); + parent_class->draw = gnt_line_draw; + parent_class->map = gnt_line_map; + parent_class->size_request = gnt_line_size_request; + + DEBUG; +} + +static void +gnt_line_init(GTypeInstance *instance, gpointer class) +{ + GntWidget *widget = GNT_WIDGET(instance); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER); + widget->priv.minw = 1; + widget->priv.minh = 1; + DEBUG; +} + +/****************************************************************************** + * GntLine API + *****************************************************************************/ +GType +gnt_line_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntLineClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_line_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntLine), + 0, /* n_preallocs */ + gnt_line_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntLine", + &info, 0); + } + + return type; +} + +GntWidget *gnt_line_new(gboolean vertical) +{ + GntWidget *widget = g_object_new(GNT_TYPE_LINE, NULL); + GntLine *line = GNT_LINE(widget); + + line->vertical = vertical; + + if (vertical) + { + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_Y); + } + else + { + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X); + } + + return widget; +} + diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntline.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntline.h Mon Jul 10 23:55:24 2006 +0000 @@ -0,0 +1,49 @@ +#ifndef GNT_LINE_H +#define GNT_LINE_H + +#include "gntwidget.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" + +#define GNT_TYPE_LINE (gnt_line_get_gtype()) +#define GNT_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_LINE, GntLine)) +#define GNT_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_LINE, GntLineClass)) +#define GNT_IS_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_LINE)) +#define GNT_IS_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_LINE)) +#define GNT_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_LINE, GntLineClass)) + +#define GNT_LINE_FLAGS(obj) (GNT_LINE(obj)->priv.flags) +#define GNT_LINE_SET_FLAGS(obj, flags) (GNT_LINE_FLAGS(obj) |= flags) +#define GNT_LINE_UNSET_FLAGS(obj, flags) (GNT_LINE_FLAGS(obj) &= ~(flags)) + +typedef struct _GnLine GntLine; +typedef struct _GnLinePriv GntLinePriv; +typedef struct _GnLineClass GntLineClass; + +struct _GnLine +{ + GntWidget parent; + + gboolean vertical; +}; + +struct _GnLineClass +{ + GntWidgetClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_line_get_gtype(void); + +GntWidget *gnt_line_new(gboolean vertical); + +G_END_DECLS + +#endif /* GNT_LINE_H */ diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntmain.c --- a/console/libgnt/gntmain.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntmain.c Mon Jul 10 23:55:24 2006 +0000 @@ -400,6 +400,7 @@ { mode = GNT_KP_MODE_NORMAL; changed = TRUE; + gnt_widget_draw(widget); } if (changed) @@ -471,19 +472,7 @@ if (changed) { - GntNode *node = g_hash_table_lookup(nodes, widget); - int x, y; - - gnt_widget_get_position(widget, &x, &y); - - hide_panel(node->panel); - gnt_widget_set_size(widget, width, height); - gnt_widget_set_position(widget, x, y); - gnt_widget_draw(widget); - replace_panel(node->panel, widget->window); - show_panel(node->panel); - update_panels(); - doupdate(); + gnt_screen_resize_widget(widget, width, height); } } } @@ -673,3 +662,21 @@ return ascii_only; } +void gnt_screen_resize_widget(GntWidget *widget, int width, int height) +{ + if (widget->parent == NULL) + { + GntNode *node = g_hash_table_lookup(nodes, widget); + if (!node) + return; + + hide_panel(node->panel); + gnt_widget_set_size(widget, width, height); + gnt_widget_draw(widget); + replace_panel(node->panel, widget->window); + show_panel(node->panel); + update_panels(); + doupdate(); + } +} + diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gnttextview.c --- a/console/libgnt/gnttextview.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gnttextview.c Mon Jul 10 23:55:24 2006 +0000 @@ -113,9 +113,14 @@ static void gnt_text_view_init(GTypeInstance *instance, gpointer class) { + GntWidget *widget = GNT_WIDGET(instance); + /* XXX: For now, resizing the width is not permitted. This is because * of the way I am handling wrapped lines. */ GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_Y); + + widget->priv.minw = 5; + widget->priv.minh = 1; DEBUG; } diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gnttree.c --- a/console/libgnt/gnttree.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gnttree.c Mon Jul 10 23:55:24 2006 +0000 @@ -399,7 +399,10 @@ static void gnt_tree_init(GTypeInstance *instance, gpointer class) { - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); + GntWidget *widget = GNT_WIDGET(instance); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); + widget->priv.minw = 4; + widget->priv.minh = 3; DEBUG; } diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntwidget.c --- a/console/libgnt/gntwidget.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntwidget.c Mon Jul 10 23:55:24 2006 +0000 @@ -4,8 +4,6 @@ #include "gntmarshal.h" #include "gnt.h" -#define MIN_SIZE 5 - enum { SIG_DESTROY, @@ -18,6 +16,7 @@ SIG_EXPOSE, SIG_SIZE_REQUEST, SIG_CONFIRM_SIZE, + SIG_SIZE_CHANGED, SIG_POSITION, SIGS }; @@ -71,7 +70,7 @@ static gboolean gnt_widget_dummy_confirm_size(GntWidget *widget, int width, int height) { - if (width < MIN_SIZE || height < MIN_SIZE) + if (width < widget->priv.minw || height < widget->priv.minh) return FALSE; if (widget->priv.width != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X)) return FALSE; @@ -173,6 +172,14 @@ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + signals[SIG_SIZE_CHANGED] = + g_signal_new("size_changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWidgetClass, size_changed), + NULL, NULL, + gnt_closure_marshal_VOID__INT_INT, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); signals[SIG_CONFIRM_SIZE] = g_signal_new("confirm_size", G_TYPE_FROM_CLASS(klass), @@ -245,15 +252,8 @@ void gnt_widget_destroy(GntWidget *obj) { - int id; g_return_if_fail(GNT_IS_WIDGET(obj)); - if ((id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(obj), "gnt:queue_update")))) - { - g_source_remove(id); - g_object_set_data(G_OBJECT(obj), "gnt:queue_update", NULL); - } - gnt_widget_hide(obj); delwin(obj->window); if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING)) @@ -276,7 +276,6 @@ gnt_widget_draw(GntWidget *widget) { /* Draw the widget */ - DEBUG; if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING)) return; @@ -293,10 +292,9 @@ if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW)) shadow = FALSE; - + widget->window = newwin(widget->priv.height + shadow, widget->priv.width + shadow, widget->priv.y, widget->priv.x); - init_widget(widget); } @@ -337,11 +335,10 @@ void gnt_widget_set_position(GntWidget *wid, int x, int y) { + g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); /* XXX: Need to install properties for these and g_object_notify */ wid->priv.x = x; wid->priv.y = y; - - g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); } void @@ -404,27 +401,38 @@ { gboolean ret = TRUE; + if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW)) + { + width--; + height--; + } + if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) { - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW)) - { - width--; - height--; - } - g_signal_emit(widget, signals[SIG_CONFIRM_SIZE], 0, width, height, &ret); + ret = gnt_widget_confirm_size(widget, width, height); } if (ret) { gboolean shadow = TRUE; + int oldw, oldh; if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW)) shadow = FALSE; + oldw = widget->priv.width; + oldh = widget->priv.height; + widget->priv.width = width; widget->priv.height = height; + + g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh); + if (widget->window) + { wresize(widget->window, height + shadow, width + shadow); + init_widget(widget); + } if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) init_widget(widget); else @@ -475,7 +483,7 @@ if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) return FALSE; gnt_screen_update(widget); - g_object_set_data(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(FALSE)); + g_object_set_data(G_OBJECT(widget), "gnt:queue_update", NULL); return FALSE; } @@ -487,7 +495,15 @@ if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) { int id = g_timeout_add(0, update_queue_callback, widget); - g_object_set_data(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(id)); + g_object_set_data_full(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(id), + (GDestroyNotify)g_source_remove); } } +gboolean gnt_widget_confirm_size(GntWidget *widget, int width, int height) +{ + gboolean ret = FALSE; + g_signal_emit(widget, signals[SIG_CONFIRM_SIZE], 0, width, height, &ret); + return ret; +} + diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/gntwidget.h --- a/console/libgnt/gntwidget.h Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/gntwidget.h Mon Jul 10 23:55:24 2006 +0000 @@ -53,6 +53,8 @@ int width, height; GntWidgetFlags flags; char *name; + + int minw, minh; /* Minimum size for the widget */ }; struct _GnWidget @@ -84,6 +86,7 @@ void (*size_request)(GntWidget *widget); gboolean (*confirm_size)(GntWidget *widget, int x, int y); + void (*size_changed)(GntWidget *widget, int w, int h); void (*set_position)(GntWidget *widget, int x, int y); gboolean (*key_pressed)(GntWidget *widget, const char *key); void (*activate)(GntWidget *widget); @@ -108,6 +111,7 @@ void gnt_widget_size_request(GntWidget *widget); void gnt_widget_get_size(GntWidget *widget, int *width, int *height); gboolean gnt_widget_set_size(GntWidget *widget, int width, int height); +gboolean gnt_widget_confirm_size(GntWidget *widget, int width, int height); gboolean gnt_widget_key_pressed(GntWidget *widget, const char *keys); diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/test/combo.c --- a/console/libgnt/test/combo.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/test/combo.c Mon Jul 10 23:55:24 2006 +0000 @@ -4,11 +4,23 @@ #include #include +static void +button_activated(GntWidget *b, GntComboBox *combo) +{ + GntWidget *w = b->parent; + + gnt_box_add_widget(GNT_BOX(w), + gnt_label_new(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)))); + fprintf(stderr, "%s\n", gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))); + gnt_box_readjust(GNT_BOX(w->parent)); +} + int main() { GntWidget *box, *combo, *button; GntWidget *hbox; + freopen(".error", "w", stderr); gnt_init(); box = gnt_box_new(FALSE, TRUE); @@ -43,6 +55,7 @@ button = gnt_button_new("OK"); gnt_box_add_widget(GNT_BOX(hbox), button); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(button_activated), combo); gnt_box_add_widget(GNT_BOX(box), hbox); diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/test/focus.c --- a/console/libgnt/test/focus.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/test/focus.c Mon Jul 10 23:55:24 2006 +0000 @@ -20,6 +20,7 @@ int main() { + freopen(".error", "w", stderr); gnt_init(); GntWidget *label = gnt_label_new("So wassup dudes and dudettes!!\nSo this is, like,\nthe third line!! \\o/"); @@ -30,7 +31,7 @@ wrefresh(stdscr); vbox = gnt_box_new(FALSE, FALSE); - hbox = gnt_box_new(TRUE, TRUE); + hbox = gnt_box_new(FALSE, TRUE); gnt_widget_set_name(vbox, "vbox"); gnt_widget_set_name(hbox, "hbox"); diff -r b14fdab68eac -r 25be562aaca8 console/libgnt/test/multiwin.c --- a/console/libgnt/test/multiwin.c Mon Jul 10 18:08:11 2006 +0000 +++ b/console/libgnt/test/multiwin.c Mon Jul 10 23:55:24 2006 +0000 @@ -60,7 +60,7 @@ gnt_tree_set_row_flags(GNT_TREE(tree), "e", GNT_TEXT_FLAG_DIM); - g_timeout_add(5000, show, box2); + g_timeout_add(5000, (GSourceFunc)show, box2); gnt_main();