473. How to apply styles to GtkTextView using GtkTextTag - Part 2 - toggle the formatting on and off?

Problem

I've showed you how to apply styles to GtkTextView / GtkTextBuffer (e.g. bold, italic, underline, font color and highlight) in How to apply styles to GtkTextView using GtkTextTag - Part 1?

This article shows you how to toggle these styles on and off using the same format buttons as shown below.

Note: This sample code in this article is contributed by Dysmas. It's a follow-up of another sample code contributed by him: How to have a popup textview for editing of long text?

How to apply styles to GtkTextView using GtkTextTag - Part 2 - toggle the formatting on and off?


Solution


Sample Code

1   
2   
3   
4   
5   
6   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
53   
55   
56   
57   
58   
59   
60   
61   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
75   
77   
78   
80   
81   
83   
84   
86   
87   
88   
89   
90   
99   
100   
101   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(400, 240);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// define menu definition
$toolbar_definition = array('Bold', 'Italic', 'Underline', '<hr>',
    'Blue', '<hr>', 'Highlight');
setup_toolbar($vbox, $toolbar_definition);

// Create a new buffer and a new view to show the buffer.
$buffer = new GtkTextBuffer();
$view = new GtkTextView();
$view->set_buffer($buffer);
$view->modify_font(new PangoFontDescription("Arial 12"));
$view->set_wrap_mode(Gtk::WRAP_WORD);
$vbox->pack_start($view);
$view->grab_focus();

$tag_table = $buffer->get_tag_table();
$tag['Bold'] = new GtkTextTag();
$tag['Bold']->set_property('weight', Pango::WEIGHT_BOLD);
$tag_table->add($tag['Bold']);

$tag['Italic'] = new GtkTextTag();
$tag['Italic']->set_property('style', Pango::STYLE_ITALIC);
$tag_table->add($tag['Italic']);

$tag['Underline'] = new GtkTextTag();
$tag['Underline']->set_property('underline', Pango::UNDERLINE_SINGLE);
$tag_table->add($tag['Underline']);

$tag['Blue'] = new GtkTextTag();
$tag['Blue']->set_property('foreground', "#0000ff");
$tag_table->add($tag['Blue']);

$tag['Highlight'] = new GtkTextTag();
$tag['Highlight']->set_property('background', "#ffff00");
$tag_table->add($tag['Highlight']);

$window->show_all();
Gtk::main();

// setup toolbar
function setup_toolbar($vbox, $toolbar_definition) {
    $toolbar = new GtkToolBar();
    $vbox->pack_start($toolbar, 0, 0);
    foreach($toolbar_definition as $item) {
        if ($item=='<hr>') {
            $toolbar->insert(new GtkSeparatorToolItem(), -1);
        } else {
            $stock_image_name = 'Gtk::STOCK_'.strtoupper($item);
            if (defined($stock_image_name)) {
                $toolbar_item = GtkToolButton::new_from_stock(constant($stock_image_name));
            } else {
                $toolbar_item = new GtkToolButton(); // no stock item
                $toolbar_item->set_label("\n".$item); // just display the text label
            }
            $toolbar->insert($toolbar_item, -1);
            $toolbar_item->connect('clicked', 'on_toolbar_button', $item);
        }
    }
}

// process toolbar
function on_toolbar_button($button, $item) {
    global $buffer, $tag;
    echo "toolbar clicked: $item\n";
    list($start, $end) = $buffer->get_selection_bounds();
    if ($start==null || $end==null) return; // no selection
    if (($start->has_tag($tag[$item]) && $end->has_tag($tag[$item])) || // note 1
        ($start->has_tag($tag[$item]) && $end->ends_tag($tag[$item]))) { 
        $buffer->remove_tag($tag[$item], $start, $end); // note 2
    } else {
        $buffer->apply_tag($tag[$item], $start, $end); // note 3
    }

}

?>

Output

As shown above.
 

Explanation

We make use of the code in How to set up toolbar? to display the toolbar.

What's new here:

  1. Selection already contains the style?
  2. Yes, remove it.
  3. No, apply the style.

Note

The sample code above only performs bold. When you press the bold button on a "bolded" text, it doesn't unbold. We will improve on this in Part 2.

Related Links

Add comment


Security code
Refresh