File: SwitchModelButton.vala

package info (click to toggle)
granite-7 7.7.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,876 kB
  • sloc: xml: 86; makefile: 9
file content (108 lines) | stat: -rw-r--r-- 3,267 bytes parent folder | download | duplicates (2)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 * Copyright 2021 elementary, Inc. (https://elementary.io)
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

/**
 * SwitchModelButton is a {@link Gtk.ToggleButton} containing a {@link Gtk.Label}
 * and a {@link Gtk.Switch} and using the menuitem css name. It can optionally
 * show description text when activated.
 *
 * ''Example''<<BR>>
 * {{{
 *   var switchmodelbutton = new Granite.SwitchModelButton ("With Description") {
 *       active = true,
 *       description = "A description of additional affects related to the activation state of this switch"
 *   };
 * }}}
 */
public class Granite.SwitchModelButton : Gtk.ToggleButton {
    /**
     * The label for the button.
     */
    public string text { get; construct set; }

    /**
     * Small, dim description text shown when active.
     */
    public string? description { get; set; }

    public SwitchModelButton (string text) {
        Object (text: text);
    }

    class construct {
        set_css_name ("modelbutton");
    }

    construct {
        var label = new Gtk.Label (text) {
            halign = START,
            hexpand = true,
            max_width_chars = 25,
            vexpand = true,
            wrap = true,
            xalign = 0,
            mnemonic_widget = this
        };

        var description_label = new Gtk.Label (null) {
            max_width_chars = 25,
            wrap = true,
            xalign = 0
        };
        description_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL);
        description_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL);

        var description_revealer = new Gtk.Revealer () {
            child = description_label
        };

        layout_manager = new Gtk.BoxLayout (HORIZONTAL);

        var box = new Gtk.Box (VERTICAL, 0);
        box.append (label);
        box.set_parent (this);

        var button_switch = new Gtk.Switch () {
            focusable = false,
            valign = Gtk.Align.START
        };
        button_switch.set_parent (this);

        accessible_role = SWITCH;

        bind_property ("text", label, "label");
        bind_property ("description", description_label, "label");
        bind_property ("active", button_switch, "active", BIDIRECTIONAL | SYNC_CREATE);

        var controller = new Gtk.GestureClick ();
        add_controller (controller);

        // Binding active doesn't trigger the switch animation; we must listen and manually activate
        controller.released.connect (() => {
            button_switch.activate ();
        });

        notify["active"].connect (() => {
            update_state (Gtk.AccessibleState.CHECKED, active, -1);
        });

        notify["description"].connect (() => {
            update_property (Gtk.AccessibleProperty.DESCRIPTION, description, -1);

            if (description == null || description == "") {
                box.remove (description_revealer);
            } else {
                box.append (description_revealer);
                button_switch.bind_property ("active", description_revealer, "reveal-child", GLib.BindingFlags.SYNC_CREATE);
            }
        });
    }

    ~SwitchModelButton () {
        while (get_first_child () != null) {
            get_first_child ().unparent ();
        }
    }
}