1 #include "Toggle.h"
2
Toggle(const Callback & callback)3 Toggle::Toggle(const Callback& callback) :
4 _callback(callback),
5 _callbackActive(false),
6 _toggled(false)
7 {}
8
isToggle() const9 bool Toggle::isToggle() const {
10 return true;
11 }
12
13 // Set the toggled state to true/false, according to <toggled> and update
14 // any associated widgets or notify any callbacks.
setToggled(const bool toggled)15 bool Toggle::setToggled(const bool toggled) {
16 if (_callbackActive) {
17 return false;
18 }
19
20 // Update the toggle status and export it to the GTK button
21 _toggled = toggled;
22 updateWidgets();
23
24 return true;
25 }
26
updateWidgets()27 void Toggle::updateWidgets() {
28 _callbackActive = true;
29
30 for (ToggleWidgetList::iterator i = _toggleWidgets.begin();
31 i != _toggleWidgets.end();
32 ++i)
33 {
34 GtkWidget* widget = *i;
35 if (GTK_IS_TOGGLE_TOOL_BUTTON(widget)) {
36 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), _toggled);
37 }
38 else if (GTK_IS_CHECK_MENU_ITEM(widget)) {
39 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), _toggled);
40 }
41 }
42
43 _callbackActive = false;
44 }
45
46 // On key press >> toggle the internal state
keyDown()47 void Toggle::keyDown() {
48 toggle();
49 }
50
isToggled() const51 bool Toggle::isToggled() const {
52 return _toggled;
53 }
54
connectWidget(GtkWidget * widget)55 void Toggle::connectWidget(GtkWidget* widget) {
56 if (GTK_IS_TOGGLE_TOOL_BUTTON(widget)) {
57 _toggleWidgets.push_back(widget);
58
59 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), _toggled);
60
61 // Connect the toggleToolbutton to the static callback of this class
62 g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(onToggleToolButtonClicked), this);
63 }
64 else if (GTK_IS_TOGGLE_BUTTON(widget)) {
65 // Store the pointer for later use
66 _toggleWidgets.push_back(widget);
67
68 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), _toggled);
69
70 g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(onToggleToolButtonClicked), this);
71 }
72 else if (GTK_IS_CHECK_MENU_ITEM(widget)) {
73 // Store it internally
74 _toggleWidgets.push_back(widget);
75
76 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), _toggled);
77
78 g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(onCheckMenuItemClicked), this);
79 }
80 }
81
82 // Invoke the registered callback and update/notify
toggle()83 void Toggle::toggle() {
84 if (_callbackActive) {
85 return;
86 }
87
88 // Check if the toggle event is enabled
89 if (_enabled) {
90 // Invert the <toggled> state
91 _toggled = !_toggled;
92
93 // Call the connected function
94 _callback();
95 }
96
97 // Update any attached GtkObjects in any case
98 updateWidgets();
99 }
100
101 // The static GTK callback methods that can be connected to a ToolButton or a MenuItem
onToggleToolButtonClicked(GtkToggleToolButton * toolButton,gpointer data)102 gboolean Toggle::onToggleToolButtonClicked(GtkToggleToolButton* toolButton, gpointer data) {
103
104 // Cast the passed pointer onto a Toggle class. Note: this may also call a toggle() method
105 // of a derived class.
106 Toggle* self = reinterpret_cast<Toggle*>(data);
107
108 // Check sanity and toggle this item
109 if (self != NULL) {
110 self->toggle();
111 }
112
113 return true;
114 }
115
onToggleButtonClicked(GtkToggleButton * toggleButton,gpointer data)116 gboolean Toggle::onToggleButtonClicked(GtkToggleButton* toggleButton, gpointer data) {
117 // Cast the passed pointer onto a Toggle class. Note: this may also call a toggle() method
118 // of a derived class.
119 Toggle* self = reinterpret_cast<Toggle*>(data);
120
121 // Check sanity and toggle this item
122 if (self != NULL) {
123 self->toggle();
124 }
125
126 return true;
127 }
128
onCheckMenuItemClicked(GtkMenuItem * menuitem,gpointer data)129 gboolean Toggle::onCheckMenuItemClicked(GtkMenuItem* menuitem, gpointer data) {
130 Toggle* self = reinterpret_cast<Toggle*>(data);
131
132 // Check sanity and toggle this item
133 if (self != NULL) {
134 self->toggle();
135 }
136
137 return true;
138 }
139