Problem
Dysmas sent me this interesting and very useful sample code that allows you to have a popup textview for editing of long text.
For example, you have set up a form that prompts the user for feedback as shown below.
If the user wants to enter a lot of text in the comments field (e.g. he would like to attach some sample codes), he can double click in the comments field which will popup a bigger textview for him to enter.
By default, a double click in a textview will select and highlight a word. You might want to see from this example how to intercept the double-click to popup the textview in a dialog box.
Solution
- We make use of the technique from How to align GtkEntry fields - Part 2? to display the form.
- By default, a double click in a textview will select and highlight a word. In addition to using button-press-event to intercept the double-click, you also need to use the method
emit_stop_by_name('button-press-event')
to stop the default actions.
Important Note: This only works for PHP-GTK2 compliled with gtk+ v2.10 and above. If you are using an older version, for linux, you may follow the step-by-step instructions to recompile php-gtk2 with gtk+ v2.10. For windows, please refer to How to install php gtk2 on windows? You may also want to take a look here to see some of the new exciting PHP-GTK2 Functionalities.
Sample Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 32 33 34 35 36 37 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 56 58 59 60 61 62 63 64 65 66 67 68 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 118 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | <?php $window = new GtkWindow(); $window->set_title($argv[0]); $window->set_size_request(400, 280); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox()); // display title $title = new GtkLabel("Have a popup textview for editing of long text"); $title->modify_font(new PangoFontDescription("Times New Roman Italic 10")); $title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff")); $title->set_size_request(-1, 40); $vbox->pack_start($title, 0, 0); $fields = array('Name', 'Email', 'Comments'); $field_size = array(240, 120, 0); $entry = array(); // to store the text entries $table = new GtkTable(); display_table($table, $fields, $field_size); // display the table $vbox->pack_start($table); function display_table($table, $fields, $field_size) { global $entry; $row = 0; foreach ($fields as $field) { $label = new GtkLabel(" $field: "); $alignment = new GtkAlignment(1, 0, 0, 0); $alignment->add($label); $table->attach($alignment, 0, 1, $row, $row+1); if ($field=='Comments') { $buffer = new GtkTextBuffer(); global $view; $view = new GtkTextView(); $view->set_buffer($buffer); $view->set_wrap_mode(Gtk::WRAP_WORD); $view->set_size_request(280, 80); $view->connect('button-press-event', 'on_view_button_press'); // note 1 $entry[$row] = new GtkVBox(); $entry[$row]->pack_start($view, 0); $entry[$row]->pack_start( new GtkLabel('Double-click for bigger text-edit window')); } else { $entry[$row] = new GtkEntry(); $entry[$row]->set_size_request($field_size[$row], -1); } $alignment = new GtkAlignment(0, 0, 0, 0); $alignment->add($entry[$row]); $table->attach($alignment, 1, 2, $row, $row+1); ++$row; } } // create a submit button $button = new GtkButton('Submit'); $button->set_size_request(60, 28); $button->connect('clicked', 'on_click'); $row = count($fields); $alignment = new GtkAlignment(0, 0.5, 0, 0); $alignment->add($button); $table->attach($alignment, 1, 2, $row, $row+1); $window->show_all(); Gtk::main(); function on_click($button) { global $fields, $entry; $i=0; foreach($fields as $field) { if ($field=='Comments') { global $view; $buffer = $view->get_buffer(); $input = $buffer->get_text($buffer->get_start_iter(), $buffer->get_end_iter()); } else { $input = $entry[$i]->get_text(); } echo "$field: $input\n"; ++$i; } } function on_view_button_press($widget, $event) { if ($event->type==Gdk::_2BUTTON_PRESS) { print "bp201. double-click!\n"; $zoom = new zoom($widget); // note 2 $widget->emit_stop_by_name('button-press-event'); // note 3 return true; } else { return false; } } function zoom($widget) { $zoom = new zoom($widget); } class zoom{ var $entry; var $ok=0; var $buff; function zoom($view) { $dialog = new GtkDialog('Zoom', null, Gtk::DIALOG_MODAL|Gtk::DIALOG_NO_SEPARATOR); $dialog->set_size_request(400, 300); // $label = new GtkLabel($label: "); // $dialog->vbox->pack_start($label); $scrolled_win = new GtkScrolledWindow(); $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); $dialog->vbox->pack_start($scrolled_win); $buffer = $view->get_buffer(); $view_copy = new GtkTextView(); $buffer_copy = new GtkTextBuffer(); $buffer_copy->set_text($buffer->get_text( $buffer->get_start_iter(), $buffer->get_end_iter())); $view_copy->set_buffer($buffer_copy); $scrolled_win->add($view_copy); $this->buffer = $buffer; $this->buffer_copy = $buffer_copy; $button_save = new GtkButton('Save'); $button_discard = new GtkButton('Discard'); $button_save->connect('clicked', array($this, 'on_button_save')); $button_discard->connect('clicked', array($this, 'on_button_discard')); $button_save->set_size_request(80, -1); $button_discard->set_size_request(80, -1); $hbox = new GtkHBox(); $dialog->vbox->pack_start($hbox, 0); $hbox->pack_start(new GtkLabel()); $hbox->pack_start($button_save, 0); $hbox->pack_start(new GtkLabel(' '), 0); $hbox->pack_start($button_discard, 0); $dialog->action_area->set_size_request(-1, 1); $this->dialog = $dialog; $dialog->show_all(); $dialog->run(); $dialog->destroy(); } function on_button_save($button) { $this->buffer->set_text($this->buffer_copy->get_text( $this->buffer_copy->get_start_iter(), $this->buffer_copy->get_end_iter())); $this->dialog->destroy(); } function on_button_discard($button) { $this->dialog->destroy(); } } ?> |
Output
As shown above.
Explanation
- Intercept the double-click.
- Popup the textview in a dialog box.
- Stop any default actions.
Read more...