change CairoWidget API to be a more logical/intuitive for setting widget state, to differentiate between active state and visual state (prelight, insensitive etc)

git-svn-id: svn://localhost/ardour2/branches/3.0@10314 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-10-27 11:24:43 +00:00
parent 24765e8459
commit 892f3c361e
11 changed files with 80 additions and 90 deletions

View File

@ -26,8 +26,6 @@
#@color arm #F33
#@color solo #A8F730
#@color midi_channel_selector #A8F730
#@color isolate #B9ECF2
#@color solo_lock #3593DA
#@color mute #FFFA87
#@color mono #DEC
#@color monitor #FFAB34

View File

@ -26,8 +26,6 @@
#@color arm #F33
#@color solo #A8F730
#@color midi_channel_selector #A8F730
#@color isolate #B9ECF2
#@color solo_lock #3593DA
#@color mute #FFFA87
#@color mono #DEC
#@color monitor #7596DE

View File

@ -400,4 +400,3 @@ widget "*MeasureLatencyButton" style:highest "default_toggle_button"
widget "*processor prefader" style:highest "processor_prefader"
widget "*processor fader" style:highest "processor_fader"
widget "*processor postfader" style:highest "processor_postfader"
widget "*ProcessorFrameActiveSend" style:highest "processor_frame_active_send"

View File

@ -37,8 +37,6 @@ using namespace Gtk;
using namespace Glib;
using std::max;
using std::min;
using std::cerr;
using std::endl;
ArdourButton::ArdourButton()
: _text_width (0)
@ -54,6 +52,7 @@ ArdourButton::ArdourButton()
{
ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler));
StateChanged.connect (sigc::mem_fun (*this, &ArdourButton::state_handler));
}
ArdourButton::~ArdourButton()
@ -160,9 +159,8 @@ ArdourButton::render (cairo_t* cr)
}
void
ArdourButton::set_state (CairoWidget::State s, bool yn)
ArdourButton::state_handler ()
{
CairoWidget::set_state (s, yn);
set_colors ();
}
@ -222,7 +220,7 @@ ArdourButton::set_colors ()
}
edge_pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, _height);
if (_state & CairoWidget::Selected) {
if (visual_state() & CairoWidget::Selected) {
start_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 border start selected", get_name()));
end_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 border end selected", get_name()));
} else {
@ -242,10 +240,11 @@ ArdourButton::set_colors ()
}
fill_pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, _height);
if (_state & Mid) {
if (active_state() == Mid) {
start_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 fill start mid", get_name()));
end_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 fill end mid", get_name()));
} else if (_state & Active) {
} else if (active_state() == Active) {
start_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 fill start active", get_name()));
end_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 fill end active", get_name()));
} else {
@ -270,14 +269,14 @@ ArdourButton::set_colors ()
}
reflection_pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, _diameter/2-3);
cairo_pattern_add_color_stop_rgba (reflection_pattern, 0, 1,1,1, (_state & Active) ? 0.4 : 0.2);
cairo_pattern_add_color_stop_rgba (reflection_pattern, 0, 1,1,1, active_state() ? 0.4 : 0.2);
cairo_pattern_add_color_stop_rgba (reflection_pattern, 1, 1,1,1, 0.0);
/* text and LED colors depend on Active/Normal/Mid */
if (_state & Active) {
if (active_state() == Active) {
text_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 text active", get_name()));
led_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 led active", get_name()));
} else if (_state & Mid) {
} else if (active_state() == Mid) {
text_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 text mid", get_name()));
led_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 led active", get_name()));
} else {

View File

@ -42,8 +42,6 @@ class ArdourButton : public CairoWidget, Gtk::Activatable
sigc::signal<void> signal_clicked;
void set_state (State s, bool);
protected:
void render (cairo_t *);
void on_size_request (Gtk::Requisition* req);
@ -78,6 +76,7 @@ class ArdourButton : public CairoWidget, Gtk::Activatable
void set_colors ();
void color_handler ();
void state_handler ();
};
#endif /* __gtk2_ardour_ardour_button_h__ */

View File

@ -23,7 +23,8 @@
CairoWidget::CairoWidget ()
: _width (1)
, _height (1)
, _state (CairoWidget::State (0))
, _active_state (CairoWidget::ActiveState (0))
, _visual_state (CairoWidget::VisualState (0))
, _dirty (true)
, _pixmap (0)
@ -131,17 +132,19 @@ CairoWidget::get_parent_bg ()
}
void
CairoWidget::set_state (CairoWidget::State s, bool yn)
CairoWidget::set_active_state (CairoWidget::ActiveState s)
{
if (yn) {
if (!(_state & s)) {
_state = CairoWidget::State (_state|s);
StateChanged ();
}
} else {
if (_state & s) {
_state = CairoWidget::State (_state & ~s);
StateChanged ();
}
if (_active_state != s) {
_active_state = s;
StateChanged ();
}
}
void
CairoWidget::set_visual_state (CairoWidget::VisualState s)
{
if (_visual_state != s) {
_visual_state = s;
StateChanged ();
}
}

View File

@ -35,21 +35,29 @@ public:
void set_dirty ();
/* widget states: unlike GTK, these OR-together so that
a widget can be both Active *and* Selected, rather than
each one being orthogonal.
/* widget states: unlike GTK, visual states like "Selected" or "Prelight"
are orthogonal to active states.
*/
enum State {
Active = 0x1,
Mid = 0x2,
Selected = 0x4,
Prelight = 0x8,
Insensitive = 0x10,
enum ActiveState {
Active = 1,
Mid,
};
enum VisualState {
/* these can be OR-ed together */
Selected = 0x1,
Prelight = 0x2,
Insensitive = 0x4,
};
State state() const { return _state; }
virtual void set_state (State, bool);
ActiveState active_state() const { return _active_state; }
VisualState visual_state() const { return _visual_state; }
virtual void set_active_state (ActiveState);
virtual void set_visual_state (VisualState);
virtual void unset_active_state () { set_active_state (ActiveState (0)); }
virtual void unset_visual_state () { set_visual_state (VisualState (0)); }
sigc::signal<void> StateChanged;
protected:
@ -61,7 +69,8 @@ protected:
int _width; ///< pixmap width
int _height; ///< pixmap height
State _state;
ActiveState _active_state;
VisualState _visual_state;
private:
bool _dirty; ///< true if the pixmap requires re-rendering

View File

@ -28,9 +28,7 @@ using namespace Gtk;
using namespace Glib;
LED::LED()
: _visual_state (0)
, _active (false)
, _diameter (0.0)
: _diameter (0.0)
, _fixed_diameter (false)
, _red (0.0)
, _green (1.0)
@ -94,14 +92,14 @@ LED::render (cairo_t* cr)
cairo_fill(cr);
//knob color
cairo_set_source_rgba (cr, _red, _green, _blue, _active ? 0.8 : 0.2);
cairo_set_source_rgba (cr, _red, _green, _blue, (active_state() == Active) ? 0.8 : 0.2);
cairo_arc (cr, 0, 0, _diameter/2-3, 0, 2 * M_PI);
cairo_fill(cr);
//reflection
cairo_scale(cr, 0.7, 0.7);
cairo_pattern_t *pat2 = cairo_pattern_create_linear (0.0, 0.0, 0.0, _diameter/2-3);
cairo_pattern_add_color_stop_rgba (pat2, 0, 1,1,1, _active ? 0.4 : 0.2);
cairo_pattern_add_color_stop_rgba (pat2, 0, 1,1,1, active_state() ? 0.4 : 0.2);
cairo_pattern_add_color_stop_rgba (pat2, 1, 1,1,1, 0.0);
cairo_arc (cr, 0, 0, _diameter/2-3, 0, 2 * M_PI);
cairo_set_source (cr, pat2);
@ -111,24 +109,6 @@ LED::render (cairo_t* cr)
cairo_stroke (cr);
}
void
LED::set_active (bool yn)
{
_active = yn;
_visual_state = (yn ? 1 : 0);
set_colors_from_style ();
}
void
LED::set_visual_state (int32_t s)
{
if (s != _visual_state) {
_visual_state = s;
set_colors_from_style ();
}
}
void
LED::set_diameter (float d)
{

View File

@ -30,10 +30,6 @@ class LED : public CairoWidget
LED ();
virtual ~LED ();
void set_active (bool yn);
bool active () const { return _active; }
void set_visual_state (int32_t s);
int32_t visual_state() const { return _visual_state; }
void set_diameter (float);
protected:
@ -42,8 +38,6 @@ class LED : public CairoWidget
void on_realize ();
private:
int32_t _visual_state;
bool _active;
float _diameter;
bool _fixed_diameter;
float _red;

View File

@ -104,7 +104,9 @@ ProcessorEntry::ProcessorEntry (boost::shared_ptr<Processor> p, Width w)
_vbox.pack_start (_button, true, true);
_vbox.show ();
_button.set_state (CairoWidget::Active, _processor->active());
if (_processor->active()) {
_button.set_active_state (CairoWidget::Active);
}
_button.set_diameter (3);
_button.signal_clicked.connect (sigc::mem_fun (*this, &ProcessorEntry::led_clicked));
_button.set_text (name());
@ -149,17 +151,18 @@ ProcessorEntry::set_visual_state (Gtk::StateType t)
switch (t) {
case Gtk::STATE_ACTIVE:
_button.set_state (CairoWidget::Active, true);
_button.set_active_state (CairoWidget::Active);
_button.unset_visual_state ();
break;
case Gtk::STATE_SELECTED:
_button.set_state (CairoWidget::Selected, true);
_button.set_visual_state (CairoWidget::Selected);
break;
case Gtk::STATE_NORMAL:
default:
_button.set_state (CairoWidget::Selected, false);
_button.set_state (CairoWidget::Active, false);
_button.unset_visual_state ();
_button.unset_active_state ();
break;
}
}
@ -208,7 +211,11 @@ ProcessorEntry::led_clicked()
void
ProcessorEntry::processor_active_changed ()
{
_button.set_state (CairoWidget::Active, _processor->active());
if (_processor->active()) {
_button.set_active_state (CairoWidget::Active);
} else {
_button.unset_active_state ();
}
}
void

View File

@ -608,26 +608,22 @@ RouteUI::update_monitoring_display ()
MonitorState ms = t->monitoring_state();
if (t->monitoring_choice() & MonitorInput) {
monitor_input_button->set_state (CairoWidget::Active, true);
monitor_input_button->set_state (CairoWidget::Mid, false);
monitor_input_button->set_active_state (CairoWidget::Active);
} else {
if (ms & MonitoringInput) {
monitor_input_button->set_state (CairoWidget::Mid, true);
monitor_input_button->set_state (CairoWidget::Active, false);
monitor_input_button->set_active_state (CairoWidget::Mid);
} else {
monitor_input_button->set_state (CairoWidget::State (CairoWidget::Active|CairoWidget::Mid), false);
monitor_input_button->unset_active_state ();
}
}
if (t->monitoring_choice() & MonitorDisk) {
monitor_disk_button->set_state (CairoWidget::Active, true);
monitor_disk_button->set_state (CairoWidget::Mid, false);
monitor_disk_button->set_active_state (CairoWidget::Active);
} else {
if (ms & MonitoringDisk) {
monitor_disk_button->set_state (CairoWidget::Mid, true);
monitor_disk_button->set_state (CairoWidget::Active, false);
monitor_disk_button->set_active_state (CairoWidget::Mid);
} else {
monitor_disk_button->set_state (CairoWidget::State (CairoWidget::Active|CairoWidget::Mid), false);
monitor_disk_button->unset_active_state ();
}
}
}
@ -1066,11 +1062,19 @@ RouteUI::update_solo_display ()
set_button_names ();
if (solo_isolated_led) {
solo_isolated_led->set_state (CairoWidget::Active, _route->solo_isolated());
if (_route->solo_isolated()) {
solo_isolated_led->set_active_state (CairoWidget::Active);
} else {
solo_isolated_led->unset_active_state ();
}
}
if (solo_safe_led) {
solo_safe_led->set_state (CairoWidget::Active, _route->solo_safe());
if (_route->solo_safe()) {
solo_safe_led->set_active_state (CairoWidget::Active);
} else {
solo_safe_led->unset_active_state ();
}
}
solo_button->set_visual_state (solo_visual_state (_route));
@ -1340,7 +1344,7 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
return true;
}
bool view = (solo_isolated_led->state() & (CairoWidget::Active|CairoWidget::Mid));
bool view = solo_isolated_led->active_state();
bool model = _route->solo_isolated();
/* called BEFORE the view has changed */
@ -1371,7 +1375,7 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
bool
RouteUI::solo_safe_button_release (GdkEventButton*)
{
_route->set_solo_safe (!(solo_safe_led->state() & (CairoWidget::Active|CairoWidget::Mid)), this);
_route->set_solo_safe (!solo_safe_led->active_state(), this);
return true;
}