diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc index b6654a9747..ae2c1a8749 100644 --- a/gtk2_ardour/ardour_button.cc +++ b/gtk2_ardour/ardour_button.cc @@ -971,7 +971,7 @@ ArdourButton::on_focus_out_event (GdkEventFocus* ev) bool ArdourButton::on_key_release_event (GdkEventKey *ev) { - if (_focused && (ev->keyval == GDK_KEY_space || ev->keyval == GDK_Return)) { + if (_focused && (ev->keyval == GDK_space || ev->keyval == GDK_Return)) { signal_clicked(); if (_action) { _action->activate (); diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 20e0a338cd..b094d84049 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -211,10 +211,16 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , error_log_button (_("Errors")) , _status_bar_visibility (X_("status-bar")) , _feedback_exists (false) - , _dsp_load_adjustment (0) + , _dsp_load_adjustment (0) + , _hd_load_adjustment (0) + , _dsp_load_label(0) + , _hd_load_label(0) + , _hd_remained_time_label(0) , editor (0) , mixer (0) - //, meterbridge (0) + , _bit_depth_button(0) + , _sample_rate_button(0) + , _frame_rate_button(0) , splash (0) { Gtkmm2ext::init(localedir); @@ -314,6 +320,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) ARDOUR::GUIIdle.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::gui_idle_handler, this), gui_context()); + EngineStateController::instance()->SampleRateChanged.connect_same_thread (update_connections_to_toolbar_buttons, boost::bind (&ARDOUR_UI::update_sample_rate_button, this) ); + EngineStateController::instance()->EngineRunning.connect_same_thread (update_connections_to_toolbar_buttons, boost::bind (&ARDOUR_UI::update_sample_rate_button, this) ); + /* lets get this party started */ setup_gtk_ardour_enums (); @@ -436,6 +445,7 @@ ARDOUR_UI::engine_running () } update_disk_space (); + update_disk_usage (); update_cpu_load (); update_sample_rate (EngineStateController::instance()->get_current_sample_rate() ); update_timecode_format (); @@ -1092,6 +1102,7 @@ ARDOUR_UI::every_second () update_cpu_load (); update_buffer_load (); update_disk_space (); + update_disk_usage (); update_timecode_format (); if (nsm && nsm->is_active ()) { @@ -1236,6 +1247,10 @@ ARDOUR_UI::update_cpu_load () snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), c >= 90 ? X_("red") : X_("green"), c); cpu_load_label.set_markup (buf); _dsp_load_adjustment->set_value (c); + + stringstream ss; + ss << (int)c; + _dsp_load_label->set_text ( ss.str() + "%" ); } void @@ -1279,6 +1294,8 @@ ARDOUR_UI::count_recenabled_streams (Route& route) void ARDOUR_UI::update_disk_space() { + string result; + if (_session == 0) { return; } @@ -1295,9 +1312,11 @@ ARDOUR_UI::update_disk_space() if (!opt_frames) { /* Available space is unknown */ snprintf (buf, sizeof (buf), "%s", _("Disk: Unknown")); + result = "Unknown"; } else if (opt_frames.get_value_or (0) == max_framecnt) { snprintf (buf, sizeof (buf), "%s", _("Disk: 24hrs+")); - } else { + result = "24hrs+"; + } else { rec_enabled_streams = 0; _session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams); @@ -1305,7 +1324,9 @@ ARDOUR_UI::update_disk_space() if (rec_enabled_streams) { frames /= rec_enabled_streams; - } + } else { + frames /= _session->nroutes (); + } int hrs; int mins; @@ -1315,7 +1336,8 @@ ARDOUR_UI::update_disk_space() if (hrs > 24) { snprintf (buf, sizeof (buf), "%s", _("Disk: >24 hrs")); - } else { + result =">24hrs"; + } else { frames -= hrs * fr * 3600; mins = frames / (fr * 60); frames -= mins * fr * 60; @@ -1329,10 +1351,29 @@ ARDOUR_UI::update_disk_space() low ? X_("red") : X_("green"), hrs, mins, secs ); + + stringstream ss; + ss << hrs << "h " << mins << "m "; + result = ss.str(); } } disk_space_label.set_markup (buf); + _hd_remained_time_label->set_text(result); +} + +void +ARDOUR_UI::update_disk_usage () +{ + if (_session == 0) { + return; + } + + uint32_t const hd_buffer = 100 - (_session ? _session->capture_load () : 100); + _hd_load_adjustment->set_value (hd_buffer); + stringstream ss; + ss << hd_buffer; + _hd_load_label->set_text ( ss.str() + "%" ); } void @@ -2206,6 +2247,7 @@ ARDOUR_UI::map_transport_state () editor->get_waves_button ("transport_loop_button").set_active (false); } update_disk_space (); + update_disk_usage (); } } @@ -2946,7 +2988,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri continue; } - int pos = full_session_name.rfind(suffix); + size_t pos = full_session_name.rfind(suffix); // if not *.ardour file was choosen if( !(pos == full_session_name.size() - suffix.size()) ) @@ -4622,3 +4664,25 @@ ARDOUR_UI::transport_numpad_event (int num) } } } + +void +ARDOUR_UI::open_media_folder () +{ + if (!_session) { + return; + } + +#if defined (PLATFORM_WINDOWS) + //ShellExecute (NULL, "open", _session->session_directory ().sources_root ().c_str (), NULL, NULL, SW_SHOW); + ShellExecute (NULL, "open", _session->session_directory ().sound_path ().c_str (), NULL, NULL, SW_SHOW); +#elif defined (__APPLE__) + //std::string command = "open \"" + _session->session_directory ().sources_root () + "\""; + std::string command = "open \"" + _session->session_directory ().sound_path () + "\""; + system (command.c_str ()); +#else + + /* nix */ + /* XXX what to do here ? */ + +#endif +} diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 13c1f6039d..40147535fe 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -148,6 +148,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr void launch_reference (); void show_about (); void hide_about (); + void open_media_folder (); void idle_load (const std::string& path); void finish(); @@ -226,6 +227,17 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr void focus_on_clock (); AudioClock* big_clock; + WavesButton* _bit_depth_button; + WavesButton* _sample_rate_button; + WavesButton* _frame_rate_button; + void on_bit_depth_button (WavesButton*); + void on_sample_rate_button (WavesButton*); + void on_frame_rate_button (WavesButton*); + void update_bit_depth_button (); + void update_sample_rate_button (); + void update_frame_rate_button (); + PBD::ScopedConnectionList update_connections_to_toolbar_buttons; + TimeInfoBox* time_info_box; VideoTimeLine *video_timeline; @@ -546,6 +558,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr Gtk::Label disk_space_label; void update_disk_space (); + void update_disk_usage (); Gtk::Label timecode_format_label; @@ -771,6 +784,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr VisibilityGroup _status_bar_visibility; Gtk::Adjustment* _dsp_load_adjustment; + Gtk::Adjustment* _hd_load_adjustment; + Gtk::Label* _dsp_load_label; + Gtk::Label* _hd_load_label; + Gtk::Label* _hd_remained_time_label; /** A ProcessThread so that we have some thread-local buffers for use by * PluginEqGui::impulse_analysis (). diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 716c7e2fe9..56f76e2c95 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -243,8 +243,11 @@ ARDOUR_UI::setup_transport () act = ActionManager::get_action (X_("Common"), X_("toggle-meterbridge")); editor->get_waves_button ("meter_bridge_on_button").set_related_action (act); - - update_output_operation_mode_buttons(); + + act = ActionManager::get_action (X_("Common"), X_("OpenMediaFolder")); + editor->get_waves_button ("media_button").set_related_action (act); + + update_output_operation_mode_buttons(); transport_base.set_name ("TransportBase"); transport_base.add (transport_hbox); diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 30ba8ff8bd..b41acab714 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -227,6 +227,10 @@ ARDOUR_UI::set_session (Session *s) editor_meter_peak_display.show(); } } + + update_bit_depth_button (); + update_sample_rate_button (); + update_frame_rate_button (); } int @@ -396,9 +400,11 @@ ARDOUR_UI::toggle_meterbridge () mixer_tact->set_active(false); editor->get_container ("edit_pane").hide (); editor->get_container ("meter_bridge_view_home").show (); + editor->get_container ("compact_meter_bridge_home").hide (); } else { editor->get_container ("meter_bridge_view_home").hide (); editor->get_container ("edit_pane").show (); + editor->get_container ("compact_meter_bridge_home").show (); } } diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index e901bddd6a..3f11f85091 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -66,6 +66,7 @@ #include "control_protocol/control_protocol.h" #include "i18n.h" +#include "utils.h" using namespace std; using namespace ARDOUR; @@ -80,11 +81,24 @@ ARDOUR_UI::create_editor () try { editor = new Editor (); _dsp_load_adjustment = &editor->get_adjustment ("dsp_load_adjustment"); - } + _hd_load_adjustment = &editor->get_adjustment("hd_load_adjustment"); + + _dsp_load_label = &editor->get_label("dsp_load_label"); + _hd_load_label = &editor->get_label("hd_load_label"); + _hd_remained_time_label = &editor->get_label("hd_remained_time"); + + _bit_depth_button = &editor->get_waves_button("bit_depth_button"); + _sample_rate_button = &editor->get_waves_button("sample_rate_button"); + _frame_rate_button = &editor->get_waves_button("frame_rate_button"); + } catch (failed_constructor& err) { return -1; } + + _bit_depth_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_bit_depth_button)); + _sample_rate_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_sample_rate_button)); + _frame_rate_button->signal_clicked.connect(sigc::mem_fun (*this, &ARDOUR_UI::on_frame_rate_button)); editor->Realized.connect (sigc::mem_fun (*this, &ARDOUR_UI::editor_realized)); editor->signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), true)); @@ -92,6 +106,85 @@ ARDOUR_UI::create_editor () return 0; } +void +ARDOUR_UI::on_bit_depth_button (WavesButton*) +{ + tracks_control_panel->show (); +} + +void +ARDOUR_UI::on_sample_rate_button (WavesButton*) +{ + tracks_control_panel->show (); +} + +void +ARDOUR_UI::on_frame_rate_button (WavesButton*) +{ + tracks_control_panel->show (); +} + +void +ARDOUR_UI::update_bit_depth_button () +{ + if( _session && _bit_depth_button ) + { + string file_data_format; + switch (_session->config.get_native_file_data_format ()) { + case FormatFloat: + file_data_format = "32 bit"; + break; + case FormatInt24: + file_data_format = "24 bit"; + break; + case FormatInt16: + file_data_format = "16 bit"; + break; + } + _bit_depth_button->set_text (file_data_format); + } +} + +void +ARDOUR_UI::update_sample_rate_button () +{ + if( !_sample_rate_button ) + return; + + std::string active_sr = ARDOUR_UI_UTILS::rate_as_string(EngineStateController::instance()->get_current_sample_rate()); + _sample_rate_button->set_text (active_sr); +} + +void +ARDOUR_UI::update_frame_rate_button () +{ + if( !_frame_rate_button ) + return; + + string timecode_format_string; + switch( _timecode_format ) { + case Timecode::timecode_24: + timecode_format_string = "24 fps"; + break; + case Timecode::timecode_25: + timecode_format_string = "25 fps"; + break; + case Timecode::timecode_30: + timecode_format_string = "30 fps"; + break; + case Timecode::timecode_23976: + timecode_format_string = "23.976 fps"; + break; + case Timecode::timecode_2997: + timecode_format_string = "29.97 fps"; + break; + default: + break; + } + + _frame_rate_button->set_text (timecode_format_string); +} + void ARDOUR_UI::install_actions () { @@ -216,6 +309,8 @@ ARDOUR_UI::install_actions () ActionManager::register_action (common_actions, X_("Manual"), S_("Help|Manual"), mem_fun(*this, &ARDOUR_UI::launch_manual)); ActionManager::register_action (common_actions, X_("Reference"), _("Reference"), mem_fun(*this, &ARDOUR_UI::launch_reference)); + ActionManager::register_action (common_actions, X_("OpenMediaFolder"), _("OpenMediaFolder"), mem_fun(*this, &ARDOUR_UI::open_media_folder)); + act = ActionManager::register_action (common_actions, X_("Save"), _("Save"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::save_state), string(""), false)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::write_sensitive_actions.push_back (act); diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 7d9c526503..135d41fe13 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -425,10 +425,20 @@ ARDOUR_UI::parameter_changed (std::string p) void ARDOUR_UI::session_parameter_changed (const std::string& param) { - if (param == "native-file-data-format" || param == "native-file-header-format") + if ( param == "native-file-data-format" ) + { update_format(); - if ( param == "timecode-format") + update_bit_depth_button (); + } + else if (param == "native-file-header-format") + { + update_format(); + } + else if ( param == "timecode-format" ) + { update_timecode_format(); + update_frame_rate_button (); + } } void diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index d544c1bd1a..14eb15329a 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1293,7 +1293,7 @@ Editor::update_title () namespace { const size_t mixer_bridge_strip_max_name_size = 9; - const size_t meter_bridge_strip_max_name_size = 6; + const size_t meter_bridge_strip_max_name_size = 8; } void Editor::set_session (Session *t) diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index fa1cdd1929..1270f738f9 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -702,7 +702,9 @@ EditorRoutes::routes_added (list routes) (*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context()); (*x)->route()->solo_safe_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_safe_display, this), gui_context()); (*x)->route()->active_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_active_display, this), gui_context ()); - + + // connect to DnD reordering signal + (*x)->relative_tracks_reorder_request.connect(*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::move_selected_tracks_relatively, this, _1, _2, _3), gui_context()); } update_rec_display (); @@ -1570,6 +1572,80 @@ EditorRoutes::move_selected_tracks (bool up) _model->reorder (neworder); } +void +EditorRoutes::move_selected_tracks_relatively (const PBD::ID& source_track_id, const PBD::ID& target_track_id, bool after_target) +{ + if (source_track_id == target_track_id) { + return; + } + + RouteTimeAxisView* source_rtv = _editor->get_route_view_by_route_id(source_track_id); + Selection& selection = _editor->get_selection(); + + RouteList routes; + RouteList routes_to_move; + TreeModel::Children rows = _model->children(); + + for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri) { + + boost::shared_ptr route = (*ri)[_columns.route]; + TimeAxisView* tv = (*ri)[_columns.tv]; + + // selected tracks: add to the move list but if it's not a target + if (selection.selected(tv) && + route->id() != target_track_id) { + routes_to_move.push_back(route); + continue; + } + + // master track should always be the first + RouteTimeAxisView* rtv = dynamic_cast(tv); + if (rtv->is_master_track() ) { + routes.push_front(route); + } else { + routes.push_back (route); + } + } + + RouteList::iterator insert_position; + for (RouteList::iterator iter = routes.begin(); iter != routes.end(); ++iter) { + if ((*iter)->id() == target_track_id ) { + insert_position = iter; + break; + } + } + + // insert the pack of tracks to be moved to the correct possition + if (after_target) { + ++insert_position; + } + routes.insert(insert_position, routes_to_move.begin(), routes_to_move.end() ); + + std::vector neworder; + + for (RouteList::const_iterator iter = routes.begin(); iter != routes.end(); ++iter) { + uint32_t order = (*iter)->order_key (); + neworder.push_back (order); + } + +#ifndef NDEBUG + DEBUG_TRACE (DEBUG::OrderKeys, "New order after moving tracks:\n"); + for (vector::iterator i = neworder.begin(); i != neworder.end(); ++i) { + DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("\t%1\n", *i)); + } + DEBUG_TRACE (DEBUG::OrderKeys, "-------\n"); + + for (vector::iterator i = neworder.begin(); i != neworder.end(); ++i) { + if (*i >= (int) neworder.size()) { + cerr << "Trying to move something to " << *i << " of " << neworder.size() << endl; + } + assert (*i < (int) neworder.size ()); + } +#endif + + _model->reorder (neworder); +} + void EditorRoutes::update_input_active_display () { diff --git a/gtk2_ardour/editor_routes.h b/gtk2_ardour/editor_routes.h index 3def0804a5..0046ba741f 100644 --- a/gtk2_ardour/editor_routes.h +++ b/gtk2_ardour/editor_routes.h @@ -36,6 +36,8 @@ public: } void move_selected_tracks (bool); + void move_selected_tracks_relatively (const PBD::ID& source_track_id, const PBD::ID& target_track_id, bool after_target); + void show_track_in_display (TimeAxisView &); void suspend_redisplay () { diff --git a/gtk2_ardour/icons/ardour-app-icon_osx.png b/gtk2_ardour/icons/ardour-app-icon_osx.png index f428f2972d..fc1227aa12 100644 Binary files a/gtk2_ardour/icons/ardour-app-icon_osx.png and b/gtk2_ardour/icons/ardour-app-icon_osx.png differ diff --git a/gtk2_ardour/icons/ardour_icon_16px.png b/gtk2_ardour/icons/ardour_icon_16px.png index 8e40f74600..ef6a2a9133 100644 Binary files a/gtk2_ardour/icons/ardour_icon_16px.png and b/gtk2_ardour/icons/ardour_icon_16px.png differ diff --git a/gtk2_ardour/icons/ardour_icon_22px.png b/gtk2_ardour/icons/ardour_icon_22px.png index 815ba545d6..a92cf33350 100644 Binary files a/gtk2_ardour/icons/ardour_icon_22px.png and b/gtk2_ardour/icons/ardour_icon_22px.png differ diff --git a/gtk2_ardour/icons/ardour_icon_256px.png b/gtk2_ardour/icons/ardour_icon_256px.png index e4a3a5aba5..1139334969 100644 Binary files a/gtk2_ardour/icons/ardour_icon_256px.png and b/gtk2_ardour/icons/ardour_icon_256px.png differ diff --git a/gtk2_ardour/icons/ardour_icon_32px.png b/gtk2_ardour/icons/ardour_icon_32px.png index ed30d4b8ba..3b1049fc8c 100644 Binary files a/gtk2_ardour/icons/ardour_icon_32px.png and b/gtk2_ardour/icons/ardour_icon_32px.png differ diff --git a/gtk2_ardour/icons/ardour_icon_48px.png b/gtk2_ardour/icons/ardour_icon_48px.png index 15aa6b575b..0f3d2e93e8 100644 Binary files a/gtk2_ardour/icons/ardour_icon_48px.png and b/gtk2_ardour/icons/ardour_icon_48px.png differ diff --git a/gtk2_ardour/icons/fader_touch_cursor.png b/gtk2_ardour/icons/fader_touch_cursor.png new file mode 100644 index 0000000000..1fbe812659 Binary files /dev/null and b/gtk2_ardour/icons/fader_touch_cursor.png differ diff --git a/gtk2_ardour/icons/lock_session.png b/gtk2_ardour/icons/lock_session.png index bc46b5c511..ab3c172244 100644 Binary files a/gtk2_ardour/icons/lock_session.png and b/gtk2_ardour/icons/lock_session.png differ diff --git a/gtk2_ardour/icons/lock_session_active.png b/gtk2_ardour/icons/lock_session_active.png index 6df328bb0d..a21148da12 100644 Binary files a/gtk2_ardour/icons/lock_session_active.png and b/gtk2_ardour/icons/lock_session_active.png differ diff --git a/gtk2_ardour/icons/lock_session_prelight.png b/gtk2_ardour/icons/lock_session_prelight.png index 019f68696d..f8fbf2176c 100644 Binary files a/gtk2_ardour/icons/lock_session_prelight.png and b/gtk2_ardour/icons/lock_session_prelight.png differ diff --git a/gtk2_ardour/icons/metrics_display.png b/gtk2_ardour/icons/metrics_display.png index 272b1cad4f..e5b100111d 100644 Binary files a/gtk2_ardour/icons/metrics_display.png and b/gtk2_ardour/icons/metrics_display.png differ diff --git a/gtk2_ardour/icons/panner_touch_cursor.png b/gtk2_ardour/icons/panner_touch_cursor.png new file mode 100644 index 0000000000..1fbe812659 Binary files /dev/null and b/gtk2_ardour/icons/panner_touch_cursor.png differ diff --git a/gtk2_ardour/icons/tracks.png b/gtk2_ardour/icons/tracks.png index 628e8ce88e..342269cad3 100644 Binary files a/gtk2_ardour/icons/tracks.png and b/gtk2_ardour/icons/tracks.png differ diff --git a/gtk2_ardour/icons/tracks_active.png b/gtk2_ardour/icons/tracks_active.png index 628e8ce88e..0f7ca3cefc 100644 Binary files a/gtk2_ardour/icons/tracks_active.png and b/gtk2_ardour/icons/tracks_active.png differ diff --git a/gtk2_ardour/icons/tracks_prelight.png b/gtk2_ardour/icons/tracks_prelight.png index 628e8ce88e..a793f3b4f8 100644 Binary files a/gtk2_ardour/icons/tracks_prelight.png and b/gtk2_ardour/icons/tracks_prelight.png differ diff --git a/gtk2_ardour/icons/transport_end.png b/gtk2_ardour/icons/transport_end.png index 6e98a9a826..98635738c6 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 index cd3938c4f5..b4c765b4e7 100644 Binary files a/gtk2_ardour/icons/transport_end_active.png 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 index 3e8fbcb849..cb38d8f198 100644 Binary files a/gtk2_ardour/icons/transport_end_prelight.png 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 f32d645056..68360eeef7 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 index 6e11357d00..99fdc10b75 100644 Binary files a/gtk2_ardour/icons/transport_loop_active.png 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 index 07c71869ea..bc3a747194 100644 Binary files a/gtk2_ardour/icons/transport_loop_prelight.png 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 07bb37bf80..3c7eef079e 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 index aff12e3534..693ea4686d 100644 Binary files a/gtk2_ardour/icons/transport_play_active.png 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 index 8bc99c8f52..eae6f09626 100644 Binary files a/gtk2_ardour/icons/transport_play_prelight.png 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 0186439071..612efe51f7 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 index 6e79744141..083d91962d 100644 Binary files a/gtk2_ardour/icons/transport_record_active.png 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 index 48862c7a2b..468ec173c8 100644 Binary files a/gtk2_ardour/icons/transport_record_prelight.png 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 7946e11799..655387986c 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 index 156df0087a..313c199eb7 100644 Binary files a/gtk2_ardour/icons/transport_start_active.png 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 index f0636bb644..855b5eeca0 100644 Binary files a/gtk2_ardour/icons/transport_start_prelight.png 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 0023a52e39..59a2681ac5 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 index e919e6d29f..9d67d09bad 100644 Binary files a/gtk2_ardour/icons/transport_stop_active.png 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 index 9d1fd8425d..03e783b761 100644 Binary files a/gtk2_ardour/icons/transport_stop_prelight.png and b/gtk2_ardour/icons/transport_stop_prelight.png differ diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index fac74072ad..a2f5817cfe 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -126,26 +126,48 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, const std::string& layout_s } } -string cut_string(const string& route_name, size_t max_name_size) -{ - if ( max_name_size == 0 ) - return route_name; - - string cutted_route_name; - - if ( route_name.size()<=max_name_size ) +namespace { + bool is_vowel_letter(char letter) { - cutted_route_name = route_name; - } - else - { - cutted_route_name.assign(route_name, 0, max_name_size-3); - cutted_route_name += "..."; + if( letter=='a' || letter=='e' || letter=='i' || letter=='o' || + letter=='q' || letter=='u' || letter=='y') + return true; + return false; } - return cutted_route_name; + string cut_string(string route_name, size_t max_name_size) + { + if ( max_name_size == 0 ) + return route_name; + + string cutted_route_name; + + if ( route_name.size()<=max_name_size ) + { + cutted_route_name = route_name; + } + else + { + // first step: delete vowel letters + int i = route_name.size()-1; // iterator + while( i >= 0 && route_name.size() > max_name_size ) + { + if( is_vowel_letter( route_name[i] ) ) + route_name.erase(i, 1); + else + --i; + } + + if ( route_name.size()<=max_name_size ) + cutted_route_name = route_name; + else // second step: leave only first letters + cutted_route_name.assign(route_name, 0, max_name_size); + } + + return cutted_route_name; + } } - + MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, boost::shared_ptr rt, const std::string& layout_script_file, size_t max_name_size) : AxisView(sess) , RouteUI (sess, layout_script_file) diff --git a/gtk2_ardour/mono_panner.cc b/gtk2_ardour/mono_panner.cc index e42e11b7b2..c934581e1d 100644 --- a/gtk2_ardour/mono_panner.cc +++ b/gtk2_ardour/mono_panner.cc @@ -52,12 +52,14 @@ using namespace Gtk; using namespace Gtkmm2ext; using namespace ARDOUR_UI_UTILS; +Gdk::Cursor* MonoPanner::__touch_cursor; + MonoPanner::MonoPanner (boost::shared_ptr p) : PannerInterface (p->panner()) , _panner_shell (p) , position_control (_panner->pannable()->pan_azimuth_control) - , drag_start_x (0) - , last_drag_x (0) + , drag_start_y (0) + , last_drag_y (0) , accumulated_delta (0) , detented (false) , position_binder (position_control) @@ -70,6 +72,13 @@ MonoPanner::MonoPanner (boost::shared_ptr p) } } + if (__touch_cursor == 0) { + __touch_cursor = new Gdk::Cursor (Gdk::Display::get_default(), + ::get_icon ("panner_touch_cursor"), + 12, + 12); + } + position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&MonoPanner::value_change, this), gui_context()); _panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&MonoPanner::bypass_handler, this), gui_context()); @@ -127,12 +136,15 @@ MonoPanner::on_button_press_event (GdkEventButton* ev) if (PannerInterface::on_button_press_event (ev)) { return true; } + if (_panner_shell->bypassed()) { return false; } - drag_start_x = ev->x; - last_drag_x = ev->x; + get_window()->set_cursor (*__touch_cursor); + + drag_start_y = ev->y; + last_drag_y = ev->y; _dragging = false; _tooltip.target_stop_drag (); @@ -203,6 +215,8 @@ MonoPanner::on_button_release_event (GdkEventButton* ev) return false; } + get_window()->set_cursor(); + _dragging = false; _tooltip.target_stop_drag (); accumulated_delta = 0; @@ -261,7 +275,7 @@ MonoPanner::on_motion_notify_event (GdkEventMotion* ev) } int w = get_width(); - double delta = (ev->x - last_drag_x) / (double) w; + double delta = (last_drag_y - ev->y) / (double) w; /* create a detent close to the center */ @@ -286,7 +300,7 @@ MonoPanner::on_motion_notify_event (GdkEventMotion* ev) position_control->set_value (pv + delta); } - last_drag_x = ev->x; + last_drag_y = ev->y; return true; } diff --git a/gtk2_ardour/mono_panner.h b/gtk2_ardour/mono_panner.h index 3a8533835d..afe9fe0a8c 100644 --- a/gtk2_ardour/mono_panner.h +++ b/gtk2_ardour/mono_panner.h @@ -62,8 +62,8 @@ class MonoPanner : public PannerInterface boost::shared_ptr position_control; PBD::ScopedConnectionList panvalue_connections; PBD::ScopedConnectionList panshell_connections; - int drag_start_x; - int last_drag_x; + int drag_start_y; + int last_drag_y; double accumulated_delta; bool detented; @@ -73,6 +73,8 @@ class MonoPanner : public PannerInterface bool _dragging; + static Gdk::Cursor* __touch_cursor; + void bypass_handler (); void pannable_handler (); }; diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index b8ed4dd99f..280d51b0a8 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -90,6 +90,7 @@ using namespace Editing; using namespace std; using std::list; + RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, ArdourCanvas::Canvas& canvas, @@ -111,15 +112,20 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, , color_mode_menu (0) , gm (sess, "track_header_gain_meter.xml") , _ignore_set_layer_display (false) + , _ignore_dnd_requests (false) , gain_meter_home (get_box ("gain_meter_home")) , selected_track_color_box (get_container ("selected_track_color_box")) , track_color_box (get_container ("track_color_box")) + , upper_drop_indicator(get_event_box ("upper_drop_indicator")) + , lower_drop_indicator(get_event_box ("lower_drop_indicator")) { } void RouteTimeAxisView::set_route (boost::shared_ptr rt) { + disable_header_dnd (); + RouteUI::set_route (rt); CANVAS_DEBUG_NAME (_canvas_display, string_compose ("main for %1", rt->name())); @@ -168,6 +174,8 @@ RouteTimeAxisView::set_route (boost::shared_ptr rt) if (is_master_track() ) { // do not display number for master track TimeAxisView::set_number_is_hidden(true); + } else { + enable_header_dnd (); } playlist_button.set_visible(is_track() && track()->mode() == ARDOUR::Normal); @@ -1106,6 +1114,73 @@ RouteTimeAxisView::speed_changed () Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteTimeAxisView::reset_samples_per_pixel, this)); } +bool +RouteTimeAxisView::handle_route_drag_motion(const Glib::RefPtr& context, int x, int y, guint time) +{ + // check if the target of the drop is expected by our drop zone + if (RouteUI::header_target.get_target () == drag_dest_find_target (context) && + drag_get_source_widget(context) != this) { + + context->drag_status(context->get_suggested_action(), time); + + if (context->get_suggested_action() ) { + + int height = get_height(); + + if (y <= height/2) { + upper_drop_indicator.show(); + lower_drop_indicator.hide(); + } else { + lower_drop_indicator.show(); + upper_drop_indicator.hide(); + } + + return true; + } + } + + context->drag_refuse(time); + return false; +} + +void +RouteTimeAxisView::handle_route_drag_leave(const Glib::RefPtr& context, guint time) +{ + upper_drop_indicator.hide(); + lower_drop_indicator.hide(); +} + +void +RouteTimeAxisView::handle_route_drag_begin (const Glib::RefPtr& context) +{ + _ebox_release_can_act = false; + + // mark dragged track selected anyway + if (!_editor.get_selection().selected(this) ) { + _editor.get_selection().clear_tracks(); + _editor.get_selection().add(this); + } + + //GZ TO-DO: Draw DnD icon for track header +} + +void +RouteTimeAxisView::handle_route_drag_end(const Glib::RefPtr& context) +{ +} + +void +RouteTimeAxisView::handle_route_drag_data_received(const Glib::RefPtr& context, int x, int y, const SelectionData& selection_data, guint info, guint time) +{ + PBD::ID source_route_id = selection_data.get_data_as_string (); + + // emit signal + int height = get_height(); + relative_tracks_reorder_request(source_route_id, _route->id(), y > height/2 ); + + context->drop_finish(true, time); +} + void RouteTimeAxisView::update_diskstream_display () { @@ -1119,34 +1194,63 @@ RouteTimeAxisView::update_diskstream_display () void RouteTimeAxisView::selection_click (GdkEventButton* ev) { - if (Keyboard::modifier_state_equals (ev->state, (Keyboard::TertiaryModifier|Keyboard::PrimaryModifier))) { + if (dnd_in_progress() ) { + return; + } + + if (ev->type == GDK_BUTTON_PRESS) { - /* special case: select/deselect all tracks */ - if (_editor.get_selection().selected (this)) { - _editor.get_selection().clear_tracks (); - } else { - _editor.select_all_tracks (); + if (Keyboard::modifier_state_equals (ev->state, (Keyboard::TertiaryModifier|Keyboard::PrimaryModifier))) { + + /* special case: select/deselect all tracks */ + if (_editor.get_selection().selected (this)) { + _editor.get_selection().clear_tracks (); + } else { + _editor.select_all_tracks (); + } + + return; } - return; - } - switch (ArdourKeyboard::selection_type (ev->state)) { - case Selection::Toggle: - _editor.get_selection().toggle (this); - break; + switch (ArdourKeyboard::selection_type (ev->state)) { + case Selection::Toggle: + _editor.get_selection().toggle (this); + break; - case Selection::Set: - _editor.get_selection().set (this); - break; + case Selection::Set: + if (!_editor.get_selection().selected (this)) { + _editor.get_selection().set (this); + } + break; - case Selection::Extend: - _editor.extend_selection_to_track (*this); - break; + case Selection::Extend: + _editor.extend_selection_to_track (*this); + break; - case Selection::Add: - _editor.get_selection().add (this); - break; + case Selection::Add: + _editor.get_selection().add (this); + break; + } + + } else if (ev->type == GDK_BUTTON_RELEASE) { + + switch (ArdourKeyboard::selection_type (ev->state)) { + case Selection::Toggle: + break; + + case Selection::Set: + if (_editor.get_selection().selected (this)) { + _editor.get_selection().set (this); + } + break; + + case Selection::Extend: + break; + + case Selection::Add: + break; + } } } @@ -2557,3 +2661,22 @@ RouteTimeAxisView::remove_child (boost::shared_ptr c) } } } + +void +RouteTimeAxisView::control_ebox_resize_started() +{ + if (dnd_operation_enabled () ) { + _ignore_dnd_requests = true; + disable_header_dnd (); + } + +} + +void +RouteTimeAxisView::control_ebox_resize_ended() +{ + if (_ignore_dnd_requests ) { + _ignore_dnd_requests = false; + enable_header_dnd (); + } +} diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index 21648fb2dd..33d34f5ada 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -149,6 +149,14 @@ public: std::string state_id() const; + void set_ignore_dnd_requests(bool ignore) {_ignore_dnd_requests = ignore; } + bool check_ignore_dnd_requests() {return _ignore_dnd_requests; } + + virtual void control_ebox_resize_started(); + virtual void control_ebox_resize_ended(); + + PBD::Signal3 relative_tracks_reorder_request; + protected: friend class StreamView; @@ -176,7 +184,13 @@ protected: ~ProcessorAutomationInfo (); }; - + // DnD heandlers for route header + virtual void handle_route_drag_begin (const Glib::RefPtr& context); + virtual void handle_route_drag_end(const Glib::RefPtr& context); + virtual void handle_route_drag_data_received (const Glib::RefPtr& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time); + virtual bool handle_route_drag_motion (const Glib::RefPtr& context, int x, int y, guint time); + virtual void handle_route_drag_leave (const Glib::RefPtr& context, guint time); + void update_diskstream_display (); gint route_group_click (GdkEventButton *); @@ -252,7 +266,10 @@ protected: StreamView* _view; ArdourCanvas::Canvas& parent_canvas; bool no_redraw; - + + Gtk::EventBox& upper_drop_indicator; + Gtk::EventBox& lower_drop_indicator; + WavesButton& route_group_button; WavesButton& playlist_button; WavesButton& automation_button; @@ -305,6 +322,7 @@ protected: UnderlayMirrorList _underlay_mirrors; bool _ignore_set_layer_display; + bool _ignore_dnd_requests; private: diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 70188525a5..e37b9dcd60 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -64,6 +64,8 @@ using namespace ARDOUR; using namespace ARDOUR_UI_UTILS; using namespace PBD; +Gtk::TargetEntry RouteUI::header_target("HEADER", (Gtk::TargetFlags)0 ,ROUTE_HEADER); + uint32_t RouteUI::_max_invert_buttons = 3; PBD::Signal1 > RouteUI::BusSendDisplayChanged; boost::weak_ptr RouteUI::_showing_sends_to; @@ -83,6 +85,8 @@ RouteUI::RouteUI (ARDOUR::Session* sess, const std::string& layout_script_file) , rec_enable_button (get_waves_button ("rec_enable_button")) , show_sends_button (get_waves_button ("show_sends_button")) , monitor_input_button (get_waves_button ("monitor_input_button")) + , _dnd_operation_in_progress (false) + , _dnd_operation_enabled (false) { set_attributes (*this, *xml_tree ()->root (), XMLNodeMap ()); if (sess) init (); @@ -151,6 +155,18 @@ RouteUI::init () monitor_input_button.signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release)); BusSendDisplayChanged.connect_same_thread (*this, boost::bind(&RouteUI::bus_send_display_changed, this, _1)); + + // DnD callbacks + // source side + signal_drag_begin().connect (sigc::mem_fun(*this, &RouteUI::on_route_drag_begin)); + signal_drag_data_get().connect (sigc::mem_fun(*this, &RouteUI::on_route_drag_data_get)); + signal_drag_begin().connect (sigc::mem_fun(*this, &RouteUI::on_route_drag_end)); + + // destination callbacks + signal_drag_motion().connect (sigc::mem_fun(*this, &RouteUI::on_route_drag_motion)); + signal_drag_leave().connect (sigc::mem_fun(*this, &RouteUI::on_route_drag_leave)); + signal_drag_drop().connect (sigc::mem_fun(*this, &RouteUI::on_route_drag_drop)); + signal_drag_data_received().connect (sigc::mem_fun(*this, &RouteUI::on_route_drag_data_received)); } void @@ -173,6 +189,11 @@ RouteUI::self_delete () delete this; } +namespace { + size_t default_palette_color = 9; + size_t master_color = 3; +} + void RouteUI::set_route (boost::shared_ptr rp) { @@ -185,10 +206,20 @@ RouteUI::set_route (boost::shared_ptr rp) Editor* editor = dynamic_cast( &(ARDOUR_UI::instance()->the_editor()) ); if( editor!=NULL && editor->set_session_in_progress() ) - color = MixerStrip::palette_random_color(); + { + if( _route->is_master() ) + color = (Gdk::Color)(MixerStrip::XMLColor[master_color]); + else + color = MixerStrip::palette_random_color(); + } else - color = (Gdk::Color)(MixerStrip::XMLColor[14]); - + { + if( _route->is_master() ) + color = (Gdk::Color)(MixerStrip::XMLColor[master_color]); + else + color = (Gdk::Color)(MixerStrip::XMLColor[default_palette_color]); + } + set_color (color); } @@ -267,6 +298,88 @@ RouteUI::set_route (boost::shared_ptr rp) update_solo_display (); } +void RouteUI::enable_header_dnd () +{ + std::vector targets; + targets.push_back(header_target); + drag_source_set(targets, Gdk::BUTTON1_MASK); + drag_dest_set(targets, DEST_DEFAULT_HIGHLIGHT); + _dnd_operation_enabled = true; +} + +bool RouteUI::disable_header_dnd () +{ + // disable DnD operations + drag_source_unset (); + drag_dest_unset (); + _dnd_operation_enabled = false; +} + +void +RouteUI::on_route_drag_begin(const Glib::RefPtr& context) +{ + _dnd_operation_in_progress = true; + handle_route_drag_begin(context); +} + +void +RouteUI::on_route_drag_end(const Glib::RefPtr& context) +{ + _dnd_operation_in_progress = false; + handle_route_drag_end(context); +} + +void +RouteUI::on_route_drag_data_get(const Glib::RefPtr& context, Gtk::SelectionData& selection_data, guint info, guint time) +{ + switch (info) + { + case RouteUI::ROUTE_HEADER: + { + // Put route id, if we have a route + if (_route) { + std::string route_id_string =_route->id().to_s(); + selection_data.set(8, (const guint8*)route_id_string.c_str(), route_id_string.length() + 1 ); + break; + } + } + + default: + break; + } +} + +bool +RouteUI::on_route_drag_motion(const Glib::RefPtr& context, int x, int y, guint time) +{ + return handle_route_drag_motion(context, x, y, time); +} + +void +RouteUI::on_route_drag_leave(const Glib::RefPtr& context, guint time) +{ + handle_route_drag_leave(context, time); +} + +bool +RouteUI::on_route_drag_drop(const Glib::RefPtr& context, int x, int y, guint time) +{ + if (RouteUI::header_target.get_target () == drag_dest_find_target (context) ) + { + // request the data from the source: + drag_get_data (context, RouteUI::header_target.get_target (), time ); + return true; + } + + return false; +} + +void +RouteUI::on_route_drag_data_received(const Glib::RefPtr& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time) +{ + handle_route_drag_data_received(context, x, y, selection_data, info, time); +} + void RouteUI::polarity_changed () { diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index dd8000bf79..5837e13ee4 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -56,6 +56,14 @@ class ArdourButton; class RouteUI : public Gtk::EventBox, public WavesUI, public virtual AxisView { public: + + enum { + ROUTE_HEADER + // add more targets here + } DnDTargets; + + static Gtk::TargetEntry header_target; + RouteUI(ARDOUR::Session*, const std::string& layout_script_file); virtual ~RouteUI(); @@ -65,6 +73,35 @@ class RouteUI : public Gtk::EventBox, public WavesUI, public virtual AxisView virtual void set_route (boost::shared_ptr); virtual void set_button_names () = 0; + // DnD + void enable_header_dnd (); + bool disable_header_dnd (); + bool dnd_operation_enabled () { return _dnd_operation_enabled; } + + // DnD callback handlers: + // source callbacks + void on_route_drag_begin(const Glib::RefPtr& context); + void on_route_drag_data_get(const Glib::RefPtr& context, Gtk::SelectionData& selection_data, guint info, guint time); + void on_route_drag_end(const Glib::RefPtr& context); + + // destination callbacks + bool on_route_drag_motion(const Glib::RefPtr& context, int x, int y, guint time); + void on_route_drag_leave(const Glib::RefPtr& context, guint time); + bool on_route_drag_drop(const Glib::RefPtr& context, int x, int y, guint time); + void on_route_drag_data_received(const Glib::RefPtr& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time); + + // HANDLERS WHICH MUST BE DEFINED in inheriting class for DnD support + // define in inheriting class if you want custom drag icon to be set + virtual void handle_route_drag_begin(const Glib::RefPtr& context) {}; + // define in inheriting class if you want actions on dnd end + virtual void handle_route_drag_end(const Glib::RefPtr& context) {}; + // define this in inheriting class to provide the responce on a draging above the widget + virtual bool handle_route_drag_motion(const Glib::RefPtr& context, int x, int y, guint time) { context->drag_refuse(time); return false; }; + // define this in inheriting class to provide the responce on a leaving the widget with drag + virtual void handle_route_drag_leave(const Glib::RefPtr& context, guint time) {}; + // define this in inheriting class to provide the responce and actions on the destination side + virtual void handle_route_drag_data_received(const Glib::RefPtr& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time) {context->drop_finish(false, time); }; + bool is_track() const; bool is_audio_track() const; bool is_master_track() const; @@ -93,7 +130,6 @@ class RouteUI : public Gtk::EventBox, public WavesUI, public virtual AxisView bool wait_for_release; bool multiple_mute_change; bool multiple_solo_change; - WavesButton& master_mute_button; WavesButton& mute_button; WavesButton& solo_button; @@ -225,6 +261,8 @@ class RouteUI : public Gtk::EventBox, public WavesUI, public virtual AxisView */ static PBD::Signal1 > BusSendDisplayChanged; + bool dnd_in_progress() {return _dnd_operation_in_progress; } + protected: PBD::ScopedConnectionList route_connections; bool self_destruct; @@ -281,6 +319,9 @@ class RouteUI : public Gtk::EventBox, public WavesUI, public virtual AxisView static boost::weak_ptr _showing_sends_to; static uint32_t _max_invert_buttons; + + bool _dnd_operation_in_progress; + bool _dnd_operation_enabled; }; #endif /* __ardour_route_ui__ */ diff --git a/gtk2_ardour/small-splash.png b/gtk2_ardour/small-splash.png index 58284482ac..7537d0757a 100644 Binary files a/gtk2_ardour/small-splash.png and b/gtk2_ardour/small-splash.png differ diff --git a/gtk2_ardour/splash.png b/gtk2_ardour/splash.png index dc072ebcb3..fb27714b75 100644 Binary files a/gtk2_ardour/splash.png and b/gtk2_ardour/splash.png differ diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index d664b77f0c..f9f83ac587 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -338,10 +338,15 @@ TimeAxisView::controls_ebox_button_press (GdkEventButton* event) } + if (event->button == 1) { + selection_click (event); + } + _ebox_release_can_act = true; if (maybe_set_cursor (event->y) > 0) { _resize_drag_start = event->y_root; + control_ebox_resize_started(); } return true; @@ -358,7 +363,7 @@ bool TimeAxisView::controls_ebox_motion (GdkEventMotion* ev) { if (_resize_drag_start >= 0) { - + /* (ab)use the DragManager to do autoscrolling - basically we * are pretending that the drag is taking place over the canvas * (which perhaps in the glorious future, when track headers @@ -429,6 +434,7 @@ TimeAxisView::controls_ebox_button_release (GdkEventButton* ev) } _editor.stop_canvas_autoscroll (); _resize_drag_start = -1; + control_ebox_resize_ended(); } if (!_ebox_release_can_act) { @@ -1201,7 +1207,7 @@ TimeAxisView::preset_height (Height h) case HeightLarge: return 66; case HeightNormal: - return 44; + return 45; case HeightSmall: return 22; case HeightMaximum: diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index 10cb719875..cb41b84586 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -227,6 +227,7 @@ class TimeAxisView : public virtual AxisView bool _number_is_hidden; bool _hidden; bool in_destructor; + bool _ebox_release_can_act; Gtk::Menu* _size_menu; ArdourCanvas::Container* _canvas_display; double _y_position; @@ -256,6 +257,10 @@ class TimeAxisView : public virtual AxisView virtual bool controls_ebox_motion (GdkEventMotion*); virtual bool controls_ebox_leave (GdkEventCrossing*); + // Define in inheriting class to rect on control ebox resizing + virtual void control_ebox_resize_started() {} + virtual void control_ebox_resize_ended() {} + /** Display the standard LHS control menu at when. * * @param when the popup activation time @@ -294,7 +299,6 @@ private: double _resize_drag_start; GdkCursor* _preresize_cursor; bool _have_preresize_cursor; - bool _ebox_release_can_act; static uint32_t button_height; static uint32_t extra_height; diff --git a/gtk2_ardour/tracks_control_panel.logic.cc b/gtk2_ardour/tracks_control_panel.logic.cc index 17b9ac5c6a..112777a227 100644 --- a/gtk2_ardour/tracks_control_panel.logic.cc +++ b/gtk2_ardour/tracks_control_panel.logic.cc @@ -939,7 +939,7 @@ TracksControlPanel::cleanup_output_channels_list() } playback_controls.pop_back(); - _device_capture_list.remove(*item); + _device_playback_list.remove(*item); delete item; } } diff --git a/gtk2_ardour/ui/add_tracks_dialog.xml b/gtk2_ardour/ui/add_tracks_dialog.xml index b7bbbaf40a..a8f7d585a4 100644 --- a/gtk2_ardour/ui/add_tracks_dialog.xml +++ b/gtk2_ardour/ui/add_tracks_dialog.xml @@ -62,15 +62,15 @@ text="CANCEL" x="0" y="155" - width="70" + width="69" height="25"/>