diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 90e4c54635..b718bc26fc 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -245,13 +245,36 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) session_loaded = false; ignore_dual_punch = false; + const XMLTree* layout = WavesUI::load_layout("tracks_tools.xml"); + if (layout == NULL) { + return; + } + + XMLNode* root = layout->root(); + if ((root == NULL) || strcasecmp(root->name().c_str(), "layout")) { + return; + } + + WavesUI::create_ui(layout, tracks_tools_packer, _tools); + roll_button.set_controllable (roll_controllable); + _tools.get_waves_button ("transport_play_button").set_controllable (roll_controllable); + stop_button.set_controllable (stop_controllable); + _tools.get_waves_button ("transport_stop_button").set_controllable (stop_controllable); + goto_start_button.set_controllable (goto_start_controllable); + _tools.get_waves_button ("transport_start_button").set_controllable (goto_start_controllable); + goto_end_button.set_controllable (goto_end_controllable); + _tools.get_waves_button ("transport_end_button").set_controllable (goto_end_controllable); + auto_loop_button.set_controllable (auto_loop_controllable); + _tools.get_waves_button ("transport_loop_button").set_controllable (auto_loop_controllable); + play_selection_button.set_controllable (play_selection_controllable); rec_button.set_controllable (rec_controllable); + _tools.get_waves_button ("transport_record_button").set_controllable (rec_controllable); roll_button.set_name ("transport button"); stop_button.set_name ("transport button"); @@ -2120,9 +2143,12 @@ ARDOUR_UI::map_transport_state () { if (!_session) { auto_loop_button.unset_active_state (); + _tools.get_waves_button ("transport_loop_button").set_active (false); play_selection_button.unset_active_state (); roll_button.unset_active_state (); + _tools.get_waves_button ("transport_play_button").set_active (false); stop_button.set_active_state (Gtkmm2ext::ExplicitActive); + _tools.get_waves_button ("transport_stop_button").set_active (true); return; } @@ -2138,23 +2164,29 @@ ARDOUR_UI::map_transport_state () play_selection_button.set_active_state (Gtkmm2ext::ExplicitActive); roll_button.unset_active_state (); + _tools.get_waves_button ("transport_play_button").set_active (true); auto_loop_button.unset_active_state (); - + _tools.get_waves_button ("transport_loop_button").set_active (false); } else if (_session->get_play_loop ()) { auto_loop_button.set_active (true); + _tools.get_waves_button ("transport_loop_button").set_active (true); play_selection_button.set_active (false); if (Config->get_loop_is_mode()) { roll_button.set_active (true); + _tools.get_waves_button ("transport_play_button").set_active (true); } else { roll_button.set_active (false); + _tools.get_waves_button ("transport_play_button").set_active (false); } } else { roll_button.set_active (true); + _tools.get_waves_button ("transport_play_button").set_active (true); play_selection_button.set_active (false); auto_loop_button.set_active (false); + _tools.get_waves_button ("transport_loop_button").set_active (false); } if (Config->get_always_play_range()) { @@ -2164,16 +2196,22 @@ ARDOUR_UI::map_transport_state () } stop_button.set_active (false); + _tools.get_waves_button ("transport_stop_button").set_active (false); } else { stop_button.set_active (true); + _tools.get_waves_button ("transport_stop_button").set_active (true); roll_button.set_active (false); + _tools.get_waves_button ("transport_play_button").set_active (false); + play_selection_button.set_active (false); if (Config->get_loop_is_mode ()) { auto_loop_button.set_active (_session->get_play_loop()); + _tools.get_waves_button ("transport_loop_button").set_active (_session->get_play_loop()); } else { auto_loop_button.set_active (false); + _tools.get_waves_button ("transport_loop_button").set_active (false); } update_disk_space (); } @@ -2452,13 +2490,17 @@ ARDOUR_UI::transport_rec_enable_blink (bool onoff) if (r == Session::Enabled || (r == Session::Recording && !h)) { if (onoff) { rec_button.set_active_state (Gtkmm2ext::ExplicitActive); + _tools.get_waves_button ("transport_record_button").set_active (true); } else { rec_button.set_active_state (Gtkmm2ext::ImplicitActive); - } + _tools.get_waves_button ("transport_record_button").set_active (false); + } } else if (r == Session::Recording && h) { rec_button.set_active_state (Gtkmm2ext::ExplicitActive); + _tools.get_waves_button ("transport_record_button").set_active (true); } else { rec_button.unset_active_state (); + _tools.get_waves_button ("transport_record_button").set_active (false); } } @@ -4130,10 +4172,14 @@ ARDOUR_UI::step_edit_status_change (bool yn) if (yn) { rec_button.set_active_state (Gtkmm2ext::ImplicitActive); + _tools.get_waves_button ("transport_record_button").set_active (true); rec_button.set_sensitive (false); + _tools.get_waves_button ("transport_record_button").set_sensitive (false); } else { - rec_button.unset_active_state ();; + rec_button.unset_active_state (); + _tools.get_waves_button ("transport_record_button").set_active (false); rec_button.set_sensitive (true); + _tools.get_waves_button ("transport_record_button").set_sensitive (true); } } diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index eca63e3f2b..0f466336c7 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -93,6 +93,8 @@ #include "speaker_dialog.h" #include "theme_manager.h" +#include "waves_ui.h" + class VideoTimeLine; class ArdourKeyboard; class AudioClock; @@ -331,6 +333,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr int setup_windows (); void setup_transport (); + void setup_transport_trx (); void setup_clock (); static ARDOUR_UI *theArdourUI; @@ -363,6 +366,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr void about_signal_response(int response); Gtk::VBox top_packer; + Gtk::VBox tracks_tools_packer; sigc::connection clock_signal_connection; void update_clocks (); @@ -438,6 +442,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr ArdourButton play_selection_button; ArdourButton rec_button; + WavesUI::WidgetMap _tools; + void toggle_external_sync (); void toggle_time_master (); void toggle_video_sync (); diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 8dee90182d..8a0ae989df 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -110,8 +110,11 @@ ARDOUR_UI::setup_windows () #else top_packer.pack_start (menu_bar_base, false, false); #endif - - top_packer.pack_start (transport_frame, false, false); + if (ARDOUR::Profile->get_trx()) { + top_packer.pack_start (tracks_tools_packer, false, false); + } else { + top_packer.pack_start (transport_frame, false, false); + } editor->add_toplevel_controls (top_packer); @@ -210,9 +213,229 @@ ARDOUR_UI::tearoff_settings (const char* name) const return 0; } +void +ARDOUR_UI::setup_transport_trx () +{ + RefPtr act; + + transport_tearoff_hbox.set_border_width (3); + transport_tearoff_hbox.set_spacing (3); + + transport_tearoff = manage (new TearOff (transport_tearoff_hbox)); + transport_tearoff->set_name ("TransportBase"); + transport_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &transport_tearoff->tearoff_window()), false); + transport_tearoff->set_can_be_torn_off (false); + + transport_hbox.pack_start (*transport_tearoff, true, false); + + transport_base.set_name ("TransportBase"); + transport_base.add (transport_hbox); + + transport_frame.set_shadow_type (SHADOW_OUT); + transport_frame.set_name ("BaseFrame"); + transport_frame.add (transport_base); + + transport_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::detach_tearoff), static_cast(&top_packer), + static_cast(&transport_frame))); + transport_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::reattach_tearoff), static_cast (&top_packer), + static_cast (&transport_frame), 1)); + transport_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::detach_tearoff), static_cast(&top_packer), + static_cast(&transport_frame))); + transport_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::reattach_tearoff), static_cast (&top_packer), + static_cast (&transport_frame), 1)); + + auto_return_button.set_text(_("Auto Return")); + + follow_edits_button.set_text(_("Follow Edits")); + + click_button.set_image (get_icon (X_("metronome"))); + act = ActionManager::get_action ("Transport", "ToggleClick"); + click_button.set_related_action (act); + click_button.signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::click_button_clicked), false); + + auto_return_button.set_name ("transport option button"); + follow_edits_button.set_name ("transport option button"); + auto_input_button.set_name ("transport option button"); + + /* these have to provide a clear indication of active state */ + + click_button.set_name ("transport button"); + + stop_button.set_active (true); + _tools.get_waves_button ("transport_stop_button").set_active (true); + + goto_start_button.set_image (get_icon (X_("transport_start"))); + goto_end_button.set_image (get_icon (X_("transport_end"))); + roll_button.set_image (get_icon (X_("transport_play"))); + stop_button.set_image (get_icon (X_("transport_stop"))); + play_selection_button.set_image (get_icon (X_("transport_range"))); + rec_button.set_image (get_icon (X_("transport_record"))); + auto_loop_button.set_image (get_icon (X_("transport_loop"))); + + midi_panic_button.set_image (get_icon (X_("midi_panic"))); + /* the icon for this has an odd aspect ratio, so fatten up the button */ + midi_panic_button.set_size_request (25, -1); + + act = ActionManager::get_action (X_("Transport"), X_("Stop")); + stop_button.set_related_action (act); + _tools.get_waves_button ("transport_stop_button").set_related_action (act); + + act = ActionManager::get_action (X_("Transport"), X_("Roll")); + roll_button.set_related_action (act); + _tools.get_waves_button ("transport_play_button").set_related_action (act); + + act = ActionManager::get_action (X_("Transport"), X_("Record")); + rec_button.set_related_action (act); + _tools.get_waves_button ("transport_record_button").set_related_action (act); + + act = ActionManager::get_action (X_("Transport"), X_("GotoStart")); + goto_start_button.set_related_action (act); + _tools.get_waves_button ("transport_start_button").set_related_action (act); + + act = ActionManager::get_action (X_("Transport"), X_("GotoEnd")); + goto_end_button.set_related_action (act); + _tools.get_waves_button ("transport_end_button").set_related_action (act); + + act = ActionManager::get_action (X_("Transport"), X_("Loop")); + auto_loop_button.set_related_action (act); + _tools.get_waves_button ("transport_loop_button").set_related_action (act); + act = ActionManager::get_action (X_("Transport"), X_("PlaySelection")); + play_selection_button.set_related_action (act); + act = ActionManager::get_action (X_("MIDI"), X_("panic")); + midi_panic_button.set_related_action (act); + act = ActionManager::get_action (X_("Transport"), X_("ToggleExternalSync")); + + /* clocks, etc. */ + + ARDOUR_UI::Clock.connect (sigc::mem_fun (primary_clock, &AudioClock::set)); + ARDOUR_UI::Clock.connect (sigc::mem_fun (secondary_clock, &AudioClock::set)); + + primary_clock->ValueChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::primary_clock_value_changed)); + secondary_clock->ValueChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::secondary_clock_value_changed)); + big_clock->ValueChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::big_clock_value_changed)); + + act = ActionManager::get_action ("Transport", "ToggleAutoReturn"); + auto_return_button.set_related_action (act); + act = ActionManager::get_action (X_("Transport"), X_("ToggleFollowEdits")); + follow_edits_button.set_related_action (act); + act = ActionManager::get_action ("Transport", "ToggleAutoInput"); + auto_input_button.set_related_action (act); + + /* alerts */ + + /* CANNOT sigc::bind these to clicked or toggled, must use pressed or released */ + + solo_alert_button.set_name ("rude solo"); + solo_alert_button.signal_button_press_event().connect (sigc::mem_fun(*this,&ARDOUR_UI::solo_alert_press), false); + auditioning_alert_button.set_name ("rude audition"); + auditioning_alert_button.signal_button_press_event().connect (sigc::mem_fun(*this,&ARDOUR_UI::audition_alert_press), false); + feedback_alert_button.set_name ("feedback alert"); + feedback_alert_button.signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::feedback_alert_press), false); + + alert_box.pack_start (solo_alert_button, true, false); + alert_box.pack_start (auditioning_alert_button, true, false); + alert_box.pack_start (feedback_alert_button, true, false); + + /* all transport buttons should be the same size vertically and + * horizontally + */ + + Glib::RefPtr transport_button_size_group = SizeGroup::create (SIZE_GROUP_BOTH); + transport_button_size_group->add_widget (goto_start_button); + transport_button_size_group->add_widget (goto_end_button); + transport_button_size_group->add_widget (auto_loop_button); + transport_button_size_group->add_widget (rec_button); + transport_button_size_group->add_widget (play_selection_button); + transport_button_size_group->add_widget (roll_button); + transport_button_size_group->add_widget (stop_button); + + goto_start_button.set_size_request (33, 25); + + HBox* tbox1 = manage (new HBox); + HBox* tbox2 = manage (new HBox); + HBox* tbox = manage (new HBox); + + VBox* vbox1 = manage (new VBox); + VBox* vbox2 = manage (new VBox); + + Alignment* a1 = manage (new Alignment); + Alignment* a2 = manage (new Alignment); + + tbox1->set_spacing (2); + tbox2->set_spacing (2); + tbox->set_spacing (2); + + tbox1->pack_start (goto_start_button, false, false); + tbox1->pack_start (goto_end_button, false, false); + tbox1->pack_start (auto_loop_button, false, false); + + tbox2->pack_start (roll_button, false, false); + tbox2->pack_start (stop_button, false, false); + tbox2->pack_start (rec_button, false, false, 5); + + vbox1->pack_start (*tbox1, false, false); + vbox2->pack_start (*tbox2, false, false); + + a1->add (*vbox1); + a1->set (0.5, 1.0, 0.0, 0.0); + a2->add (*vbox2); + a2->set (0.5, 1.0, 0.0, 0.0); + + tbox->pack_start (*a1, false, false); + tbox->pack_start (*a2, false, false); + + HBox* clock_box = manage (new HBox); + + clock_box->pack_start (*primary_clock, false, false); + if (!ARDOUR::Profile->get_small_screen() && !ARDOUR::Profile->get_trx()) { + clock_box->pack_start (*secondary_clock, false, false); + } + + clock_box->set_spacing (3); + + shuttle_box = new ShuttleControl; + shuttle_box->show (); + + VBox* transport_vbox = manage (new VBox); + transport_vbox->set_name ("TransportBase"); + transport_vbox->set_border_width (0); + transport_vbox->set_spacing (3); + transport_vbox->pack_start (*tbox, true, true, 0); + + time_info_box = manage (new TimeInfoBox); + VBox& tv_box = *manage (new VBox); + HBox& th_box = *manage (new HBox); + transport_tearoff_hbox.pack_start (tv_box, false, false); + tv_box.pack_start (th_box, false, false); + th_box.pack_start (*time_info_box, false, false); + th_box.pack_start (*clock_box, false, false); + tv_box.pack_start (*transport_vbox, false, false); + + + /* transport related toggle controls */ + + VBox* auto_box = manage (new VBox); + auto_box->set_homogeneous (true); + auto_box->set_spacing (2); + transport_tearoff_hbox.pack_start (*auto_box, false, false); + // NO NEED TO HAVE IT: auto_box->pack_start (sync_button, false, false); + if (ARDOUR::Profile->get_small_screen()) { + transport_tearoff_hbox.pack_start (_editor_transport_box, false, false); + } + + /* desensitize */ + + set_transport_sensitivity (false); +} + void ARDOUR_UI::setup_transport () { + if (Profile->get_trx()) { + setup_transport_trx(); + return; + } + RefPtr act; transport_tearoff_hbox.set_border_width (3); @@ -331,17 +554,17 @@ ARDOUR_UI::setup_transport () /* all transport buttons should be the same size vertically and * horizontally */ + int width = 33; + int height = 25; + goto_start_button.set_size_request (width, height); + goto_end_button.set_size_request (width, height); + auto_loop_button.set_size_request (width, height); + rec_button.set_size_request (width, height); + play_selection_button.set_size_request (width, height); + roll_button.set_size_request (width, height); + stop_button.set_size_request (width, height); - Glib::RefPtr transport_button_size_group = SizeGroup::create (SIZE_GROUP_BOTH); - transport_button_size_group->add_widget (goto_start_button); - transport_button_size_group->add_widget (goto_end_button); - transport_button_size_group->add_widget (auto_loop_button); - transport_button_size_group->add_widget (rec_button); - transport_button_size_group->add_widget (play_selection_button); - transport_button_size_group->add_widget (roll_button); - transport_button_size_group->add_widget (stop_button); - - goto_start_button.set_size_request (-1, 40); + goto_start_button.set_size_request (width, height); HBox* tbox1 = manage (new HBox); HBox* tbox2 = manage (new HBox); diff --git a/gtk2_ardour/icons/inspector_on.png b/gtk2_ardour/icons/inspector_on.png new file mode 100644 index 0000000000..cbcc1fa48f Binary files /dev/null and b/gtk2_ardour/icons/inspector_on.png differ diff --git a/gtk2_ardour/icons/inspector_on_active.png b/gtk2_ardour/icons/inspector_on_active.png new file mode 100644 index 0000000000..8a68f61e14 Binary files /dev/null and b/gtk2_ardour/icons/inspector_on_active.png differ diff --git a/gtk2_ardour/icons/inspector_on_prelight.png b/gtk2_ardour/icons/inspector_on_prelight.png new file mode 100644 index 0000000000..18fc476395 Binary files /dev/null and b/gtk2_ardour/icons/inspector_on_prelight.png differ diff --git a/gtk2_ardour/icons/mixer_on.png b/gtk2_ardour/icons/mixer_on.png new file mode 100644 index 0000000000..e207a8a2b1 Binary files /dev/null and b/gtk2_ardour/icons/mixer_on.png differ diff --git a/gtk2_ardour/icons/mixer_on_active.png b/gtk2_ardour/icons/mixer_on_active.png new file mode 100644 index 0000000000..6e9c63610b Binary files /dev/null and b/gtk2_ardour/icons/mixer_on_active.png differ diff --git a/gtk2_ardour/icons/mixer_on_prelight.png b/gtk2_ardour/icons/mixer_on_prelight.png new file mode 100644 index 0000000000..01a0fab721 Binary files /dev/null and b/gtk2_ardour/icons/mixer_on_prelight.png differ diff --git a/gtk2_ardour/icons/transport_end.png b/gtk2_ardour/icons/transport_end.png index ccba11809f..ba20d49d9b 100644 Binary files a/gtk2_ardour/icons/transport_end.png and b/gtk2_ardour/icons/transport_end.png differ diff --git a/gtk2_ardour/icons/transport_end_active.png b/gtk2_ardour/icons/transport_end_active.png new file mode 100644 index 0000000000..dec7761b98 Binary files /dev/null and b/gtk2_ardour/icons/transport_end_active.png differ diff --git a/gtk2_ardour/icons/transport_end_prelight.png b/gtk2_ardour/icons/transport_end_prelight.png new file mode 100644 index 0000000000..9c0de57adf Binary files /dev/null and b/gtk2_ardour/icons/transport_end_prelight.png differ diff --git a/gtk2_ardour/icons/transport_loop.png b/gtk2_ardour/icons/transport_loop.png index c2831c1012..6501814c95 100644 Binary files a/gtk2_ardour/icons/transport_loop.png and b/gtk2_ardour/icons/transport_loop.png differ diff --git a/gtk2_ardour/icons/transport_loop_active.png b/gtk2_ardour/icons/transport_loop_active.png new file mode 100644 index 0000000000..21a71dcb45 Binary files /dev/null and b/gtk2_ardour/icons/transport_loop_active.png differ diff --git a/gtk2_ardour/icons/transport_loop_prelight.png b/gtk2_ardour/icons/transport_loop_prelight.png new file mode 100644 index 0000000000..bb4b30a7cc Binary files /dev/null and b/gtk2_ardour/icons/transport_loop_prelight.png differ diff --git a/gtk2_ardour/icons/transport_play.png b/gtk2_ardour/icons/transport_play.png index 07e89695e5..397467d9e4 100644 Binary files a/gtk2_ardour/icons/transport_play.png and b/gtk2_ardour/icons/transport_play.png differ diff --git a/gtk2_ardour/icons/transport_play_active.png b/gtk2_ardour/icons/transport_play_active.png new file mode 100644 index 0000000000..617026f016 Binary files /dev/null and b/gtk2_ardour/icons/transport_play_active.png differ diff --git a/gtk2_ardour/icons/transport_play_prelight.png b/gtk2_ardour/icons/transport_play_prelight.png new file mode 100644 index 0000000000..5ed902dbd5 Binary files /dev/null and b/gtk2_ardour/icons/transport_play_prelight.png differ diff --git a/gtk2_ardour/icons/transport_record.png b/gtk2_ardour/icons/transport_record.png index f92b60730d..14ec665991 100644 Binary files a/gtk2_ardour/icons/transport_record.png and b/gtk2_ardour/icons/transport_record.png differ diff --git a/gtk2_ardour/icons/transport_record_active.png b/gtk2_ardour/icons/transport_record_active.png new file mode 100644 index 0000000000..2b92d11b54 Binary files /dev/null and b/gtk2_ardour/icons/transport_record_active.png differ diff --git a/gtk2_ardour/icons/transport_record_prelight.png b/gtk2_ardour/icons/transport_record_prelight.png new file mode 100644 index 0000000000..9872def26d Binary files /dev/null and b/gtk2_ardour/icons/transport_record_prelight.png differ diff --git a/gtk2_ardour/icons/transport_start.png b/gtk2_ardour/icons/transport_start.png index fe05dc2c39..997b5ff3c7 100644 Binary files a/gtk2_ardour/icons/transport_start.png and b/gtk2_ardour/icons/transport_start.png differ diff --git a/gtk2_ardour/icons/transport_start_active.png b/gtk2_ardour/icons/transport_start_active.png new file mode 100644 index 0000000000..5f361abaa4 Binary files /dev/null and b/gtk2_ardour/icons/transport_start_active.png differ diff --git a/gtk2_ardour/icons/transport_start_prelight.png b/gtk2_ardour/icons/transport_start_prelight.png new file mode 100644 index 0000000000..e08e0feeff Binary files /dev/null and b/gtk2_ardour/icons/transport_start_prelight.png differ diff --git a/gtk2_ardour/icons/transport_stop.png b/gtk2_ardour/icons/transport_stop.png index 05562b1060..1503434cad 100644 Binary files a/gtk2_ardour/icons/transport_stop.png and b/gtk2_ardour/icons/transport_stop.png differ diff --git a/gtk2_ardour/icons/transport_stop_active.png b/gtk2_ardour/icons/transport_stop_active.png new file mode 100644 index 0000000000..db3df74a2f Binary files /dev/null and b/gtk2_ardour/icons/transport_stop_active.png differ diff --git a/gtk2_ardour/icons/transport_stop_prelight.png b/gtk2_ardour/icons/transport_stop_prelight.png new file mode 100644 index 0000000000..8da755cace Binary files /dev/null and b/gtk2_ardour/icons/transport_stop_prelight.png differ diff --git a/gtk2_ardour/ui/tracks_tools.xml b/gtk2_ardour/ui/tracks_tools.xml new file mode 100644 index 0000000000..a2a53730f3 --- /dev/null +++ b/gtk2_ardour/ui/tracks_tools.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + diff --git a/gtk2_ardour/waves_button.h b/gtk2_ardour/waves_button.h index 4c953f7f11..9dcc7c3f75 100644 --- a/gtk2_ardour/waves_button.h +++ b/gtk2_ardour/waves_button.h @@ -16,8 +16,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef __gtk2_waves_ardour_button_h__ -#define __gtk2_waves_ardour_button_h__ +#ifndef __gtk2_waves_button_h__ +#define __gtk2_waves_button_h__ #include #include @@ -74,11 +74,6 @@ class WavesButton : public CairoWidget , public Gtkmm2ext::Activatable void controllable_changed (); PBD::ScopedConnection watch_connection; - private: - Glib::RefPtr _layout; - std::string _text; - BindingProxy binding_proxy; - int _text_width; int _text_height; float _corner_radius; @@ -101,6 +96,12 @@ class WavesButton : public CairoWidget , public Gtkmm2ext::Activatable void action_sensitivity_changed (); void action_visibility_changed (); void action_tooltip_changed (); + +private: + Glib::RefPtr _layout; + std::string _text; + BindingProxy binding_proxy; + }; -#endif /* __gtk2_waves_ardour_button_h__ */ +#endif /* __gtk2_waves_button_h__ */ diff --git a/gtk2_ardour/waves_icon_button.cc b/gtk2_ardour/waves_icon_button.cc new file mode 100644 index 0000000000..1b303e8998 --- /dev/null +++ b/gtk2_ardour/waves_icon_button.cc @@ -0,0 +1,145 @@ +/* + 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 "gtkmm2ext/utils.h" +#include "gtkmm2ext/rgb_macros.h" +#include "gtkmm2ext/gui_thread.h" + +#include "ardour/rc_configuration.h" // for widget prelight preference + +#include "waves_icon_button.h" +#include "ardour_ui.h" +#include "global_signals.h" + +#include "i18n.h" + +#define REFLECTION_HEIGHT 2 + +using namespace Gdk; +using namespace Gtk; +using namespace Glib; +using namespace PBD; +using std::max; +using std::min; +using namespace std; + +WavesIconButton::WavesIconButton () + : WavesButton() +{ +} + +WavesIconButton::~WavesIconButton() +{ +} + + +void +WavesIconButton::render (cairo_t* cr) +{ + void (*rounded_function)(cairo_t*, double, double, double, double, double); + + switch (_corner_mask) { + case 0x1: /* upper left only */ + rounded_function = Gtkmm2ext::rounded_top_left_rectangle; + break; + case 0x2: /* upper right only */ + rounded_function = Gtkmm2ext::rounded_top_right_rectangle; + break; + case 0x3: /* upper only */ + rounded_function = Gtkmm2ext::rounded_top_rectangle; + break; + /* should really have functions for lower right, lower left, + lower only, but for now, we don't + */ + default: + rounded_function = Gtkmm2ext::rounded_rectangle; + } + + Glib::RefPtr style = get_style(); + + Gdk::Color bgcolor = style->get_bg ((get_state() == Gtk::STATE_INSENSITIVE) ? Gtk::STATE_INSENSITIVE : + (_hovering ? + (_pushed ? + Gtk::STATE_ACTIVE : + Gtk::STATE_PRELIGHT ) : + (get_active() ? + Gtk::STATE_ACTIVE : + Gtk::STATE_NORMAL))); + + Glib::RefPtr pixbuf = (get_state() == Gtk::STATE_INSENSITIVE) ? (_inactive_pixbuf ? _inactive_pixbuf : _normal_pixbuf) : + (_hovering ? + (_pushed ? + (_active_pixbuf ? _active_pixbuf : _normal_pixbuf) : + (_prelight_pixbuf ? _prelight_pixbuf : _normal_pixbuf)) : + (get_active() ? + (_active_pixbuf ? _active_pixbuf : _normal_pixbuf) : + _normal_pixbuf)); + + if ((_left_border_width != 0) || + (_top_border_width != 0) || + (_right_border_width != 0) || + (_bottom_border_width != 0)) { + cairo_set_source_rgba (cr, _border_color.get_red_p(), _border_color.get_blue_p(), _border_color.get_green_p(), 1); + rounded_function (cr, 0, 0, get_width(), get_height(), _corner_radius); + cairo_fill (cr); + } + + rounded_function (cr, _left_border_width, _top_border_width, get_width()-_left_border_width-_right_border_width, get_height()-_top_border_width-_bottom_border_width, _corner_radius); + cairo_set_source_rgba (cr, bgcolor.get_red_p(), bgcolor.get_green_p(), bgcolor.get_blue_p(), 1); + cairo_fill (cr); + + // pixbuf, if any + if (pixbuf) { + double x,y; + x = (get_width() - pixbuf->get_width())/2.0; + y = (get_height() - pixbuf->get_height())/2.0; + + cairo_rectangle (cr, x, y, pixbuf->get_width(), pixbuf->get_height()); + gdk_cairo_set_source_pixbuf (cr, pixbuf->gobj(), x, y); + cairo_fill (cr); + } +} + +void +WavesIconButton::set_normal_image (const RefPtr& img) +{ + _normal_pixbuf = img; + queue_draw (); +} + +void +WavesIconButton::set_active_image (const RefPtr& img) +{ + _active_pixbuf = img; + queue_draw (); +} + +void +WavesIconButton::set_inactive_image (const RefPtr& img) +{ + _inactive_pixbuf = img; + queue_draw (); +} + +void +WavesIconButton::set_prelight_image (const RefPtr& img) +{ + _prelight_pixbuf = img; + queue_draw (); +} diff --git a/gtk2_ardour/waves_icon_button.h b/gtk2_ardour/waves_icon_button.h new file mode 100644 index 0000000000..15b8352d0a --- /dev/null +++ b/gtk2_ardour/waves_icon_button.h @@ -0,0 +1,45 @@ +/* + 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_waves_icon_button_h__ +#define __gtk2_waves_icon_button_h__ + +#include "waves_button.h" + +class WavesIconButton : public WavesButton +{ + public: + WavesIconButton (); + virtual ~WavesIconButton (); + + void set_normal_image (const Glib::RefPtr& img); + void set_active_image (const Glib::RefPtr& img); + void set_inactive_image (const Glib::RefPtr& img); + void set_prelight_image (const Glib::RefPtr& img); + + protected: + void render (cairo_t *); + + private: + Glib::RefPtr _normal_pixbuf; + Glib::RefPtr _active_pixbuf; + Glib::RefPtr _inactive_pixbuf; + Glib::RefPtr _prelight_pixbuf; +}; + +#endif /* __gtk2_waves_icon_button_h__ */ diff --git a/gtk2_ardour/waves_ui.cc b/gtk2_ardour/waves_ui.cc index 3cd849dfa2..870b952e32 100644 --- a/gtk2_ardour/waves_ui.cc +++ b/gtk2_ardour/waves_ui.cc @@ -22,6 +22,7 @@ #include "waves_ui.h" #include "pbd/file_utils.h" #include "ardour/filesystem_paths.h" +#include "utils.h" #include "pbd/convert.h" #include "dbg_msg.h" @@ -42,9 +43,32 @@ WavesUI::create_widget (const XMLNode& definition, const XMLNodeMap& styles, std std::transform(widget_type.begin(), widget_type.end(), widget_type.begin(), ::toupper); if (widget_type == "BUTTON") { - child = manage (new WavesButton(text)); - ((WavesButton*)child)->set_border_width (xml_property (definition, "borderwidth", styles, "0").c_str()); - ((WavesButton*)child)->set_border_color (xml_property (definition, "bordercolor", styles, "#000000").c_str()); + WavesButton& button = *manage (new WavesButton(text)); + child = &button; + button.set_border_width (xml_property (definition, "borderwidth", styles, "0").c_str()); + button.set_border_color (xml_property (definition, "bordercolor", styles, "#000000").c_str()); + } else if (widget_type == "ICONBUTTON") { + WavesIconButton& iconbutton = *manage (new WavesIconButton); + child = &iconbutton; + iconbutton.set_border_width (xml_property (definition, "borderwidth", styles, "0").c_str()); + iconbutton.set_border_color (xml_property (definition, "bordercolor", styles, "#000000").c_str()); + + std::string property = xml_property (definition, "normalicon", styles, ""); + if (!property.empty ()) { + iconbutton.set_normal_image(get_icon(property.c_str())); + } + property = xml_property (definition, "activeicon", styles, ""); + if (!property.empty ()) { + iconbutton.set_active_image(get_icon(property.c_str())); + } + property = xml_property (definition, "prelighticon", styles, ""); + if (!property.empty ()) { + iconbutton.set_prelight_image(get_icon(property.c_str())); + } + property = xml_property (definition, "inactiveicon", styles, ""); + if (!property.empty ()) { + iconbutton.set_inactive_image(get_icon(property.c_str())); + } } else if (widget_type == "COMBOBOXTEXT") { child = manage (new Gtk::ComboBoxText); } else if (widget_type == "LABEL") { @@ -212,47 +236,47 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X widget.set_size_request (width, height); std::string property = xml_property (definition, "bgnormal", styles, ""); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_bg(Gtk::STATE_NORMAL, Gdk::Color(property)); } property = xml_property (definition, "bgdisabled", styles, property); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_bg(Gtk::STATE_INSENSITIVE, Gdk::Color(property)); } property = xml_property (definition, "bgactive", styles, ""); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_bg(Gtk::STATE_ACTIVE, Gdk::Color(property)); } property = xml_property (definition, "bghover", styles, ""); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_bg(Gtk::STATE_PRELIGHT, Gdk::Color(property)); } property = xml_property (definition, "fgnormal", styles, ""); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_fg(Gtk::STATE_NORMAL, Gdk::Color(property)); } property = xml_property (definition, "fgdisabled", styles, property); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_fg(Gtk::STATE_INSENSITIVE, Gdk::Color(property)); } property = xml_property (definition, "fgactive", styles, ""); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_fg(Gtk::STATE_ACTIVE, Gdk::Color(property)); } property = xml_property (definition, "fghover", styles, ""); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_fg(Gtk::STATE_PRELIGHT, Gdk::Color(property)); } property = xml_property (definition, "font", styles, ""); - if (!property.empty()) { + if (!property.empty ()) { widget.modify_font(Pango::FontDescription(property)); } @@ -261,6 +285,12 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X } else { widget.hide(); } + + Gtk::Box* box = dynamic_cast (&widget); + if (box) + { + box->set_spacing(xml_property (definition, "spacing", styles, 0)); + } } diff --git a/gtk2_ardour/waves_ui.h b/gtk2_ardour/waves_ui.h index f460c3474f..ebaab4906d 100644 --- a/gtk2_ardour/waves_ui.h +++ b/gtk2_ardour/waves_ui.h @@ -30,6 +30,7 @@ #include "canvas/canvas.h" #include "canvas/xml_ui.h" #include "waves_button.h" +#include "waves_icon_button.h" using namespace ArdourCanvas::XMLUI; namespace WavesUI { diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index e48c4805f0..84b4a734ac 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -35,6 +35,7 @@ gtk2_ardour_sources = [ 'analysis_window.cc', 'ardour_button.cc', 'waves_button.cc', + 'waves_icon_button.cc', 'ardour_dialog.cc', 'waves_dialog.cc', 'ardour_ui.cc',