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.
24 #include <gtkmm/main.h>
26 #include <gtkmm2ext/stateful_button.h>
30 using namespace Gtkmm2ext;
33 StateButton::StateButton ()
35 , _self_managed (false)
36 , _is_realized (false)
37 , style_changing (false)
38 , state_before_prelight (Gtk::STATE_NORMAL)
44 StateButton::set_visual_state (int n)
47 /* not yet realized */
52 if (n == visual_state) {
56 string name = get_widget_name ();
57 name = name.substr (0, name.find_last_of ('-'));
72 name += "-alternate2";
76 set_widget_name (name);
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.
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();
111 gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle);
115 g_object_unref (rcstyle);
116 style_changing = false;
121 StateButton::avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget)
123 GtkStateType state = gtk_widget_get_state (widget);
125 if (state == GTK_STATE_PRELIGHT) {
127 state_before_prelight = old_state;
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.
135 GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget);
136 GtkStyle* style = gtk_widget_get_style (widget);
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);
142 g_object_ref (rcstyle);
143 gtk_widget_modify_style (widget, rcstyle);
145 Widget* child = get_child_widget ();
148 gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle);
151 g_object_unref (rcstyle);
156 /* ----------------------------------------------------------------- */
158 StatefulToggleButton::StatefulToggleButton ()
163 StatefulToggleButton::StatefulToggleButton (const std::string& label)
164 : ToggleButton (label)
170 StatefulToggleButton::on_realize ()
172 ToggleButton::on_realize ();
175 visual_state++; // to force transition
176 set_visual_state (visual_state - 1);
180 StatefulButton::on_realize ()
182 Button::on_realize ();
185 visual_state++; // to force transition
186 set_visual_state (visual_state - 1);
190 StatefulToggleButton::on_toggled ()
192 if (!_self_managed) {
194 set_state (Gtk::STATE_ACTIVE);
196 set_state (Gtk::STATE_NORMAL);
203 StatefulToggleButton::on_style_changed (const Glib::RefPtr<Gtk::Style>& style)
205 avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj()));
206 Button::on_style_changed (style);
210 StatefulToggleButton::on_state_changed (Gtk::StateType old_state)
212 avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj()));
213 Button::on_state_changed (old_state);
217 StatefulToggleButton::get_child_widget ()
223 StatefulToggleButton::set_widget_name (const std::string& name)
226 Widget* w = get_child();
233 /*--------------------------------------------- */
235 StatefulButton::StatefulButton ()
239 StatefulButton::StatefulButton (const std::string& label)
245 StatefulButton::on_style_changed (const Glib::RefPtr<Gtk::Style>& style)
247 avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj()));
248 Button::on_style_changed (style);
252 StatefulButton::on_state_changed (Gtk::StateType old_state)
254 avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj()));
255 Button::on_state_changed (old_state);
259 StatefulButton::get_child_widget ()
265 StatefulButton::set_widget_name (const std::string& name)
268 Widget* w = get_child();