ardour
stateful_button.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000-2007 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <string>
21 #include <iostream>
22 
23 
24 #include <gtkmm/main.h>
25 
27 
28 using namespace Gtk;
29 using namespace Glib;
30 using namespace Gtkmm2ext;
31 using namespace std;
32 
33 StateButton::StateButton ()
34  : visual_state (0)
35  , _self_managed (false)
36  , _is_realized (false)
37  , style_changing (false)
38  , state_before_prelight (Gtk::STATE_NORMAL)
39  , is_toggle (false)
40 {
41 }
42 
43 void
45 {
46  if (!_is_realized) {
47  /* not yet realized */
48  visual_state = n;
49  return;
50  }
51 
52  if (n == visual_state) {
53  return;
54  }
55 
56  string name = get_widget_name ();
57  name = name.substr (0, name.find_last_of ('-'));
58 
59  switch (n) {
60  case 0:
61  /* relax */
62  break;
63  case 1:
64  name += "-active";
65  break;
66 
67  case 2:
68  name += "-alternate";
69  break;
70 
71  case 3:
72  name += "-alternate2";
73  break;
74  }
75 
76  set_widget_name (name);
77  visual_state = n;
78 }
79 
80 void
81 StateButton::avoid_prelight_on_style_changed (const Glib::RefPtr<Gtk::Style>& /* old_style */, GtkWidget* widget)
82 {
83  /* don't go into an endless recursive loop if we're changing
84  the style in response to an existing style change.
85  */
86 
87  if (style_changing) {
88  return;
89  }
90 
91  if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT) {
92 
93  /* avoid PRELIGHT: make sure that the prelight colors in this new style match
94  the colors of the new style in whatever state we were in
95  before we switched to prelight.
96  */
97 
98  GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget);
99  GtkStyle* style = gtk_widget_get_style (widget);
100 
101  rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[state_before_prelight];
102  rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[state_before_prelight];
103  rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG);
104 
105  style_changing = true;
106  g_object_ref (rcstyle);
107  gtk_widget_modify_style (widget, rcstyle);
108 
109  Widget* child = get_child_widget();
110  if (child) {
111  gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle);
112  }
113 
114 
115  g_object_unref (rcstyle);
116  style_changing = false;
117  }
118 }
119 
120 void
121 StateButton::avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget)
122 {
123  GtkStateType state = gtk_widget_get_state (widget);
124 
125  if (state == GTK_STATE_PRELIGHT) {
126 
127  state_before_prelight = old_state;
128 
129 
130  /* avoid PRELIGHT when currently ACTIVE:
131  if we just went into PRELIGHT, make sure that the colors
132  match those of whatever state we were in before.
133  */
134 
135  GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget);
136  GtkStyle* style = gtk_widget_get_style (widget);
137 
138  rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[old_state];
139  rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[old_state];
140  rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG);
141 
142  g_object_ref (rcstyle);
143  gtk_widget_modify_style (widget, rcstyle);
144 
145  Widget* child = get_child_widget ();
146 
147  if (child) {
148  gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle);
149  }
150 
151  g_object_unref (rcstyle);
152 
153  }
154 }
155 
156 /* ----------------------------------------------------------------- */
157 
159 {
160  is_toggle = true;
161 }
162 
164  : ToggleButton (label)
165 {
166  is_toggle = true;
167 }
168 
169 void
171 {
172  ToggleButton::on_realize ();
173 
174  _is_realized = true;
175  visual_state++; // to force transition
177 }
178 
179 void
181 {
182  Button::on_realize ();
183 
184  _is_realized = true;
185  visual_state++; // to force transition
187 }
188 
189 void
191 {
192  if (!_self_managed) {
193  if (get_active()) {
194  set_state (Gtk::STATE_ACTIVE);
195  } else {
196  set_state (Gtk::STATE_NORMAL);
197  }
198  }
199 }
200 
201 
202 void
203 StatefulToggleButton::on_style_changed (const Glib::RefPtr<Gtk::Style>& style)
204 {
205  avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj()));
206  Button::on_style_changed (style);
207 }
208 
209 void
210 StatefulToggleButton::on_state_changed (Gtk::StateType old_state)
211 {
212  avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj()));
213  Button::on_state_changed (old_state);
214 }
215 
216 Widget*
218 {
219  return get_child();
220 }
221 
222 void
224 {
225  set_name (name);
226  Widget* w = get_child();
227 
228  if (w) {
229  w->set_name (name);
230  }
231 }
232 
233 /*--------------------------------------------- */
234 
236 {
237 }
238 
239 StatefulButton::StatefulButton (const std::string& label)
240  : Button (label)
241 {
242 }
243 
244 void
245 StatefulButton::on_style_changed (const Glib::RefPtr<Gtk::Style>& style)
246 {
247  avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj()));
248  Button::on_style_changed (style);
249 }
250 
251 void
252 StatefulButton::on_state_changed (Gtk::StateType old_state)
253 {
254  avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj()));
255  Button::on_state_changed (old_state);
256 }
257 
258 Widget*
260 {
261  return get_child();
262 }
263 
264 void
266 {
267  set_name (name);
268  Widget* w = get_child();
269 
270  if (w) {
271  w->set_name (name);
272  }
273 }
Gtk::Widget * get_child_widget()
void avoid_prelight_on_state_changed(Gtk::StateType old_state, GtkWidget *widget)
void on_state_changed(Gtk::StateType old_state)
virtual std::string get_widget_name() const =0
Definition: ardour_ui.h:130
Definition: Beats.hpp:239
void avoid_prelight_on_style_changed(const Glib::RefPtr< Gtk::Style > &style, GtkWidget *widget)
virtual Gtk::Widget * get_child_widget()=0
virtual void set_widget_name(const std::string &name)=0
void on_state_changed(Gtk::StateType old_state)
const char * name
void on_style_changed(const Glib::RefPtr< Gtk::Style > &style)
void set_widget_name(const std::string &name)
void on_style_changed(const Glib::RefPtr< Gtk::Style > &style)
Gtk::StateType state_before_prelight
void set_widget_name(const std::string &name)