063. How to allow user to change font using GtkFontSelectionDialog?

Problem

You want to allow user to change font with a GtkFontSelectionDialog as shown below:

How to allow user to change font using GtkFontSelectionDialog?


Solution


Sample Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
45   
47   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
65   
66   
67   
68   
70   
71   
72   
73   
74   
75   
76   
77   
78   
79   
80   
81   
82   
83   
85   
86   
87   
88   
89   
91   
92   
93   
94   
95   
96   
97   
98   
99   
100   
101   
102   
103   
104   
105   
106   
107   
108   
110   
111   
112   
113   
114   
120   
121   
122   
126   
127   
128   
129   
130   
131   
132   
133   
134   
135   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 150);
$window->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());
$accel_group = new GtkAccelGroup(); // create a new accelerator
$window->add_accel_group($accel_group); // attach it to the window

// display title

$menu_definition = array(
    '_File' => array('E_xit|X'),
    '_Font' => array('Change _Font|F')
);
setup_menu($vbox, $menu_definition); // note 2

$label = new GtkLabel('Press Ctrl-F to change font');
$vbox->pack_start($label);

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

// process menu item selection
function on_menu_select($menu_item) {
    $item = $menu_item->child->get_label();
    echo "menu selected: $item\n";
    if ($item=='E_xit') Gtk::main_quit();
    if ($item=='Change _Font') {
        $selected_font = get_font(); // note 3
        print "selected_font = $selected_font\n";
        global $label;
        $label->modify_font(new PangoFontDescription($selected_font));
    }
}

// wrapper for class GetFont
function get_font() { 
// note 1
    $getfont_dialog = new GetFont();
    $font_name = $getfont_dialog->main();
    return $font_name;
}

class GetFont{ 
// note 1
    function GetFont() {
        $dialog = new GtkFontSelectionDialog('Select Font');
        $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
        $this->dialog = $dialog;
        $dialog->show_all();
    }

    function main() {
        $this->dialog->run();
        $fontname = $this->dialog->get_font_name();
        $this->dialog->destroy();
        return $fontname;
    }
}


function setup_menu($vbox, $menus) { // note 2
    global $accel_group;
    $menubar = new GtkMenuBar();
    $vbox->pack_start($menubar, 0, 0);
    foreach($menus as $toplevel => $sublevels) {
        $menubar->append($top_menu = new GtkMenuItem($toplevel));
        $menu = new GtkMenu();
        $top_menu->set_submenu($menu);
        foreach($sublevels as $submenu) {
            if (strpos("$submenu", '|') === false) {
                $accel_key = '';
            } else {
                list($submenu, $accel_key) = explode('|', $submenu);
            }

            if (is_array($submenu)) { // set up radio menus
                $i=0;
                $radio[0] = null;
                foreach($submenu as $radio_item) {
                    $radio[$i] = new GtkRadioMenuItem($radio[0], $radio_item);
                    $radio[$i]->connect('toggled', "on_toggle");
                    $menu->append($radio[$i]);
                    ++$i;
                }
                $radio[0]->set_active(1);
            } else {
                if ($submenu=='<hr>') {
                    $menu->append(new GtkSeparatorMenuItem());
                } else {
                    $submenu2 = str_replace('_', '', $submenu);
                    $submenu2 = str_replace(' ', '_', $submenu2);
                    $stock_image_name = 'Gtk::STOCK_'.strtoupper($submenu2);
                    if (defined($stock_image_name)) {
                        $menu_item = new GtkImageMenuItem(constant($stock_image_name));
                    } else {
                        $menu_item = new GtkMenuItem($submenu);
                    }
                    if ($accel_key!='') {
                        $menu_item->add_accelerator("activate", $accel_group, ord($accel_key), Gdk::CONTROL_MASK, 1);
                    }

                    $menu->append($menu_item);
                    $menu_item->connect('activate', 'on_menu_select');
                }
            }
        }
    }
}

?>

Output

As shown above.
 

Explanation

  1. Display a font dialog is exactly the same as display a standard dialog. We write a wrapper function get_font here so that we can get the font selection using a one-liner $selected_font = get_font().
  2. We make use of the codes in How to set up menu and radio menu - Part 3 - add accelerators? to display a menu with accelerators so that we can activate the font dialog with Ctrl-F.
  3. When Ctrl-F is pressed, we activate the font dialog, get user's selection, and change the font of the label.

Related Links

Add comment


Security code
Refresh