X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fgtkmm2ext%2Fstateful_button.cc;h=3c1ad2a830e92d3c0ab77c039b54b0fa740e251d;hb=235631a618de23793f0915aa7dc9b2f669b766f9;hp=949cae958b7bcfaa14102ec72853e80fd012c62c;hpb=666e0870554705f4fb466fc6b188fe9b4000ca49;p=ardour.git diff --git a/libs/gtkmm2ext/stateful_button.cc b/libs/gtkmm2ext/stateful_button.cc index 949cae958b..3c1ad2a830 100644 --- a/libs/gtkmm2ext/stateful_button.cc +++ b/libs/gtkmm2ext/stateful_button.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 Paul Davis + Copyright (C) 2000-2007 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ #include #include + #include #include @@ -30,9 +31,13 @@ using namespace Gtkmm2ext; using namespace std; StateButton::StateButton () + : visual_state (0) + , _self_managed (false) + , _is_realized (false) + , style_changing (false) + , state_before_prelight (Gtk::STATE_NORMAL) + , is_toggle (false) { - _is_realized = false; - visual_state = 0; } void @@ -56,19 +61,111 @@ StateButton::set_visual_state (int n) /* relax */ break; case 1: - name += "-active"; + name += "-active"; break; + case 2: name += "-alternate"; break; + + case 3: + name += "-alternate2"; + break; } set_widget_name (name); visual_state = n; } +void +StateButton::avoid_prelight_on_style_changed (const Glib::RefPtr& /* old_style */, GtkWidget* widget) +{ + /* don't go into an endless recursive loop if we're changing + the style in response to an existing style change. + */ + + if (style_changing) { + return; + } + + if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT) { + + /* avoid PRELIGHT: make sure that the prelight colors in this new style match + the colors of the new style in whatever state we were in + before we switched to prelight. + */ + + GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget); + GtkStyle* style = gtk_widget_get_style (widget); + + rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[state_before_prelight]; + rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[state_before_prelight]; + rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG); + + style_changing = true; + g_object_ref (rcstyle); + gtk_widget_modify_style (widget, rcstyle); + + Widget* child = get_child_widget(); + if (child) { + gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle); + } + + + g_object_unref (rcstyle); + style_changing = false; + } +} + +void +StateButton::avoid_prelight_on_state_changed (Gtk::StateType old_state, GtkWidget* widget) +{ + GtkStateType state = gtk_widget_get_state (widget); + + if (state == GTK_STATE_PRELIGHT) { + + state_before_prelight = old_state; + + + /* avoid PRELIGHT when currently ACTIVE: + if we just went into PRELIGHT, make sure that the colors + match those of whatever state we were in before. + */ + + GtkRcStyle* rcstyle = gtk_widget_get_modifier_style (widget); + GtkStyle* style = gtk_widget_get_style (widget); + + rcstyle->fg[GTK_STATE_PRELIGHT] = style->fg[old_state]; + rcstyle->bg[GTK_STATE_PRELIGHT] = style->bg[old_state]; + rcstyle->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (GTK_RC_FG|GTK_RC_BG); + + g_object_ref (rcstyle); + gtk_widget_modify_style (widget, rcstyle); + + Widget* child = get_child_widget (); + + if (child) { + gtk_widget_modify_style (GTK_WIDGET(child->gobj()), rcstyle); + } + + g_object_unref (rcstyle); + + } +} + /* ----------------------------------------------------------------- */ +StatefulToggleButton::StatefulToggleButton () +{ + is_toggle = true; +} + +StatefulToggleButton::StatefulToggleButton (const std::string& label) + : ToggleButton (label) +{ + is_toggle = true; +} + void StatefulToggleButton::on_realize () { @@ -94,9 +191,83 @@ StatefulToggleButton::on_toggled () { if (!_self_managed) { if (get_active()) { - set_visual_state (1); + set_state (Gtk::STATE_ACTIVE); } else { - set_visual_state (0); + set_state (Gtk::STATE_NORMAL); } } } + + +void +StatefulToggleButton::on_style_changed (const Glib::RefPtr& style) +{ + avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj())); + Button::on_style_changed (style); +} + +void +StatefulToggleButton::on_state_changed (Gtk::StateType old_state) +{ + avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj())); + Button::on_state_changed (old_state); +} + +Widget* +StatefulToggleButton::get_child_widget () +{ + return get_child(); +} + +void +StatefulToggleButton::set_widget_name (const std::string& name) +{ + set_name (name); + Widget* w = get_child(); + + if (w) { + w->set_name (name); + } +} + +/*--------------------------------------------- */ + +StatefulButton::StatefulButton () +{ +} + +StatefulButton::StatefulButton (const std::string& label) + : Button (label) +{ +} + +void +StatefulButton::on_style_changed (const Glib::RefPtr& style) +{ + avoid_prelight_on_style_changed (style, GTK_WIDGET(gobj())); + Button::on_style_changed (style); +} + +void +StatefulButton::on_state_changed (Gtk::StateType old_state) +{ + avoid_prelight_on_state_changed (old_state, GTK_WIDGET(gobj())); + Button::on_state_changed (old_state); +} + +Widget* +StatefulButton::get_child_widget () +{ + return get_child(); +} + +void +StatefulButton::set_widget_name (const std::string& name) +{ + set_name (name); + Widget* w = get_child(); + + if (w) { + w->set_name (name); + } +}