diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-10-26 21:01:14 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-10-26 21:01:14 +0000 |
commit | 51ab5ccabf432540ca935065f6c6f40a96f42dad (patch) | |
tree | a5f062738bcedc33cd55b176168d532e4cc6d189 | |
parent | ae3eb6e3f4f270a03ff297d1bbe7cd3f3a2159a9 (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.in | 138 | ||||
-rw-r--r-- | gtk2_ardour/ardour3_ui_dark.rc.in | 3 | ||||
-rw-r--r-- | gtk2_ardour/ardour3_ui_default.conf | 96 | ||||
-rw-r--r-- | gtk2_ardour/ardour3_ui_light.rc.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour3_widget_list.rc | 27 | ||||
-rw-r--r-- | gtk2_ardour/ardour_button.cc | 375 | ||||
-rw-r--r-- | gtk2_ardour/ardour_button.h | 83 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_dependents.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_ed.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/cairo_widget.cc | 44 | ||||
-rw-r--r-- | gtk2_ardour/cairo_widget.h | 19 | ||||
-rw-r--r-- | gtk2_ardour/canvas_vars.h | 25 | ||||
-rw-r--r-- | gtk2_ardour/led.cc | 17 | ||||
-rw-r--r-- | gtk2_ardour/led.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/mixer_strip.cc | 108 | ||||
-rw-r--r-- | gtk2_ardour/mixer_strip.h | 6 | ||||
-rw-r--r-- | gtk2_ardour/processor_box.cc | 118 | ||||
-rw-r--r-- | gtk2_ardour/processor_box.h | 15 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.cc | 10 | ||||
-rw-r--r-- | gtk2_ardour/route_ui.cc | 55 | ||||
-rw-r--r-- | gtk2_ardour/route_ui.h | 12 | ||||
-rw-r--r-- | gtk2_ardour/theme_manager.cc | 11 | ||||
-rw-r--r-- | gtk2_ardour/ui_config.cc | 53 | ||||
-rw-r--r-- | gtk2_ardour/ui_config.h | 9 | ||||
-rw-r--r-- | gtk2_ardour/wscript | 1 |
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', |