summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-10-26 21:01:14 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-10-26 21:01:14 +0000
commit51ab5ccabf432540ca935065f6c6f40a96f42dad (patch)
treea5f062738bcedc33cd55b176168d532e4cc6d189
parentae3eb6e3f4f270a03ff297d1bbe7cd3f3a2159a9 (diff)
new ArdourButton class, to start to provide more control over how our buttons work and appear; use ArdourButtons for monitor, solo isolate and solo safe buttons, and in the processor box; don't save UI config file (canvas colors) to the user's home dir unless one or more parameters were modified by the user
git-svn-id: svn://localhost/ardour2/branches/3.0@10311 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour3_styles.rc.in138
-rw-r--r--gtk2_ardour/ardour3_ui_dark.rc.in3
-rw-r--r--gtk2_ardour/ardour3_ui_default.conf96
-rw-r--r--gtk2_ardour/ardour3_ui_light.rc.in1
-rw-r--r--gtk2_ardour/ardour3_widget_list.rc27
-rw-r--r--gtk2_ardour/ardour_button.cc375
-rw-r--r--gtk2_ardour/ardour_button.h83
-rw-r--r--gtk2_ardour/ardour_ui_dependents.cc4
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc4
-rw-r--r--gtk2_ardour/cairo_widget.cc44
-rw-r--r--gtk2_ardour/cairo_widget.h19
-rw-r--r--gtk2_ardour/canvas_vars.h25
-rw-r--r--gtk2_ardour/led.cc17
-rw-r--r--gtk2_ardour/led.h2
-rw-r--r--gtk2_ardour/mixer_strip.cc108
-rw-r--r--gtk2_ardour/mixer_strip.h6
-rw-r--r--gtk2_ardour/processor_box.cc118
-rw-r--r--gtk2_ardour/processor_box.h15
-rw-r--r--gtk2_ardour/route_time_axis.cc10
-rw-r--r--gtk2_ardour/route_ui.cc55
-rw-r--r--gtk2_ardour/route_ui.h12
-rw-r--r--gtk2_ardour/theme_manager.cc11
-rw-r--r--gtk2_ardour/ui_config.cc53
-rw-r--r--gtk2_ardour/ui_config.h9
-rw-r--r--gtk2_ardour/wscript1
25 files changed, 883 insertions, 353 deletions
diff --git a/gtk2_ardour/ardour3_styles.rc.in b/gtk2_ardour/ardour3_styles.rc.in
index 634768e6f6..3b3ff039bf 100644
--- a/gtk2_ardour/ardour3_styles.rc.in
+++ b/gtk2_ardour/ardour3_styles.rc.in
@@ -148,52 +148,16 @@ style "mixer_track_rec_enable_button_active" = "track_rec_enable_button_active"
ythickness = 0
}
-style "monitor_input_button" = "small_button"
+style "monitor" = "small_button"
{
- fg[NORMAL] = darker(@@COLPREFIX@_fg)
- fg[PRELIGHT] = darker(@@COLPREFIX@_fg)
- bg[NORMAL] = mix(0.1,@@COLPREFIX@_monitor,darker(@@COLPREFIX@_bg))
- bg[PRELIGHT] = mix(0.1,@@COLPREFIX@_somewhat_bright_indicator,darker(@@COLPREFIX@_bg))
}
-style "monitor_input_button_active" = "small_button"
+style "solo_isolate" = "very_small_text"
{
- fg[NORMAL] = @@COLPREFIX@_fg
- fg[PRELIGHT] = @@COLPREFIX@_fg
- bg[NORMAL] = mix (0.8, @@COLPREFIX@_monitor, darker (@@COLPREFIX@_bg))
- bg[PRELIGHT] = mix (0.8, @@COLPREFIX@_monitor, darker (@@COLPREFIX@_bg))
}
-style "monitor_input_button_alternate" = "small_button"
+style "solo_safe" = "very_small_text"
{
- fg[NORMAL] = @@COLPREFIX@_fg
- fg[PRELIGHT] = @@COLPREFIX@_fg
- bg[NORMAL] = mix(0.5,@@COLPREFIX@_monitor,darker(@@COLPREFIX@_bg))
- bg[PRELIGHT] = mix(0.5,@@COLPREFIX@_monitor,darker(@@COLPREFIX@_bg))
-}
-
-style "monitor_disk_button" = "small_button"
-{
- fg[NORMAL] = darker(@@COLPREFIX@_fg)
- fg[PRELIGHT] = darker(@@COLPREFIX@_fg)
- bg[NORMAL] = mix(0.1,@@COLPREFIX@_monitor,darker(@@COLPREFIX@_bg))
- bg[PRELIGHT] = mix(0.1,@@COLPREFIX@_monitor,darker(@@COLPREFIX@_bg))
-}
-
-style "monitor_disk_button_active" = "small_button"
-{
- fg[NORMAL] = @@COLPREFIX@_fg
- fg[PRELIGHT] = @@COLPREFIX@_fg
- bg[NORMAL] = @@COLPREFIX@_monitor
- bg[PRELIGHT] = @@COLPREFIX@_monitor
-}
-
-style "monitor_disk_button_alternate" = "small_button"
-{
- fg[NORMAL] = @@COLPREFIX@_fg
- fg[PRELIGHT] = @@COLPREFIX@_fg
- bg[NORMAL] = mix(0.5,@@COLPREFIX@_monitor,darker(@@COLPREFIX@_bg))
- bg[PRELIGHT] = mix(0.5,@@COLPREFIX@_monitor,darker(@@COLPREFIX@_bg))
}
style "solo_button" = "small_button"
@@ -203,18 +167,6 @@ style "solo_button" = "small_button"
fg[ACTIVE] = @@COLPREFIX@_darkest
}
-style "solo_isolate_led"
-{
- fg[NORMAL] = mix(0.2,@@COLPREFIX@_isolate, @@COLPREFIX@_darkest)
- fg[ACTIVE] = @@COLPREFIX@_isolate
-}
-
-style "solo_safe_led"
-{
- fg[NORMAL] = mix(0.2,@@COLPREFIX@_isolate, @@COLPREFIX@_darkest)
- fg[ACTIVE] = @@COLPREFIX@_isolate
-}
-
style "solo_button_alternate" = "small_button"
{
#
@@ -263,6 +215,10 @@ style "solo_button_active" = "small_button"
fg[PRELIGHT] = @@COLPREFIX@_darkest
}
+style "processor" = "small_text"
+{
+}
+
style "mixer_invert_button" = "small_button"
{
bg[ACTIVE] = @@COLPREFIX@_not_so_bright_indicator
@@ -294,42 +250,6 @@ style "mixer_solo_button_active" = "solo_button_active"
ythickness = 0
}
-style "mixer_monitor_input" = "monitor_input_button"
-{
- xthickness = 0
- ythickness = 0
-}
-
-style "mixer_monitor_input_active" = "monitor_input_button_active"
-{
- xthickness = 0
- ythickness = 0
-}
-
-style "mixer_monitor_input_alternate" = "monitor_input_button_alternate"
-{
- xthickness = 0
- ythickness = 0
-}
-
-style "mixer_monitor_disk" = "monitor_disk_button"
-{
- xthickness = 0
- ythickness = 0
-}
-
-style "mixer_monitor_disk_active" = "monitor_disk_button_active"
-{
- xthickness = 0
- ythickness = 0
-}
-
-style "mixer_monitor_disk_alternate" = "monitor_disk_button_alternate"
-{
- xthickness = 0
- ythickness = 0
-}
-
style "monitor_opt_button" = "small_button"
{
bg[NORMAL] = mix(0.1,@@COLPREFIX@_not_so_bright_indicator,@@COLPREFIX@_bg)
@@ -985,14 +905,6 @@ style "processor_list" = "very_small_text"
bg[NORMAL] = @@COLPREFIX@_darkest
bg[ACTIVE] = shade (1.8, @@COLPREFIX@_fg_selected)
fg[ACTIVE] = @@COLPREFIX@_darkest
- GtkCheckButton::indicator-size = 10
- GtkCheckButton::indicator-spacing = 0
-}
-
-# Colour of a processor frame when it is selected
-style "processor_frame_selected"
-{
- bg[NORMAL] = @@COLPREFIX@_fg_selected
}
# Colour of a processor frame when it is a send whose level is being controller by the fader
@@ -1001,42 +913,6 @@ style "processor_frame_active_send"
bg[NORMAL] = @@COLPREFIX@_send_fg
}
-# Fader processor's background
-style "processor_fader"
-{
- bg[NORMAL] = @@COLPREFIX@_processor_fader_bg
-}
-
-# Fader processor's frame
-style "processor_fader_frame"
-{
-bg[NORMAL] = @@COLPREFIX@_processor_fader_frame
-}
-
-# Pre-fader processor's background
-style "processor_prefader"
-{
- bg[NORMAL] = @@COLPREFIX@_processor_prefader
-}
-
-# Pre-fader processor's frame
-style "processor_prefader_frame"
-{
- bg[NORMAL] = @@COLPREFIX@_processor_prefader_frame
-}
-
-# Post-fader processor's background
-style "processor_postfader"
-{
- bg[NORMAL] = @@COLPREFIX@_processor_postfader
-}
-
-# Post-fader processor's frame
-style "processor_postfader_frame"
-{
- bg[NORMAL] = @@COLPREFIX@_processor_postfader_frame
-}
-
# MixerPanZone:
#
# the NORMAL fg color is used for the pan puck
diff --git a/gtk2_ardour/ardour3_ui_dark.rc.in b/gtk2_ardour/ardour3_ui_dark.rc.in
index 05865b11d5..2ad1d7c5d4 100644
--- a/gtk2_ardour/ardour3_ui_dark.rc.in
+++ b/gtk2_ardour/ardour3_ui_dark.rc.in
@@ -27,6 +27,7 @@
#@color solo #A8F730
#@color midi_channel_selector #A8F730
#@color isolate #B9ECF2
+#@color solo_lock #3593DA
#@color mute #FFFA87
#@color mono #DEC
#@color monitor #FFAB34
@@ -41,7 +42,7 @@
#@color send_bg #C4C4B8
#@color processor_frame_selected #E2CC33
-#@color processor_fader_bg #666666
+#@color processor_fader #666666
#@color processor_fader_frame #7F7F7F
#@color processor_prefader #4D0000
#@color processor_prefader_frame #7F0000
diff --git a/gtk2_ardour/ardour3_ui_default.conf b/gtk2_ardour/ardour3_ui_default.conf
index 196bb89710..770b9156fa 100644
--- a/gtk2_ardour/ardour3_ui_default.conf
+++ b/gtk2_ardour/ardour3_ui_default.conf
@@ -142,5 +142,101 @@
<Option name="waveform fill" value="3d4753dc"/>
<Option name="zero line" value="b5b5b525"/>
<Option name="zoom rect" value="c6d1b26d"/>
+ <Option name="processor prefader border start" value="630a0aff"/>
+ <Option name="processor prefader border end" value="630a0aff"/>
+ <Option name="processor prefader border start selected" value="edc400ff"/>
+ <Option name="processor prefader border end selected" value="ffd300ff"/>
+ <Option name="processor prefader fill start" value="873c3cff"/>
+ <Option name="processor prefader fill end" value="542525ff"/>
+ <Option name="processor prefader fill start active" value="873c3cff"/>
+ <Option name="processor prefader fill end active" value="542525ff"/>
+ <Option name="processor prefader fill start mid" value="873c3cff"/>
+ <Option name="processor prefader fill end mid" value="542525ff"/>
+ <Option name="processor prefader led" value="26550eff"/>
+ <Option name="processor prefader led active" value="78cb4eff"/>
+ <Option name="processor prefader led mid" value="26550eff"/>
+ <Option name="processor prefader text" value="aaaaa3ff"/>
+ <Option name="processor prefader text active" value="eeeeecff"/>
+ <Option name="processor prefader text mid" value="aaaaa3ff"/>
+ <Option name="processor fader border start" value="7cb5d9ff"/>
+ <Option name="processor fader border end" value="6493b0ff"/>
+ <Option name="processor fader border start selected" value="cdfaf8ff"/>
+ <Option name="processor fader border end selected" value="c0ebe9ff"/>
+ <Option name="processor fader fill start" value="5d90b0ff"/>
+ <Option name="processor fader fill end" value="154c6eff"/>
+ <Option name="processor fader fill start active" value="5d90b0ff"/>
+ <Option name="processor fader fill end active" value="154d6fff"/>
+ <Option name="processor fader fill start mid" value="5d90b0ff"/>
+ <Option name="processor fader fill end mid" value="154d6fff"/>
+ <Option name="processor fader led" value="26550eff"/>
+ <Option name="processor fader led active" value="78cb4eff"/>
+ <Option name="processor fader led mid" value="26550eff"/>
+ <Option name="processor fader text" value="aaaaa3ff"/>
+ <Option name="processor fader text active" value="eeeeecff"/>
+ <Option name="processor fader text mid" value="aaaaa3ff"/>
+ <Option name="processor postfader border start" value="1d631dff"/>
+ <Option name="processor postfader border end" value="1d631dff"/>
+ <Option name="processor postfader border start selected" value="46f046ff"/>
+ <Option name="processor postfader border end selected" value="46f046ff"/>
+ <Option name="processor postfader fill start" value="415947ff"/>
+ <Option name="processor postfader fill end" value="405945ff"/>
+ <Option name="processor postfader fill start active" value="415947ff"/>
+ <Option name="processor postfader fill end active" value="405945ff"/>
+ <Option name="processor postfader fill start mid" value="415947ff"/>
+ <Option name="processor postfader fill end mid" value="405945ff"/>
+ <Option name="processor postfader led" value="26550eff"/>
+ <Option name="processor postfader led active" value="78cb4eff"/>
+ <Option name="processor postfader led mid" value="26550eff"/>
+ <Option name="processor postfader text" value="aaaaa3ff"/>
+ <Option name="processor postfader text active" value="eeeeecff"/>
+ <Option name="processor postfader text mid" value="aaaaa3ff"/>
+ <Option name="monitor border start" value="9a908eff"/>
+ <Option name="monitor border end" value="675c5bff"/>
+ <Option name="monitor border start selected" value="46f046ff"/>
+ <Option name="monitor border end selected" value="46f046ff"/>
+ <Option name="monitor fill start" value="5d5856ff"/>
+ <Option name="monitor fill end" value="564d48ff"/>
+ <Option name="monitor fill start active" value="d3704fff"/>
+ <Option name="monitor fill end active" value="c58c41ff"/>
+ <Option name="monitor fill start mid" value="b25e42ff"/>
+ <Option name="monitor fill end mid" value="665646ff"/>
+ <Option name="monitor led" value="26550eff"/>
+ <Option name="monitor led active" value="78cb4eff"/>
+ <Option name="monitor led mid" value="26550eff"/>
+ <Option name="monitor text" value="aaaaa3ff"/>
+ <Option name="monitor text active" value="5d5a5bff"/>
+ <Option name="monitor text mid" value="aaaaa3ff"/>
+ <Option name="solo isolate border start" value="bbeff5ff"/>
+ <Option name="solo isolate border end" value="0041ddff"/>
+ <Option name="solo isolate border start selected" value="46f046ff"/>
+ <Option name="solo isolate border end selected" value="46f046ff"/>
+ <Option name="solo isolate fill start" value="475c5eff"/>
+ <Option name="solo isolate fill end" value="3e4f51ff"/>
+ <Option name="solo isolate fill start active" value="637f82ff"/>
+ <Option name="solo isolate fill end active" value="5b7577ff"/>
+ <Option name="solo isolate fill start mid" value="51686bff"/>
+ <Option name="solo isolate fill end mid" value="475c5eff"/>
+ <Option name="solo isolate led" value="3e4f51ff"/>
+ <Option name="solo isolate led active" value="9ff837ff"/>
+ <Option name="solo isolate led mid" value="6daa25ff"/>
+ <Option name="solo isolate text" value="e3e3d9ff"/>
+ <Option name="solo isolate text active" value="e3e3d9ff"/>
+ <Option name="solo isolate text mid" value="e3e3d9ff"/>
+ <Option name="solo safe border start" value="94e833ff"/>
+ <Option name="solo safe border end" value="54841cff"/>
+ <Option name="solo safe border start selected" value="3ca5f5ff"/>
+ <Option name="solo safe border end selected" value="2a75adff"/>
+ <Option name="solo safe fill start" value="536b6dff"/>
+ <Option name="solo safe fill end" value="3c5e13ff"/>
+ <Option name="solo safe fill start active" value="619921ff"/>
+ <Option name="solo safe fill end active" value="55841dff"/>
+ <Option name="solo safe fill start mid" value="5b7577ff"/>
+ <Option name="solo safe fill end mid" value="506568ff"/>
+ <Option name="solo safe led" value="477018ff"/>
+ <Option name="solo safe led active" value="9ff837ff"/>
+ <Option name="solo safe led mid" value="6daa25ff"/>
+ <Option name="solo safe text" value="e2e2d8ff"/>
+ <Option name="solo safe text active" value="e3e3d9ff"/>
+ <Option name="solo safe text mid" value="e3e3d9ff"/>
</Canvas>
</Ardour>
diff --git a/gtk2_ardour/ardour3_ui_light.rc.in b/gtk2_ardour/ardour3_ui_light.rc.in
index 20d16ef2f2..b4501e89de 100644
--- a/gtk2_ardour/ardour3_ui_light.rc.in
+++ b/gtk2_ardour/ardour3_ui_light.rc.in
@@ -27,6 +27,7 @@
#@color solo #A8F730
#@color midi_channel_selector #A8F730
#@color isolate #B9ECF2
+#@color solo_lock #3593DA
#@color mute #FFFA87
#@color mono #DEC
#@color monitor #7596DE
diff --git a/gtk2_ardour/ardour3_widget_list.rc b/gtk2_ardour/ardour3_widget_list.rc
index 9f0a3c0393..8daf1c2cee 100644
--- a/gtk2_ardour/ardour3_widget_list.rc
+++ b/gtk2_ardour/ardour3_widget_list.rc
@@ -78,15 +78,7 @@ widget "*MixerSoloButton" style:highest "mixer_solo_button"
widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate"
widget "*MixerSoloButton-alternate2" style:highest "mixer_solo_button_alternate2"
widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active"
-
-widget "*MixerMonitorInputButton" style:highest "mixer_monitor_input"
-widget "*MixerMonitorInputButton-active" style:highest "mixer_monitor_input_active"
-widget "*MixerMonitorInputButton-alternate" style:highest "mixer_monitor_input_alternate"
-
-widget "*MixerMonitorDiskButton" style:highest "mixer_monitor_disk"
-widget "*MixerMonitorDiskButton-active" style:highest "mixer_monitor_disk_active"
-widget "*MixerMonitorDiskButton-alternate" style:highest "mixer_monitor_disk_alternate"
-
+widget "*monitor" style:highest "monitor"
widget "*TrackLoopButton*" style:highest "track_loop_button"
widget "*PanAutomationLineSelector*" style:highest "multiline_combo"
widget "*EditorTimeButton*" style:highest "time_button"
@@ -386,19 +378,10 @@ widget "*RegionListWholeFile" style:highest "treeview_parent_node"
widget "*EditorHScrollbar" style:highest "editor_hscrollbar"
widget "*MidiListView*" style:highest "treeview_display"
widget "*ProcessorList*" style:highest "processor_list"
-widget "*ProcessorFrameSelected" style:highest "processor_frame_selected"
-widget "*ProcessorFrameActiveSend" style:highest "processor_frame_active_send"
-widget "*ProcessorFaderFrame" style:highest "processor_fader_frame"
-widget "*ProcessorPreFader" style:highest "processor_prefader"
-widget "*ProcessorPreFaderFrame" style:highest "processor_prefader_frame"
-widget "*ProcessorFader" style:highest "processor_fader"
-widget "*ProcessorPostFader" style:highest "processor_postfader"
-widget "*ProcessorPostFaderFrame" style:highest "processor_postfader_frame"
widget "*PortMatrixLabel*" style:highest "small_text"
widget "*MidiTracerTextView" style:highest "midi_tracer_textview"
-widget "*SoloIsolatedLED" style:highest "solo_isolate_led"
-widget "*SoloSafeLED" style:highest "solo_safe_led"
-widget "*SoloLEDLabel" style:highest "very_small_text"
+widget "*solo isolate" style:highest "solo_isolate"
+widget "*solo safe" style:highest "solo_safe"
widget "*ContrastingPopup" style:highest "contrasting_popup"
widget "*ContrastingPopup*" style:highest "contrasting_popup"
widget "*MidiChannelSelectorButton" style:highest "midi_channel_selector_button"
@@ -414,3 +397,7 @@ widget "*InsertTimeClock" style:highest "default_clock_display"
widget "*EditorRouteGroupsAllGroupButton" style:highest "default_toggle_button"
widget "*MidiSoundNotesButton" style:highest "default_toggle_button"
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"
diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc
new file mode 100644
index 0000000000..042e5fae71
--- /dev/null
+++ b/gtk2_ardour/ardour_button.cc
@@ -0,0 +1,375 @@
+/*
+ Copyright (C) 2010 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <iostream>
+#include <cmath>
+#include <algorithm>
+
+#include <pangomm/layout.h>
+
+#include "pbd/compose.h"
+
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/rgb_macros.h"
+
+#include "ardour_button.h"
+#include "ardour_ui.h"
+#include "global_signals.h"
+
+using namespace Gdk;
+using namespace Gtk;
+using namespace Glib;
+using std::max;
+using std::min;
+using std::cerr;
+using std::endl;
+
+ArdourButton::ArdourButton()
+ : _text_width (0)
+ , _text_height (0)
+ , _led_left (false)
+ , _diameter (0.0)
+ , _fixed_diameter (false)
+ , _distinct_led_click (true)
+ , edge_pattern (0)
+ , fill_pattern (0)
+ , led_inset_pattern (0)
+ , reflection_pattern (0)
+
+{
+ ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler));
+}
+
+ArdourButton::~ArdourButton()
+{
+}
+
+void
+ArdourButton::set_text (const std::string& str)
+{
+ _text = str;
+
+ if (!_layout && !_text.empty()) {
+ _layout = Pango::Layout::create (get_pango_context());
+ }
+
+ _layout->set_text (str);
+
+ queue_resize ();
+}
+
+void
+ArdourButton::set_markup (const std::string& str)
+{
+ _text = str;
+
+ if (!_layout) {
+ _layout = Pango::Layout::create (get_pango_context());
+ }
+
+ _layout->set_text (str);
+ queue_resize ();
+}
+
+void
+ArdourButton::render (cairo_t* cr)
+{
+ if (!_fixed_diameter) {
+ _diameter = std::min (_width, _height);
+ }
+
+ /* background fill. use parent window style, so that we fit in nicely.
+ */
+
+ Color c = get_parent_bg ();
+
+ cairo_rectangle (cr, 0, 0, _width, _height);
+ cairo_stroke_preserve (cr);
+ cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p());
+ cairo_fill (cr);
+
+ /* edge */
+
+ Gtkmm2ext::rounded_rectangle (cr, 0, 0, _width, _height, 9);
+ cairo_set_source (cr, edge_pattern);
+ cairo_fill (cr);
+
+ /* button itself: leaves 1 pixel border of the edge visible all around. */
+
+ Gtkmm2ext::rounded_rectangle (cr, 1, 1, _width-2, _height-2, 9);
+ cairo_set_source (cr, fill_pattern);
+ cairo_fill (cr);
+
+ /* text, if any */
+
+ if (!_text.empty()) {
+ cairo_set_source_rgba (cr, text_r, text_g, text_b, text_a);
+ if (_led_left) {
+ cairo_move_to (cr, _diameter + 3 + 4, _height/2.0 - _text_height/2.0);
+ } else {
+ cairo_move_to (cr, 3, _height/2.0 - _text_height/2.0);
+ }
+ pango_cairo_show_layout (cr, _layout->gobj());
+ }
+
+ /* move to the center of the ArdourButton itself */
+
+ if (_led_left) {
+ cairo_translate (cr, 3 + (_diameter/2.0), _height/2.0);
+ } else {
+ cairo_translate (cr, _width - ((_diameter/2.0) + 4.0), _height/2.0);
+ }
+
+ //inset
+ cairo_arc (cr, 0, 0, _diameter/2, 0, 2 * M_PI);
+ cairo_set_source (cr, led_inset_pattern);
+ cairo_fill (cr);
+
+ //black ring
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_arc (cr, 0, 0, _diameter/2-2, 0, 2 * M_PI);
+ cairo_fill(cr);
+
+ //led color
+ cairo_set_source_rgba (cr, led_r, led_g, led_b, led_a);
+ cairo_arc (cr, 0, 0, _diameter/2-3, 0, 2 * M_PI);
+ cairo_fill(cr);
+
+ //reflection
+ cairo_scale(cr, 0.7, 0.7);
+ cairo_arc (cr, 0, 0, _diameter/2-3, 0, 2 * M_PI);
+ cairo_set_source (cr, reflection_pattern);
+ cairo_fill (cr);
+ cairo_stroke (cr); // ??
+}
+
+void
+ArdourButton::set_state (CairoWidget::State s, bool yn)
+{
+ CairoWidget::set_state (s, yn);
+ set_colors ();
+}
+
+void
+ArdourButton::set_diameter (float d)
+{
+ _diameter = (d*2) + 5.0;
+
+ if (_diameter != 0.0) {
+ _fixed_diameter = true;
+ }
+
+ set_dirty ();
+}
+
+void
+ArdourButton::on_realize ()
+{
+ set_colors ();
+ CairoWidget::on_realize ();
+}
+
+void
+ArdourButton::on_size_request (Gtk::Requisition* req)
+{
+ int xpad = 0;
+ int ypad = 6;
+
+ if (!_text.empty()) {
+ _layout->get_pixel_size (_text_width, _text_height);
+ xpad += 6;
+ }
+
+ if (_fixed_diameter) {
+ req->width = _text_width + (int) _diameter + xpad;
+ req->height = max (_text_height, (int) _diameter) + ypad;
+ } else {
+ CairoWidget::on_size_request (req);
+ }
+}
+
+void
+ArdourButton::set_colors ()
+{
+ uint32_t start_color;
+ uint32_t end_color;
+ uint32_t r, g, b, a;
+ uint32_t text_color;
+ uint32_t led_color;
+
+ /* we use the edge of the button to show Selected state, so the
+ * color/pattern used there will vary depending on that
+ */
+
+ if (edge_pattern) {
+ cairo_pattern_destroy (edge_pattern);
+ }
+
+ edge_pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, _height);
+ if (_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 {
+ start_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 border start", get_name()));
+ end_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 border end", get_name()));
+ }
+ UINT_TO_RGBA (start_color, &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgba (edge_pattern, 0, r/255.0,g/255.0,b/255.0, 0.7);
+ UINT_TO_RGBA (end_color, &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgba (edge_pattern, 1, r/255.0,g/255.0,b/255.0, 0.7);
+
+ /* the fill pattern is used to indicate Normal/Active/Mid state
+ */
+
+ if (fill_pattern) {
+ cairo_pattern_destroy (fill_pattern);
+ }
+
+ fill_pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, _height);
+ if (_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) {
+ 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 {
+ start_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 fill start", get_name()));
+ end_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 fill end", get_name()));
+ }
+ UINT_TO_RGBA (start_color, &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgba (fill_pattern, 0, r/255.0,g/255.0,b/255.0, a/255.0);
+ UINT_TO_RGBA (end_color, &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgba (fill_pattern, 1, r/255.0,g/255.0,b/255.0, a/255.0);
+
+ if (led_inset_pattern) {
+ cairo_pattern_destroy (led_inset_pattern);
+ }
+
+ led_inset_pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, _diameter);
+ cairo_pattern_add_color_stop_rgba (led_inset_pattern, 0, 0,0,0, 0.4);
+ cairo_pattern_add_color_stop_rgba (led_inset_pattern, 1, 1,1,1, 0.7);
+
+ if (reflection_pattern) {
+ cairo_pattern_destroy (reflection_pattern);
+ }
+
+ 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, 1, 1,1,1, 0.0);
+
+ /* text and LED colors depend on Active/Normal/Mid */
+ if (_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) {
+ 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 {
+ text_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 text", get_name()));
+ led_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 led", get_name()));
+ }
+
+ UINT_TO_RGBA (text_color, &r, &g, &b, &a);
+ text_r = r/255.0;
+ text_g = g/255.0;
+ text_b = b/255.0;
+ text_a = a/255.0;
+ UINT_TO_RGBA (led_color, &r, &g, &b, &a);
+ led_r = r/255.0;
+ led_g = g/255.0;
+ led_b = b/255.0;
+ led_a = a/255.0;
+
+ set_dirty ();
+}
+
+void
+ArdourButton::set_led_left (bool yn)
+{
+ _led_left = yn;
+}
+
+bool
+ArdourButton::on_button_press_event (GdkEventButton *ev)
+{
+ if (_distinct_led_click) {
+ /* if within LED, swallow event */
+
+ int top = lrint (_height/2.0 - _diameter/2.0);
+ int bottom = lrint (_height/2.0 + _diameter/2.0);
+ int left;
+ int right;
+
+ if (_led_left) {
+ left = 4;
+ right = left + _diameter;
+ } else {
+ left = lrint (_width - 4 - _diameter/2.0);
+ right = left + _diameter;
+ }
+
+ if (ev->x >= left && ev->x <= right && ev->y <= bottom && ev->y >= top) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+ArdourButton::on_button_release_event (GdkEventButton *ev)
+{
+
+ if (_distinct_led_click) {
+
+ /* if within LED, emit signal */
+
+ int top = lrint (_height/2.0 - _diameter/2.0);
+ int bottom = lrint (_height/2.0 + _diameter/2.0);
+ int left;
+ int right;
+ if (_led_left) {
+ left = 4;
+ right = left + _diameter;
+ } else {
+ left = lrint (_width - 4 - _diameter/2.0);
+ right = left + _diameter;
+ }
+
+ if (ev->x >= left && ev->x <= right && ev->y <= bottom && ev->y >= top) {
+ signal_clicked(); /* EMIT SIGNAL */
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+ArdourButton::set_distinct_led_click (bool yn)
+{
+ _distinct_led_click = yn;
+}
+
+void
+ArdourButton::color_handler ()
+{
+ set_colors ();
+ set_dirty ();
+}
diff --git a/gtk2_ardour/ardour_button.h b/gtk2_ardour/ardour_button.h
new file mode 100644
index 0000000000..a499f60b3a
--- /dev/null
+++ b/gtk2_ardour/ardour_button.h
@@ -0,0 +1,83 @@
+/*
+ Copyright (C) 2010 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __gtk2_ardour_ardour_button_h__
+#define __gtk2_ardour_ardour_button_h__
+
+#include <stdint.h>
+
+#include <gtkmm/activatable.h>
+
+#include "cairo_widget.h"
+
+class ArdourButton : public CairoWidget, Gtk::Activatable
+{
+ public:
+ ArdourButton ();
+ virtual ~ArdourButton ();
+
+ void set_diameter (float);
+
+ void set_text (const std::string&);
+ void set_markup (const std::string&);
+
+ void set_led_left (bool yn);
+ void set_distinct_led_click (bool yn);
+
+ sigc::signal<void> signal_clicked;
+
+ void set_state (State s, bool);
+
+ protected:
+ void render (cairo_t *);
+ void on_size_request (Gtk::Requisition* req);
+ void on_realize ();
+ bool on_button_press_event (GdkEventButton*);
+ bool on_button_release_event (GdkEventButton*);
+
+ private:
+ Glib::RefPtr<Pango::Layout> _layout;
+ std::string _text;
+ int _text_width;
+ int _text_height;
+ bool _led_left;
+ float _diameter;
+ bool _fixed_diameter;
+ bool _distinct_led_click;
+
+ cairo_pattern_t* edge_pattern;
+ cairo_pattern_t* fill_pattern;
+ cairo_pattern_t* led_inset_pattern;
+ cairo_pattern_t* reflection_pattern;
+
+ double text_r;
+ double text_g;
+ double text_b;
+ double text_a;
+
+ double led_r;
+ double led_g;
+ double led_b;
+ double led_a;
+
+ void set_colors ();
+ void color_handler ();
+};
+
+#endif /* __gtk2_ardour_ardour_button_h__ */
diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc
index 3f819829b9..937ba5ab81 100644
--- a/gtk2_ardour/ardour_ui_dependents.cc
+++ b/gtk2_ardour/ardour_ui_dependents.cc
@@ -53,7 +53,9 @@ using namespace ARDOUR;
void
ARDOUR_UI::shutdown ()
{
- ui_config->save_state();
+ if (ui_config->dirty()) {
+ ui_config->save_state();
+ }
}
void
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index bb627fc011..c9381b7a64 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -867,7 +867,9 @@ ARDOUR_UI::save_ardour_state ()
Config->add_extra_xml (_startup->engine_control()->get_state());
}
Config->save_state();
- ui_config->save_state ();
+ if (ui_config->dirty()) {
+ ui_config->save_state ();
+ }
XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
XMLNode& mnode (mixer->get_state());
diff --git a/gtk2_ardour/cairo_widget.cc b/gtk2_ardour/cairo_widget.cc
index 209770ab03..11fcfdffd6 100644
--- a/gtk2_ardour/cairo_widget.cc
+++ b/gtk2_ardour/cairo_widget.cc
@@ -21,10 +21,12 @@
#include "gui_thread.h"
CairoWidget::CairoWidget ()
- : _width (1),
- _height (1),
- _dirty (true),
- _pixmap (0)
+ : _width (1)
+ , _height (1)
+ , _state (CairoWidget::State (0))
+ , _dirty (true)
+ , _pixmap (0)
+
{
}
@@ -109,3 +111,37 @@ CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
set_dirty ();
}
+
+Gdk::Color
+CairoWidget::get_parent_bg ()
+{
+ Widget* parent;
+
+ parent = get_parent ();
+
+ while (parent && !parent->get_has_window()) {
+ parent = parent->get_parent();
+ }
+
+ if (parent && parent->get_has_window()) {
+ return parent->get_style ()->get_bg (parent->get_state());
+ }
+
+ return get_style ()->get_bg (get_state());
+}
+
+void
+CairoWidget::set_state (CairoWidget::State s, bool yn)
+{
+ if (yn) {
+ if (!(_state & s)) {
+ _state = CairoWidget::State (_state|s);
+ StateChanged ();
+ }
+ } else {
+ if (_state & s) {
+ _state = CairoWidget::State (_state & ~s);
+ StateChanged ();
+ }
+ }
+}
diff --git a/gtk2_ardour/cairo_widget.h b/gtk2_ardour/cairo_widget.h
index 8665f66198..e368a21a03 100644
--- a/gtk2_ardour/cairo_widget.h
+++ b/gtk2_ardour/cairo_widget.h
@@ -35,14 +35,33 @@ 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.
+ */
+
+ enum State {
+ Active = 0x1,
+ Mid = 0x2,
+ Selected = 0x4,
+ Prelight = 0x8,
+ Insensitive = 0x10,
+ };
+
+ State state() const { return _state; }
+ virtual void set_state (State, bool);
+ sigc::signal<void> StateChanged;
+
protected:
/** Render the widget to the given Cairo context */
virtual void render (cairo_t *) = 0;
virtual bool on_expose_event (GdkEventExpose *);
void on_size_allocate (Gtk::Allocation &);
+ Gdk::Color get_parent_bg ();
int _width; ///< pixmap width
int _height; ///< pixmap height
+ State _state;
private:
bool _dirty; ///< true if the pixmap requires re-rendering
diff --git a/gtk2_ardour/canvas_vars.h b/gtk2_ardour/canvas_vars.h
index b8bb1f8608..445b76ee1c 100644
--- a/gtk2_ardour/canvas_vars.h
+++ b/gtk2_ardour/canvas_vars.h
@@ -136,3 +136,28 @@ CANVAS_VARIABLE(canvasvar_WaveFormClip, "clipped waveform")
CANVAS_VARIABLE(canvasvar_WaveFormFill, "waveform fill")
CANVAS_VARIABLE(canvasvar_ZeroLine, "zero line")
CANVAS_VARIABLE(canvasvar_ZoomRect, "zoom rect")
+
+#define BUTTON_VARS(root,name) \
+CANVAS_VARIABLE(canvasvar_ ## root ## BorderStart, name " border start") \
+CANVAS_VARIABLE(canvasvar_ ## root ## BorderEnd, name " border end") \
+CANVAS_VARIABLE(canvasvar_ ## root ## BorderStartSelected, name " border start selected") \
+CANVAS_VARIABLE(canvasvar_ ## root ## BorderEndSelected, name " border end selected") \
+CANVAS_VARIABLE(canvasvar_ ## root ## FillStart, name " fill start") \
+CANVAS_VARIABLE(canvasvar_ ## root ## FillEnd, name " fill end") \
+CANVAS_VARIABLE(canvasvar_ ## root ## FillStartActive, name " fill start active") \
+CANVAS_VARIABLE(canvasvar_ ## root ## FillEndActive, name " fill end active") \
+CANVAS_VARIABLE(canvasvar_ ## root ## FillStartMid, name " fill start mid") \
+CANVAS_VARIABLE(canvasvar_ ## root ## FillEndMid, name " fill end mid") \
+CANVAS_VARIABLE(canvasvar_ ## root ## LED, name " led") \
+CANVAS_VARIABLE(canvasvar_ ## root ## LEDActive, name " led active") \
+CANVAS_VARIABLE(canvasvar_ ## root ## LEDMid, name " led mid") \
+CANVAS_VARIABLE(canvasvar_ ## root ## Text, name " text") \
+CANVAS_VARIABLE(canvasvar_ ## root ## TextActive, name " text active") \
+CANVAS_VARIABLE(canvasvar_ ## root ## TextMid, name " text mid")
+
+BUTTON_VARS(ProcessorPreFader, "processor prefader")
+BUTTON_VARS(ProcessorFader, "processor fader")
+BUTTON_VARS(ProcessorPostFader, "processor postfader")
+BUTTON_VARS(MonitorButton, "monitor")
+BUTTON_VARS(SoloIsolateButton, "solo isolate")
+BUTTON_VARS(SoloSafeButton, "solo safe")
diff --git a/gtk2_ardour/led.cc b/gtk2_ardour/led.cc
index 9a93e048d1..259ebccd2d 100644
--- a/gtk2_ardour/led.cc
+++ b/gtk2_ardour/led.cc
@@ -70,15 +70,15 @@ LED::render (cairo_t* cr)
c = style->get_bg (get_state());
}
-
+#if 0
cairo_rectangle(cr, 0, 0, _width, _height);
cairo_stroke_preserve(cr);
cairo_set_source_rgb(cr, c.get_red_p(), c.get_green_p(), c.get_blue_p());
cairo_fill(cr);
+#endif
cairo_translate(cr, _width/2, _height/2);
-#if 0
//inset
cairo_pattern_t *pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, _diameter);
cairo_pattern_add_color_stop_rgba (pat, 0, 0,0,0, 0.4);
@@ -107,16 +107,19 @@ LED::render (cairo_t* cr)
cairo_set_source (cr, pat2);
cairo_fill (cr);
cairo_pattern_destroy (pat2);
-#endif
-
- cairo_set_source_rgba (cr, _red, _green, _blue, 1.0);
- cairo_arc (cr, 0, 0, _diameter/2-5, 0, 2 * M_PI);
- cairo_fill(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) {
diff --git a/gtk2_ardour/led.h b/gtk2_ardour/led.h
index e2009ce192..e8514d60c0 100644
--- a/gtk2_ardour/led.h
+++ b/gtk2_ardour/led.h
@@ -30,6 +30,8 @@ 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);
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 5ce4caa3af..7866cef0d8 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -56,7 +56,7 @@
#include "mixer_strip.h"
#include "mixer_ui.h"
#include "keyboard.h"
-#include "led.h"
+#include "ardour_button.h"
#include "public_editor.h"
#include "send_ui.h"
#include "io_selector.h"
@@ -86,7 +86,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, bool in_mixer)
, gpm (sess, 250)
, panners (sess)
, button_table (3, 1)
- , solo_led_table (2, 2)
+ , rec_solo_table (2, 2)
, top_button_table (1, 2)
, middle_button_table (1, 2)
, bottom_button_table (1, 2)
@@ -185,54 +185,42 @@ MixerStrip::init ()
mute_button->set_name ("MixerMuteButton");
solo_button->set_name ("MixerSoloButton");
- monitor_input_button->set_name ("MixerMonitorInputButton");
- monitor_disk_button->set_name ("MixerMonitorInputButton");
+ monitor_input_button->set_diameter (3);
+ monitor_disk_button->set_diameter (3);
- solo_isolated_led = manage (new LED);
+ solo_isolated_led = manage (new ArdourButton);
solo_isolated_led->show ();
- solo_isolated_led->set_diameter (6);
+ solo_isolated_led->set_diameter (3);
solo_isolated_led->set_no_show_all (true);
- solo_isolated_led->set_name (X_("SoloIsolatedLED"));
+ solo_isolated_led->set_name (X_("solo isolate"));
solo_isolated_led->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
solo_isolated_led->signal_button_release_event().connect (sigc::mem_fun (*this, &RouteUI::solo_isolate_button_release));
UI::instance()->set_tip (solo_isolated_led, _("Isolate Solo"), "");
- solo_safe_led = manage (new LED);
+ solo_safe_led = manage (new ArdourButton);
solo_safe_led->show ();
- solo_safe_led->set_diameter (6);
+ solo_safe_led->set_diameter (3);
solo_safe_led->set_no_show_all (true);
- solo_safe_led->set_name (X_("SoloSafeLED"));
+ solo_safe_led->set_name (X_("solo safe"));
solo_safe_led->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
solo_safe_led->signal_button_release_event().connect (sigc::mem_fun (*this, &RouteUI::solo_safe_button_release));
UI::instance()->set_tip (solo_safe_led, _("Lock Solo Status"), "");
- _iso_label = manage (new Label (_("iso")));
- _safe_label = manage (new Label (_("lock")));
-
- _iso_label->set_name (X_("SoloLEDLabel"));
- _safe_label->set_name (X_("SoloLEDLabel"));
-
- _iso_label->show ();
- _safe_label->show ();
-
- solo_led_table.set_spacings (0);
- solo_led_table.set_border_width (1);
- solo_led_table.attach (*_iso_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
- solo_led_table.attach (*solo_isolated_led, 1, 2, 0, 1, Gtk::FILL, Gtk::FILL);
- solo_led_table.attach (*_safe_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL);
- solo_led_table.attach (*solo_safe_led, 1, 2, 1, 2, Gtk::FILL, Gtk::FILL);
- solo_led_table.show ();
+ solo_safe_led->set_text (_("lock"));
+ solo_isolated_led->set_text (_("iso"));
top_button_table.set_homogeneous (true);
- top_button_table.set_spacings (0);
+ top_button_table.set_spacings (2);
top_button_table.attach (*monitor_input_button, 0, 1, 0, 1);
top_button_table.attach (*monitor_disk_button, 1, 2, 0, 1);
top_button_table.show ();
- below_panner_box.set_border_width (2);
- below_panner_box.set_spacing (2);
- below_panner_box.pack_end (solo_led_table, false, false);
- below_panner_box.show ();
+ rec_solo_table.set_homogeneous (true);
+ rec_solo_table.set_row_spacings (2);
+ rec_solo_table.set_col_spacings (2);
+ rec_solo_table.attach (*solo_isolated_led, 1, 2, 0, 1);
+ rec_solo_table.attach (*solo_safe_led, 1, 2, 1, 2);
+ rec_solo_table.show ();
button_table.set_homogeneous (true);
button_table.set_spacings (0);
@@ -281,9 +269,9 @@ MixerStrip::init ()
global_vpacker.pack_start (button_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (processor_box, true, true);
global_vpacker.pack_start (panners, Gtk::PACK_SHRINK);
- global_vpacker.pack_start (top_button_table, Gtk::PACK_SHRINK);
- global_vpacker.pack_start (below_panner_box, Gtk::PACK_SHRINK);
- global_vpacker.pack_start (middle_button_table, Gtk::PACK_SHRINK);
+ global_vpacker.pack_start (top_button_table, Gtk::PACK_SHRINK, 2);
+ global_vpacker.pack_start (rec_solo_table, Gtk::PACK_SHRINK, 2);
+ global_vpacker.pack_start (middle_button_table, Gtk::PACK_SHRINK, 2);
global_vpacker.pack_start (gpm, Gtk::PACK_SHRINK);
global_vpacker.pack_start (bottom_button_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (output_button, Gtk::PACK_SHRINK);
@@ -362,11 +350,11 @@ void
MixerStrip::set_route (boost::shared_ptr<Route> rt)
{
if (rec_enable_button->get_parent()) {
- below_panner_box.remove (*rec_enable_button);
+ rec_solo_table.remove (*rec_enable_button);
}
if (show_sends_button->get_parent()) {
- below_panner_box.remove (*show_sends_button);
+ rec_solo_table.remove (*show_sends_button);
}
processor_box.set_route (rt);
@@ -388,10 +376,10 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
if (route()->is_master()) {
solo_button->hide ();
- below_panner_box.hide ();
+ rec_solo_table.hide ();
} else {
solo_button->show ();
- below_panner_box.show ();
+ rec_solo_table.show ();
}
if (_mixer_owned && (route()->is_master() || route()->is_monitor())) {
@@ -453,7 +441,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
if (is_track ()) {
- below_panner_box.pack_start (*rec_enable_button);
+ rec_solo_table.attach (*rec_enable_button, 0, 1, 0, 2);
rec_enable_button->set_sensitive (_session->writable());
rec_enable_button->show();
@@ -462,7 +450,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
/* non-master bus */
if (!_route->is_master()) {
- below_panner_box.pack_start (*show_sends_button);
+ rec_solo_table.attach (*show_sends_button, 0, 1, 0, 2);
show_sends_button->show();
}
}
@@ -586,8 +574,8 @@ MixerStrip::set_width_enum (Width w, void* owner)
panners.astate_string(_route->panner()->automation_state()));
}
- _iso_label->show ();
- _safe_label->show ();
+ solo_isolated_led->set_text (_("iso"));
+ solo_safe_led->set_text (_("lock"));
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2);
set_size_request (-1, -1);
@@ -609,9 +597,9 @@ MixerStrip::set_width_enum (Width w, void* owner)
((Gtk::Label*)panners.pan_automation_state_button.get_child())->set_text (
panners.short_astate_string(_route->panner()->automation_state()));
}
-
- _iso_label->hide ();
- _safe_label->hide ();
+
+ solo_isolated_led->set_text ("");
+ solo_safe_led->set_text ("");
Gtkmm2ext::set_size_request_to_display_given_text (name_button, longest_label.c_str(), 2, 2);
set_size_request (max (50, gpm.get_gm_width()), -1);
@@ -1737,11 +1725,20 @@ MixerStrip::set_button_names ()
case Wide:
rec_enable_button_label.set_text (_("Rec"));
mute_button_label.set_text (_("Mute"));
- monitor_input_button_label.set_text (_("In"));
- monitor_disk_button_label.set_text (_("Disk"));
+ monitor_input_button->set_text (_("In"));
+ monitor_disk_button->set_text (_("Disk"));
+
if (_route && _route->solo_safe()) {
- solo_button_label.set_text (X_("!"));
+ solo_button->remove ();
+ if (solo_safe_image == 0) {
+ solo_safe_image = new Gtk::Image (::get_icon("solo-safe-enabled"));
+ solo_safe_image->show ();
+ }
+ solo_button->add (*solo_safe_image);
} else {
+ solo_button->remove ();
+ solo_button->add (solo_button_label);
+ solo_button_label.show ();
if (!Config->get_solo_control_is_listen_control()) {
solo_button_label.set_text (_("Solo"));
} else {
@@ -1760,10 +1757,19 @@ MixerStrip::set_button_names ()
default:
rec_enable_button_label.set_text (_("R"));
mute_button_label.set_text (_("M"));
- monitor_input_button_label.set_text (_("I"));
- monitor_disk_button_label.set_text (_("D"));
+ monitor_input_button->set_text (_("I"));
+ monitor_disk_button->set_text (_("D"));
if (_route && _route->solo_safe()) {
- solo_button_label.set_text (X_("!"));
+ solo_button->remove ();
+ if (solo_safe_image == 0) {
+ solo_safe_image = new Gtk::Image (::get_icon("solo-safe-enabled"));
+ solo_safe_image->show ();
+ }
+ solo_button->add (*solo_safe_image);
+ } else {
+ solo_button->remove ();
+ solo_button->add (solo_button_label);
+ solo_button_label.show ();
if (!Config->get_solo_control_is_listen_control()) {
solo_button_label.set_text (_("S"));
} else {
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index b08e1da29c..3c123792f9 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -162,15 +162,11 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
PannerUI panners;
Gtk::Table button_table;
- Gtk::Table solo_led_table;
- Gtk::HBox below_panner_box;
+ Gtk::Table rec_solo_table;
Gtk::Table top_button_table;
Gtk::Table middle_button_table;
Gtk::Table bottom_button_table;
- Gtk::Label* _iso_label;
- Gtk::Label* _safe_label;
-
Gtk::Button gain_unit_button;
Gtk::Label gain_unit_label;
Gtk::Button meter_point_button;
diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc
index 26ec5f6c24..0632147bba 100644
--- a/gtk2_ardour/processor_box.cc
+++ b/gtk2_ardour/processor_box.cc
@@ -101,50 +101,32 @@ ProcessorEntry::ProcessorEntry (boost::shared_ptr<Processor> p, Width w)
, _width (w)
, _visual_state (Gtk::STATE_NORMAL)
{
- _hbox.pack_start (_active, false, false);
- _event_box.add (_name);
- _hbox.pack_start (_event_box, true, true);
- _vbox.pack_start (_hbox);
- _frame.add (_vbox);
-
- /* without this, the border is mis-drawn on some systems */
- _vbox.set_border_width (1);
-
- _name.set_alignment (0, 0.5);
- _name.set_text (name ());
- _name.set_padding (2, 2);
-
- if (boost::dynamic_pointer_cast<Amp> (p)) {
- /* Fader processor gets a special look */
- _event_box.set_name ("ProcessorFader");
- _frame.set_name ("ProcessorFaderFrame");
- _name.set_padding (2, 4);
- }
-
- _active.set_active (_processor->active ());
- _active.signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::active_toggled));
-
- _frame.show ();
+ _vbox.pack_start (_button, true, true);
_vbox.show ();
- _hbox.show ();
- _event_box.show ();
- _name.show ();
- _active.show ();
+
+ _button.set_state (CairoWidget::Active, _processor->active());
+ _button.set_diameter (3);
+ _button.signal_clicked.connect (sigc::mem_fun (*this, &ProcessorEntry::led_clicked));
+ _button.set_text (name());
+ _button.set_led_left (true);
+ _button.show ();
_processor->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context());
_processor->PropertyChanged.connect (name_connection, invalidator (*this), ui_bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context());
+
+ setup_visuals ();
}
EventBox&
ProcessorEntry::action_widget ()
{
- return _event_box;
+ return _button;
}
Gtk::Widget&
ProcessorEntry::widget ()
{
- return _frame;
+ return _vbox;
}
string
@@ -154,17 +136,32 @@ ProcessorEntry::drag_text () const
}
void
-ProcessorEntry::set_visual_state (Gtk::StateType t)
+ProcessorEntry::set_position (Position p)
{
- _visual_state = t;
+ _position = p;
setup_visuals ();
}
void
-ProcessorEntry::set_position (Position p)
+ProcessorEntry::set_visual_state (Gtk::StateType t)
{
- _position = p;
- setup_visuals ();
+ /* map from GTK state to CairoWidget */
+
+ switch (t) {
+ case Gtk::STATE_ACTIVE:
+ _button.set_state (CairoWidget::Active, true);
+ break;
+
+ case Gtk::STATE_SELECTED:
+ _button.set_state (CairoWidget::Selected, true);
+ break;
+
+ case Gtk::STATE_NORMAL:
+ default:
+ _button.set_state (CairoWidget::Selected, false);
+ _button.set_state (CairoWidget::Active, false);
+ break;
+ }
}
void
@@ -172,42 +169,15 @@ ProcessorEntry::setup_visuals ()
{
switch (_position) {
case PreFader:
- _event_box.set_name ("ProcessorPreFader");
- if (_visual_state == Gtk::STATE_NORMAL) {
- _frame.set_name ("ProcessorPreFaderFrame");
- }
+ _button.set_name ("processor prefader");
break;
case Fader:
- _event_box.set_name ("ProcessorFader");
- if (_visual_state == Gtk::STATE_NORMAL) {
- _frame.set_name ("ProcessorFaderFrame");
- }
+ _button.set_name ("processor fader");
break;
case PostFader:
- _event_box.set_name ("ProcessorPostFader");
- if (_visual_state == Gtk::STATE_NORMAL) {
- _frame.set_name ("ProcessorPostFaderFrame");
- }
- break;
- }
-
- switch (_visual_state) {
- case Gtk::STATE_NORMAL:
- /* _frame has been set up above */
- _event_box.set_state (Gtk::STATE_NORMAL);
- break;
- case Gtk::STATE_SELECTED:
- _frame.set_name ("ProcessorFrameSelected");
- /* don't change the background of the box when it is selected */
- _event_box.set_state (Gtk::STATE_NORMAL);
- break;
- case Gtk::STATE_ACTIVE:
- _frame.set_name ("ProcessorFrameActiveSend");
- _event_box.set_state (Gtk::STATE_ACTIVE);
- break;
- default:
+ _button.set_name ("processor postfader");
break;
}
}
@@ -226,32 +196,26 @@ ProcessorEntry::set_enum_width (Width w)
}
void
-ProcessorEntry::active_toggled ()
+ProcessorEntry::led_clicked()
{
- if (_active.get_active ()) {
- if (!_processor->active ()) {
- _processor->activate ();
- }
+ if (!_processor->active ()) {
+ _processor->activate ();
} else {
- if (_processor->active ()) {
- _processor->deactivate ();
- }
+ _processor->deactivate ();
}
}
void
ProcessorEntry::processor_active_changed ()
{
- if (_active.get_active () != _processor->active ()) {
- _active.set_active (_processor->active ());
- }
+ _button.set_state (CairoWidget::Active, _processor->active());
}
void
ProcessorEntry::processor_property_changed (const PropertyChange& what_changed)
{
if (what_changed.contains (ARDOUR::Properties::name)) {
- _name.set_text (name ());
+ _button.set_text (name ());
}
}
diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h
index eabe32a631..68ba7e9679 100644
--- a/gtk2_ardour/processor_box.h
+++ b/gtk2_ardour/processor_box.h
@@ -53,6 +53,7 @@
#include "send_ui.h"
#include "enums.h"
#include "window_proxy.h"
+#include "ardour_button.h"
class MotionController;
class PluginSelector;
@@ -123,24 +124,18 @@ public:
virtual void hide_things () {}
protected:
-
- virtual void setup_visuals ();
-
+ ArdourButton _button;
Gtk::VBox _vbox;
Position _position;
-private:
+ virtual void setup_visuals ();
- void active_toggled ();
+private:
+ void led_clicked();
void processor_active_changed ();
void processor_property_changed (const PBD::PropertyChange&);
std::string name () const;
- Gtk::Frame _frame;
- Gtk::EventBox _event_box;
- Gtk::Label _name;
- Gtk::HBox _hbox;
- Gtk::CheckButton _active;
boost::shared_ptr<ARDOUR::Processor> _processor;
Width _width;
Gtk::StateType _visual_state;
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 6e409c05c2..736476e49b 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -2350,8 +2350,16 @@ RouteTimeAxisView::set_button_names ()
rec_enable_button_label.set_text (_("r"));
if (_route && _route->solo_safe()) {
- solo_button_label.set_text (X_("!"));
+ solo_button->remove ();
+ if (solo_safe_image == 0) {
+ solo_safe_image = new Gtk::Image (::get_icon("solo-safe-enabled"));
+ solo_safe_image->show ();
+ }
+ solo_button->add (*solo_safe_image);
} else {
+ solo_button->remove ();
+ solo_button->add (solo_button_label);
+ solo_button_label.show ();
if (Config->get_solo_control_is_listen_control()) {
switch (Config->get_listen_position()) {
case AfterFaderListen:
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 9cb4941566..c0dd43404e 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -34,7 +34,7 @@
#include "ardour_ui.h"
#include "editor.h"
#include "route_ui.h"
-#include "led.h"
+#include "ardour_button.h"
#include "keyboard.h"
#include "utils.h"
#include "prompter.h"
@@ -81,6 +81,7 @@ RouteUI::~RouteUI()
delete sends_menu;
delete record_menu;
delete _invert_menu;
+ delete solo_safe_image;
}
void
@@ -107,6 +108,7 @@ RouteUI::init ()
multiple_mute_change = false;
multiple_solo_change = false;
_i_am_the_modifier = 0;
+ solo_safe_image = 0;
setup_invert_buttons ();
@@ -137,19 +139,15 @@ RouteUI::init ()
// show_sends_button->set_self_managed (true);
UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
- monitor_input_button = manage (new BindableToggleButton ());
- // monitor_input_button->set_self_managed (true);
- monitor_input_button->set_name ("MonitorInputButton");
- monitor_input_button->add (monitor_input_button_label);
- monitor_input_button_label.show ();
+ monitor_input_button = manage (new ArdourButton ());
+ monitor_input_button->set_name ("monitor");
+ monitor_input_button->set_text (_("In"));
UI::instance()->set_tip (monitor_input_button, _("Monitor input"), "");
monitor_input_button->set_no_show_all (true);
- monitor_disk_button = manage (new BindableToggleButton ());
- // monitor_disk_button->set_self_managed (true);
- monitor_disk_button->set_name ("MonitorDiskButton");
- monitor_disk_button->add (monitor_disk_button_label);
- monitor_disk_button_label.show ();
+ monitor_disk_button = manage (new ArdourButton ());
+ monitor_disk_button->set_name ("monitor");
+ monitor_disk_button->set_text (_("Disk"));
UI::instance()->set_tip (monitor_disk_button, _("Monitor playback"), "");
monitor_disk_button->set_no_show_all (true);
@@ -170,12 +168,15 @@ RouteUI::init ()
solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
+
+ monitor_input_button->set_distinct_led_click (false);
+ monitor_disk_button->set_distinct_led_click (false);
- monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press), false);
- monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release), false);
+ monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press));
+ monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release));
- monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press), false);
- monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release), false);
+ monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press));
+ monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release));
}
void
@@ -607,22 +608,26 @@ RouteUI::update_monitoring_display ()
MonitorState ms = t->monitoring_state();
if (t->monitoring_choice() & MonitorInput) {
- monitor_input_button->set_visual_state (1);
+ monitor_input_button->set_state (CairoWidget::Active, true);
+ monitor_input_button->set_state (CairoWidget::Mid, false);
} else {
if (ms & MonitoringInput) {
- monitor_input_button->set_visual_state (2);
+ monitor_input_button->set_state (CairoWidget::Mid, true);
+ monitor_input_button->set_state (CairoWidget::Active, false);
} else {
- monitor_input_button->set_visual_state (0);
+ monitor_input_button->set_state (CairoWidget::State (CairoWidget::Active|CairoWidget::Mid), false);
}
}
if (t->monitoring_choice() & MonitorDisk) {
- monitor_disk_button->set_visual_state (1);
+ monitor_disk_button->set_state (CairoWidget::Active, true);
+ monitor_disk_button->set_state (CairoWidget::Mid, false);
} else {
if (ms & MonitoringDisk) {
- monitor_disk_button->set_visual_state (2);
+ monitor_disk_button->set_state (CairoWidget::Mid, true);
+ monitor_disk_button->set_state (CairoWidget::Active, false);
} else {
- monitor_disk_button->set_visual_state (0);
+ monitor_disk_button->set_state (CairoWidget::State (CairoWidget::Active|CairoWidget::Mid), false);
}
}
}
@@ -1061,11 +1066,11 @@ RouteUI::update_solo_display ()
set_button_names ();
if (solo_isolated_led) {
- solo_isolated_led->set_visual_state (_route->solo_isolated() ? 1 : 0);
+ solo_isolated_led->set_state (CairoWidget::Active, _route->solo_isolated());
}
if (solo_safe_led) {
- solo_safe_led->set_visual_state (_route->solo_safe() ? 1 : 0);
+ solo_safe_led->set_state (CairoWidget::Active, _route->solo_safe());
}
solo_button->set_visual_state (solo_visual_state (_route));
@@ -1335,7 +1340,7 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
return true;
}
- bool view = (solo_isolated_led->visual_state() != 0);
+ bool view = (solo_isolated_led->state() & (CairoWidget::Active|CairoWidget::Mid));
bool model = _route->solo_isolated();
/* called BEFORE the view has changed */
@@ -1366,7 +1371,7 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
bool
RouteUI::solo_safe_button_release (GdkEventButton*)
{
- _route->set_solo_safe (!(solo_safe_led->visual_state() > 0), this);
+ _route->set_solo_safe (!(solo_safe_led->state() & (CairoWidget::Active|CairoWidget::Mid)), this);
return true;
}
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index d6667a3eeb..e9d81451f6 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -47,7 +47,7 @@ namespace Gtk {
}
class BindableToggleButton;
-class LED;
+class ArdourButton;
class RouteUI : public virtual AxisView
{
@@ -94,11 +94,13 @@ class RouteUI : public virtual AxisView
BindableToggleButton* solo_button;
BindableToggleButton* rec_enable_button; /* audio tracks */
BindableToggleButton* show_sends_button; /* busses */
- BindableToggleButton* monitor_input_button;
- BindableToggleButton* monitor_disk_button;
+ ArdourButton* monitor_input_button;
+ ArdourButton* monitor_disk_button;
- LED* solo_safe_led;
- LED* solo_isolated_led;
+ Gtk::Image* solo_safe_image;
+
+ ArdourButton* solo_safe_led;
+ ArdourButton* solo_isolated_led;
Gtk::Label solo_button_label;
Gtk::Label mute_button_label;
diff --git a/gtk2_ardour/theme_manager.cc b/gtk2_ardour/theme_manager.cc
index 8c2f92768b..b800554fb9 100644
--- a/gtk2_ardour/theme_manager.cc
+++ b/gtk2_ardour/theme_manager.cc
@@ -163,6 +163,7 @@ ThemeManager::button_press_event (GdkEventButton* ev)
ccvar = (*iter)[columns.pVar];
ccvar->set(rgba);
+ ARDOUR_UI::config()->set_dirty ();
//ColorChanged (rgba);
ColorsChanged();//EMIT SIGNAL
@@ -227,6 +228,7 @@ ThemeManager::on_dark_theme_button_toggled()
} else {
ARDOUR_UI::config()->ui_rc_file.set("ardour3_ui_dark.rc");
}
+ ARDOUR_UI::config()->set_dirty ();
load_rc_file (ARDOUR_UI::config()->ui_rc_file.get(), true);
}
@@ -251,19 +253,20 @@ ThemeManager::setup_theme ()
int r, g, b, a;
color_list->clear();
- for (std::vector<UIConfigVariable<uint32_t> *>::iterator i = ARDOUR_UI::config()->canvas_colors.begin(); i != ARDOUR_UI::config()->canvas_colors.end(); i++) {
+ for (std::map<std::string,UIConfigVariable<uint32_t> *>::iterator i = ARDOUR_UI::config()->canvas_colors.begin(); i != ARDOUR_UI::config()->canvas_colors.end(); i++) {
TreeModel::Row row = *(color_list->append());
Gdk::Color col;
- uint32_t rgba = (*i)->get();
+ UIConfigVariable<uint32_t>* var = i->second;
+ uint32_t rgba = var->get();
UINT_TO_RGBA (rgba, &r, &g, &b, &a);
//cerr << (*i)->name() << " == " << hex << rgba << ": " << hex << r << " " << hex << g << " " << hex << b << endl;
col.set_rgb_p (r / 255.0, g / 255.0, b / 255.0);
- row[columns.name] = (*i)->name();
+ row[columns.name] = var->name();
row[columns.color] = "";
- row[columns.pVar] = *i;
+ row[columns.pVar] = var;
row[columns.rgba] = rgba;
row[columns.gdkcolor] = col;
diff --git a/gtk2_ardour/ui_config.cc b/gtk2_ardour/ui_config.cc
index 10628334fd..84975bdbf2 100644
--- a/gtk2_ardour/ui_config.cc
+++ b/gtk2_ardour/ui_config.cc
@@ -18,6 +18,7 @@
*/
#include <unistd.h>
+#include <cstdlib>
#include <cstdio> /* for snprintf, grrr */
#include <glibmm/miscutils.h>
@@ -28,6 +29,8 @@
#include "pbd/file_utils.h"
#include "pbd/error.h"
+#include "gtkmm2ext/rgb_macros.h"
+
#include "ardour/ardour.h"
#include "ardour/filesystem_paths.h"
@@ -49,7 +52,7 @@ UIConfiguration::UIConfiguration ()
#include "canvas_vars.h"
#undef UI_CONFIG_VARIABLE
#undef CANVAS_VARIABLE
- hack(true)
+ _dirty (false)
{
load_state();
}
@@ -73,8 +76,7 @@ UIConfiguration::load_defaults ()
}
if (find_file_in_search_path (ardour_search_path() + system_config_search_path(),
- rcfile, default_ui_rc_file) )
- {
+ rcfile, default_ui_rc_file) ) {
XMLTree tree;
found = 1;
@@ -91,6 +93,8 @@ UIConfiguration::load_defaults ()
error << string_compose(_("default ui configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
return -1;
}
+
+ _dirty = false;
}
return found;
@@ -104,8 +108,7 @@ UIConfiguration::load_state ()
sys::path default_ui_rc_file;
if ( find_file_in_search_path (ardour_search_path() + system_config_search_path(),
- "ardour3_ui_default.conf", default_ui_rc_file) )
- {
+ "ardour3_ui_default.conf", default_ui_rc_file) ) {
XMLTree tree;
found = true;
@@ -127,8 +130,7 @@ UIConfiguration::load_state ()
sys::path user_ui_rc_file;
if (find_file_in_search_path (ardour_search_path() + user_config_directory(),
- "ardour3_ui.conf", user_ui_rc_file))
- {
+ "ardour3_ui.conf", user_ui_rc_file)) {
XMLTree tree;
found = true;
@@ -145,12 +147,15 @@ UIConfiguration::load_state ()
error << string_compose(_("user ui configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
return -1;
}
+
+ _dirty = false;
}
if (!found)
error << _("could not find any ui configuration file, canvas will look broken.") << endmsg;
pack_canvasvars();
+
return 0;
}
@@ -181,6 +186,8 @@ UIConfiguration::save_state()
}
}
+ _dirty = false;
+
return 0;
}
@@ -244,6 +251,7 @@ UIConfiguration::set_state (const XMLNode& root, int /*version*/)
}
}
+
return 0;
}
@@ -270,9 +278,38 @@ void
UIConfiguration::pack_canvasvars ()
{
#undef CANVAS_VARIABLE
-#define CANVAS_VARIABLE(var,name) canvas_colors.push_back(&var);
+#define CANVAS_VARIABLE(var,name) canvas_colors.insert (std::pair<std::string,UIConfigVariable<uint32_t>* >(name,&var));
#include "canvas_vars.h"
#undef CANVAS_VARIABLE
}
+static bool can_abort = false;
+
+uint32_t
+UIConfiguration::color_by_name (const std::string& name)
+{
+ map<std::string,UIConfigVariable<uint32_t>* >::iterator i = canvas_colors.find (name);
+
+ if (name == "processor fader led") {
+ can_abort = true;
+ }
+
+ if (i != canvas_colors.end()) {
+ return i->second->get();
+ }
+
+ // cerr << string_compose (_("Color %1 not found"), name) << endl;
+ return RGBA_TO_UINT (random()%256,random()%256,random()%256,0xff);
+}
+
+void
+UIConfiguration::set_dirty ()
+{
+ _dirty = true;
+}
+bool
+UIConfiguration::dirty () const
+{
+ return _dirty;
+}
diff --git a/gtk2_ardour/ui_config.h b/gtk2_ardour/ui_config.h
index 09e8448831..f96659de76 100644
--- a/gtk2_ardour/ui_config.h
+++ b/gtk2_ardour/ui_config.h
@@ -74,7 +74,10 @@ class UIConfiguration : public PBD::Stateful
UIConfiguration();
~UIConfiguration();
- std::vector<UIConfigVariable<uint32_t> *> canvas_colors;
+ std::map<std::string,UIConfigVariable<uint32_t> *> canvas_colors;
+
+ bool dirty () const;
+ void set_dirty ();
int load_state ();
int save_state ();
@@ -86,6 +89,8 @@ class UIConfiguration : public PBD::Stateful
void set_variables (const XMLNode&);
void pack_canvasvars ();
+ uint32_t color_by_name (const std::string&);
+
sigc::signal<void,const char*> ParameterChanged;
#undef UI_CONFIG_VARIABLE
@@ -99,7 +104,7 @@ class UIConfiguration : public PBD::Stateful
private:
XMLNode& state ();
- bool hack;
+ bool _dirty;
};
#endif /* __ardour_ui_configuration_h__ */
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index 60942f512a..fa53333060 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -29,6 +29,7 @@ gtk2_ardour_sources = [
'add_route_dialog.cc',
'ambiguous_file_dialog.cc',
'analysis_window.cc',
+ 'ardour_button.cc',
'ardour_dialog.cc',
'ardour_ui.cc',
'ardour_ui2.cc',