Copy local state in AudioRegionView copy constructor. Fixes #4047.
[ardour2.git] / libs / gtkmm2ext / stateful_button.cc
blob0548b8392b496c62fd7798c16e1ad0111adce573
1 /*
2 Copyright (C) 2000-2007 Paul Davis
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.
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.
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.
20 #include <string>
21 #include <iostream>
24 #include <gtkmm/main.h>
26 #include <gtkmm2ext/stateful_button.h>
28 using namespace Gtk;
29 using namespace Glib;
30 using namespace Gtkmm2ext;
31 using namespace std;
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)
43 void
44 StateButton::set_visual_state (int n)
46 if (!_is_realized) {
47 /* not yet realized */
48 visual_state = n;
49 return;
52 if (n == visual_state) {
53 return;
56 string name = get_widget_name ();
57 name = name.substr (0, name.find_last_of ('-'));
59 switch (n) {
60 case 0:
61 /* relax */
62 break;
63 case 1:
64 name += "-active";
65 break;
67 case 2:
68 name += "-alternate";
69 break;
71 case 3:
72 name += "-alternate2";
73 break;
76 set_widget_name (name);
77 visual_state = n;
80 void
81 StateButton::avoid_prelight_on_style_changed (const Glib::RefPtr<Gtk::Style>& /* old_style */, GtkWidget* widget)
83 /* don't go into an endless recursive loop if we're changing
84 the style in response to an existing style change.
87 if (style_changing) {
88 return;
91 if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT) {
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.
98 GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget);
99 GtkStyle* style = gtk_widget_get_style (widget);
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);
105 style_changing = true;
106 g_object_ref (rcstyle);
107 gtk_widget_modify_style (widget, rcstyle);
109 Widget* child = get_child_widget();
110 if (child) {
111 gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle);
114 g_object_unref (rcstyle);
115 style_changing = false;
119 void
120 StateButton::avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget)
122 GtkStateType state = gtk_widget_get_state (widget);
124 if (state == GTK_STATE_PRELIGHT) {
126 state_before_prelight = old_state;
129 /* avoid PRELIGHT when currently ACTIVE:
130 if we just went into PRELIGHT, make sure that the colors
131 match those of whatever state we were in before.
134 GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget);
135 GtkStyle* style = gtk_widget_get_style (widget);
137 rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[old_state];
138 rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[old_state];
139 rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG);
141 g_object_ref (rcstyle);
142 gtk_widget_modify_style (widget, rcstyle);
144 Widget* child = get_child_widget ();
146 if (child) {
147 gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle);
150 g_object_unref (rcstyle);
155 /* ----------------------------------------------------------------- */
157 StatefulToggleButton::StatefulToggleButton ()
159 is_toggle = true;
162 StatefulToggleButton::StatefulToggleButton (const std::string& label)
163 : ToggleButton (label)
165 is_toggle = true;
168 void
169 StatefulToggleButton::on_realize ()
171 ToggleButton::on_realize ();
173 _is_realized = true;
174 visual_state++; // to force transition
175 set_visual_state (visual_state - 1);
178 void
179 StatefulButton::on_realize ()
181 Button::on_realize ();
183 _is_realized = true;
184 visual_state++; // to force transition
185 set_visual_state (visual_state - 1);
188 void
189 StatefulToggleButton::on_toggled ()
191 if (!_self_managed) {
192 if (get_active()) {
193 set_state (Gtk::STATE_ACTIVE);
194 } else {
195 set_state (Gtk::STATE_NORMAL);
201 void
202 StatefulToggleButton::on_style_changed (const Glib::RefPtr<Gtk::Style>& style)
204 avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj()));
205 Button::on_style_changed (style);
208 void
209 StatefulToggleButton::on_state_changed (Gtk::StateType old_state)
211 avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj()));
212 Button::on_state_changed (old_state);
215 Widget*
216 StatefulToggleButton::get_child_widget ()
218 return get_child();
221 void
222 StatefulToggleButton::set_widget_name (const std::string& name)
224 set_name (name);
225 Widget* w = get_child();
227 if (w) {
228 w->set_name (name);
232 /*--------------------------------------------- */
234 StatefulButton::StatefulButton ()
238 StatefulButton::StatefulButton (const std::string& label)
239 : Button (label)
243 void
244 StatefulButton::on_style_changed (const Glib::RefPtr<Gtk::Style>& style)
246 avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj()));
247 Button::on_style_changed (style);
250 void
251 StatefulButton::on_state_changed (Gtk::StateType old_state)
253 avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj()));
254 Button::on_state_changed (old_state);
257 Widget*
258 StatefulButton::get_child_widget ()
260 return get_child();
263 void
264 StatefulButton::set_widget_name (const std::string& name)
266 set_name (name);
267 Widget* w = get_child();
269 if (w) {
270 w->set_name (name);