|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
New input box codeHello,
The attached patch re-implements input box as always a GtkTextView that is adjusting its height as necessary. Return/Enter sends text, Return/Enter with any modifier keys goes to next line in the input box, adjusting height as necessary. A largest height of 5 is used, after which a scrollbar is used - that value can easily be changed by adjusting the value passed to mud_window_textview_ensure_height(). The height is always kept only as high as necessary. The code used to check line_yrange in ensure_height too, in addition to on creation, but I opted for saving the line height and re-use it, because there seem to be bugs in GtkTextView that cause get_line_yrange to report a bogus value (usually an old visible_line_count * real height of a line) on line reduction to 1; e.g if you have two visible lines, and hitting backspace deletes the linebreak, get_yrange will report 34, not 17 as it should on my system. I think the same can be seen with after sending the thing off the mud (and keep_text is off?). This means that if the input boxes font height changes after initial creation, it will get bad heights from that on. Need to either workaround the get_yrange problem somehow, or respond to height changing signals and cache it again, or do something more clean. In wxMUD I always query the font height, for example. But that's mainly just because I don't have clean access to gtk_text_view_get_line_yrange at all there. The horizontal scrollbar policy is made AUTOMATIC instead of NONE because of gnome bugzilla bug #308126 - it will appear only if we hit that bug. This ensures that the input box won't make the toplevel grow it's width without a limit, which would be just plain wrong to do. The discoverability of modifier+enter is a little problem, imho, too. But all the cool kids are doing it (gaim, gossip?) You might want to set the wrap mode in glade file instead of code. I did it in code because: a) I don't trust my glade GUI to not screw up the glade file to no recognition (the removal of text_entry and co was done by hand in text editor) b) I'm not sure if it should be in the glade file, instead of code - it is a programmatical thing to ensure such word-wrap, not an UI choice. The size_request is set on the vscrollbar of text_view_scroll because otherwise it's higher than a line height, and we don't like that. Worth noting is, that with it always being a GtkTextView, implementing password hiding will be quite a feat, if possible at all without loosing sanity. Hopefully the patch is useful and commitable as is, or after slight changes/improvements. I need to work on other things for a couple of days myself, so posting the current (not-too-bad) state of the patch here for consideration. -- With regards, Mart Raudsepp Project manager of wxMUD - http://wxmud.sourceforge.net/ Developer of wxWidgets - http://www.wxwidgets.org/ GTK+ port maintainer of OMGUI - http://www.omgui.org/ [automatic_multiline_input.patch] Index: src/mud-window.c =================================================================== RCS file: /cvs/gnome/gnome-mud/src/mud-window.c,v retrieving revision 1.19 diff -u -B -r1.19 mud-window.c --- src/mud-window.c 25 Apr 2006 09:12:44 -0000 1.19 +++ src/mud-window.c 25 Apr 2006 19:59:27 -0000 @@ -42,7 +42,6 @@ GtkWidget *window; GtkWidget *notebook; - GtkWidget *textentry; GtkWidget *textview; GtkWidget *textviewscroll; GtkWidget *mainvpane; @@ -64,7 +63,7 @@ gchar *port; gint nr_of_tabs; - gint toggleState; + gint textview_line_height; MudTray *tray; }; @@ -190,34 +189,72 @@ } -static gboolean -mud_window_textentry_keypress(GtkWidget *widget, GdkEventKey *event, MudWindow *window) +static gint +mud_window_textview_get_display_line_count(GtkTextView *textview) { + gint result = 1; + GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview); + GtkTextIter iter; - return FALSE; + gtk_text_buffer_get_start_iter(buffer, &iter); + while (gtk_text_view_forward_display_line(textview, &iter)) + ++result; + + if (gtk_text_buffer_get_line_count(buffer) != 1) + { + GtkTextIter iter2; + gtk_text_buffer_get_end_iter(buffer, &iter2); + if (gtk_text_iter_get_chars_in_line(&iter) == 0) + ++result; + } + + return result; +} + +static void +mud_window_textview_ensure_height(MudWindow *window, guint max_lines) +{ + gint lines = mud_window_textview_get_display_line_count(GTK_TEXT_VIEW(window->priv->textview)); + gtk_widget_set_size_request(window->priv->textview, -1, + window->priv->textview_line_height * MIN(lines, max_lines)); + gtk_widget_queue_resize(gtk_widget_get_parent(window->priv->textview)); +} + +static void +mud_window_textview_buffer_changed(GtkTextBuffer *buffer, MudWindow *window) +{ + mud_window_textview_ensure_height(window, 5); } static gboolean mud_window_textview_keypress(GtkWidget *widget, GdkEventKey *event, MudWindow *window) { gchar *text; - GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(window->priv->textview)); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(window->priv->textview)); GtkTextIter start, end; - if(event->keyval == GDK_KP_Enter) + if ((event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) && + (event->state & gtk_accelerator_get_default_mod_mask()) == 0) { - if(window->priv->current_view) - { - gtk_text_buffer_get_bounds(buffer, &start, &end); - - text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); + gtk_text_buffer_get_bounds(buffer, &start, &end); + + text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); + + if (g_str_equal(text, "")) + text = g_strdup(" "); + + if (window->priv->current_view) mud_connection_view_send(MUD_CONNECTION_VIEW(window->priv->current_view), text); - + + if (gconf_client_get_bool(window->priv->gconf_client, + "/apps/gnome-mud/functionality/keeptext", NULL) == FALSE) + gtk_text_buffer_delete(buffer, &start, &end); + else gtk_text_buffer_select_range(buffer, &start, &end); - return TRUE; - - } + free(text); + + return TRUE; } return FALSE; @@ -257,22 +294,6 @@ } static void -mud_window_textentry_activate(GtkWidget *widget, MudWindow *window) -{ - gchar *tmp; - - tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); - if (g_str_equal(tmp, "")) - tmp = g_strdup(" "); - if (window->priv->current_view) - mud_connection_view_send(MUD_CONNECTION_VIEW(window->priv->current_view), tmp); - if (gconf_client_get_bool(window->priv->gconf_client, - "/apps/gnome-mud/functionality/keeptext", NULL) == FALSE) - gtk_entry_set_text(GTK_ENTRY(widget), g_strdup("")); - free (tmp); -} - -static void mud_window_preferences_cb(GtkWidget *widget, MudWindow *window) { mud_preferences_window_new("Default"); @@ -316,25 +337,6 @@ mud_window_mconnect_new(window, mywig, window->priv->tray); } -static void -mud_window_inputtoggle_cb(GtkWidget *widget, MudWindow *window) -{ - - if(window->priv->toggleState) - { - gtk_widget_hide(window->priv->textview); - gtk_widget_hide(window->priv->textviewscroll); - gtk_widget_show(window->priv->textentry); - } - else - { - gtk_widget_hide(window->priv->textentry); - gtk_widget_show(window->priv->textview); - gtk_widget_show(window->priv->textviewscroll); - } - window->priv->toggleState = !window->priv->toggleState; -} - gboolean mud_window_size_request(GtkWidget *widget, GdkEventConfigure *event, gpointer user_data) { @@ -650,10 +652,9 @@ g_signal_connect(window->priv->bufferdump, "activate", G_CALLBACK(mud_window_buffer_cb), window); /* preferences window button */ - window->priv->mi_profiles = glade_xml_get_widget(glade, "mi_profiles_menu"); g_signal_connect(glade_xml_get_widget(glade, "menu_preferences"), "activate", G_CALLBACK(mud_window_preferences_cb), window); - + g_signal_connect(glade_xml_get_widget(glade, "menu_about"), "activate", G_CALLBACK(mud_window_about_cb), window); /* other objects */ @@ -663,22 +664,27 @@ window->priv->textviewscroll = glade_xml_get_widget(glade, "text_view_scroll"); window->priv->textview = glade_xml_get_widget(glade, "text_view"); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(window->priv->textview), GTK_WRAP_WORD_CHAR); + g_signal_connect(window->priv->textview, "key_press_event", G_CALLBACK(mud_window_textview_keypress), window); - - gtk_widget_hide(window->priv->textviewscroll); - gtk_widget_hide(window->priv->textview); - - window->priv->toggleState = 0; + g_signal_connect(gtk_text_view_get_buffer(GTK_TEXT_VIEW(window->priv->textview)), "changed", + G_CALLBACK(mud_window_textview_buffer_changed), window); - window->priv->textentry = glade_xml_get_widget(glade, "text_entry"); - g_signal_connect(window->priv->textentry, "key_press_event", G_CALLBACK(mud_window_textentry_keypress), window); - g_signal_connect(window->priv->textentry, "activate", G_CALLBACK(mud_window_textentry_activate), window); + { + /* Set the initial height of the input box equal to the height of one line */ + GtkTextIter iter; + gint y; + gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(window->priv->textview)), &iter); + gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(window->priv->textview), &iter, &y, &window->priv->textview_line_height); - window->priv->mainvpane = glade_xml_get_widget(glade, "main_vpane"); - - window->priv->image = glade_xml_get_widget(glade, "image"); + gtk_widget_set_size_request(window->priv->textview, -1, window->priv->textview_line_height*1); + gtk_widget_set_size_request(GTK_SCROLLED_WINDOW(window->priv->textviewscroll)->vscrollbar, -1, 1); - g_signal_connect(glade_xml_get_widget(glade, "toggle_input"), "clicked", G_CALLBACK(mud_window_inputtoggle_cb), window); + if (GTK_WIDGET_VISIBLE(window->priv->textviewscroll)) + gtk_widget_queue_resize(window->priv->textviewscroll); + } + + window->priv->image = glade_xml_get_widget(glade, "image"); g_signal_connect(glade_xml_get_widget(glade, "plugin_list"), "activate", G_CALLBACK(do_plugin_information), NULL); Index: ui/main.glade =================================================================== RCS file: /cvs/gnome/gnome-mud/ui/main.glade,v retrieving revision 1.17 diff -u -B -r1.17 main.glade --- ui/main.glade 25 Apr 2006 09:12:44 -0000 1.17 +++ ui/main.glade 25 Apr 2006 19:59:27 -0000 @@ -537,30 +537,10 @@ <property name="spacing">0</property> <child> - <widget class="GtkEntry" id="text_entry"> - <property name="height_request">25</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> <widget class="GtkScrolledWindow" id="text_view_scroll"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> <property name="shadow_type">GTK_SHADOW_IN</property> <property name="window_placement">GTK_CORNER_TOP_LEFT</property> @@ -598,31 +578,6 @@ </packing> </child> - <child> - <widget class="GtkButton" id="toggle_input"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - - <child> - <widget class="GtkImage" id="image65"> - <property name="visible">True</property> - <property name="stock">gtk-justify-fill</property> - <property name="icon_size">1</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> </widget> <packing> <property name="padding">0</property> _______________________________________________ gnome-mud-list mailing list gnome-mud-list@... http://mail.gnome.org/mailman/listinfo/gnome-mud-list |
| Free embeddable forum powered by Nabble | Forum Help |