diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 0b676c6f84..8c1b2bcb04 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -163,6 +163,29 @@ bool drag_failed (const Glib::RefPtr& context, DragResult resu void ARDOUR_UI::setup_transport () { + /* NOTE - LIVETRAX does not call this */ + + RefPtr act; + /* setup actions */ + + /* CANNOT sigc::bind these to clicked or toggled, must use pressed or released */ + error_alert_button.signal_button_release_event().connect (sigc::mem_fun(*this,&ARDOUR_UI::error_alert_press), false); + act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window")); + error_alert_button.set_related_action(act); + error_alert_button.set_fallthrough_to_parent(true); + +#ifndef LIVETRAX + editor_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-editor-visibility"))); + mixer_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-mixer-visibility"))); + prefs_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-preferences-visibility"))); + recorder_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-recorder-visibility"))); + trigger_page_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-trigger-visibility"))); +#endif + + /* connect signals */ + ARDOUR_UI::Clock.connect (sigc::bind (sigc::mem_fun (primary_clock, &MainClock::set), false)); + ARDOUR_UI::Clock.connect (sigc::bind (sigc::mem_fun (secondary_clock, &MainClock::set), false)); + editor_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), editor)); mixer_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), mixer)); #ifndef LIVETRAX diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc index eb203cc86d..c60ab5c3bf 100644 --- a/gtk2_ardour/ardour_ui_dependents.cc +++ b/gtk2_ardour/ardour_ui_dependents.cc @@ -525,6 +525,11 @@ ARDOUR_UI::livetrax_setup_windows () act = ActionManager::get_action (X_("Common"), X_("open-media-folder")); livetrax_view_in_folder_button->set_related_action (act); + error_alert_button.signal_button_release_event().connect (sigc::mem_fun(*this,&ARDOUR_UI::error_alert_press), false); + act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window")); + error_alert_button.set_related_action(act); + error_alert_button.set_fallthrough_to_parent(true); + _main_window.signal_delete_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::main_window_delete_event)); /* pack the main vpacker into the main window and show everything diff --git a/gtk2_ardour/audio_route_properties_box.cc b/gtk2_ardour/audio_route_properties_box.cc new file mode 100644 index 0000000000..849bcece32 --- /dev/null +++ b/gtk2_ardour/audio_route_properties_box.cc @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011-2017 Paul Davis + * Copyright (C) 2024 Ben Loftis + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "pbd/compose.h" +#include + +#include "gtkmm2ext/actions.h" +#include "gtkmm2ext/gui_thread.h" +#include "gtkmm2ext/utils.h" + +#include "ardour/location.h" +#include "ardour/profile.h" +#include "ardour/session.h" + +#include "audio_clock.h" +#include "automation_line.h" +#include "control_point.h" +#include "editor.h" +#include "region_view.h" + +#include "audio_route_properties_box.h" + +#include "pbd/i18n.h" + +using namespace Gtk; +using namespace ARDOUR; +using namespace ArdourWidgets; +using std::max; +using std::min; + +AudioRoutePropertiesBox::AudioRoutePropertiesBox () +{ + _header_label.set_text (_("AUDIO Region Properties:")); + + Gtk::Table* audio_t = manage (new Gtk::Table ()); + audio_t->set_homogeneous (true); + audio_t->set_spacings (4); + + pack_start (*audio_t); +} + +AudioRoutePropertiesBox::~AudioRoutePropertiesBox () +{ +} diff --git a/gtk2_ardour/audio_route_properties_box.h b/gtk2_ardour/audio_route_properties_box.h new file mode 100644 index 0000000000..1625508e11 --- /dev/null +++ b/gtk2_ardour/audio_route_properties_box.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 Paul Davis + * Copyright (C) 2024 Ben Loftis + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include + +#include +#include +#include + +#include "ardour/ardour.h" +#include "ardour/session_handle.h" + +#include "widgets/ardour_button.h" + +#include "gtkmm2ext/cairo_packer.h" + +#include "route_properties_box.h" + +class AudioRoutePropertiesBox : public RoutePropertiesBox +{ +public: + AudioRoutePropertiesBox (); + ~AudioRoutePropertiesBox (); + +private: + +}; diff --git a/gtk2_ardour/editing_context.cc b/gtk2_ardour/editing_context.cc index 3c5d666a20..05cc6ea696 100644 --- a/gtk2_ardour/editing_context.cc +++ b/gtk2_ardour/editing_context.cc @@ -61,6 +61,7 @@ using namespace Gtk; using namespace Gtkmm2ext; using namespace PBD; using namespace Temporal; +using namespace ArdourWidgets; using std::string; sigc::signal EditingContext::DropDownKeys; @@ -124,11 +125,15 @@ EditingContext::EditingContext (std::string const & name) #endif , _snap_mode (SnapOff) , _timeline_origin (0.) + , play_note_selection_button (_("Ear"), ArdourButton::Text, true) + , follow_playhead_button (_("F"), ArdourButton::Text, true) + , full_zoom_button (_("<->"), ArdourButton::Text) , _drags (new DragManager (this)) , _leftmost_sample (0) , _playhead_cursor (nullptr) , _snapped_cursor (nullptr) , _follow_playhead (false) + , visible_channel_label (_("MIDI|Channel")) , selection (new Selection (this, true)) , cut_buffer (new Selection (this, false)) , _selection_memento (new SelectionMemento()) @@ -153,6 +158,8 @@ EditingContext::EditingContext (std::string const & name) , entered_regionview (nullptr) , clear_entered_track (false) { + using namespace Gtk::Menu_Helpers; + if (!button_bindings) { button_bindings = new Bindings ("editor-mouse"); @@ -188,15 +195,46 @@ EditingContext::EditingContext (std::string const & name) set_tooltip (grid_type_selector, _("Grid Mode")); set_tooltip (snap_mode_button, _("Snap Mode\n\nRight-click to visit Snap preferences.")); + set_tooltip (play_note_selection_button, _("Play notes when selected")); + set_tooltip (follow_playhead_button, _("Scroll automatically to keep playhead visible")); + /* Leave tip for full zoom button to derived class */ + set_tooltip (visible_channel_selector, _("Select visible MIDI channel")); + + play_note_selection_button.signal_clicked.connect (sigc::mem_fun (*this, &EditingContext::play_note_selection_clicked)); + follow_playhead_button.signal_clicked.connect (sigc::mem_fun (*this, &EditingContext::follow_playhead_clicked)); + full_zoom_button.signal_clicked.connect (sigc::mem_fun (*this, &EditingContext::full_zoom_clicked)); + + for (int i = 0; i < 16; i++) { + char buf[4]; + sprintf(buf, "%d", i+1); + visible_channel_selector.AddMenuElem (MenuElem (buf, [this,i]() { EditingContext::set_visible_channel (i); })); + } + /* handle escape */ ARDOUR_UI::instance()->Escape.connect (escape_connection, MISSING_INVALIDATOR, std::bind (&EditingContext::escape, this), gui_context()); + + Config->ParameterChanged.connect (parameter_connections, MISSING_INVALIDATOR, std::bind (&EditingContext::parameter_changed, this, _1), gui_context()); + UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &EditingContext::ui_parameter_changed)); } EditingContext::~EditingContext() { } +void +EditingContext::ui_parameter_changed (string parameter) +{ + if (parameter == "sound-midi-note") { + } +} + + +void +EditingContext::parameter_changed (string parameter) +{ +} + void EditingContext::set_session (ARDOUR::Session* s) { @@ -2043,6 +2081,7 @@ EditingContext::set_canvas_cursor (Gdk::Cursor* cursor) For now, drop down and use C API */ gdk_window_set_cursor (win->gobj(), cursor ? cursor->gobj() : 0); + gdk_flush (); } } @@ -2050,6 +2089,12 @@ size_t EditingContext::push_canvas_cursor (Gdk::Cursor* cursor) { if (!_cursors->is_invalid (cursor)) { + if (!_cursor_stack.empty()) { + if (cursor == _cursor_stack.back()) { + return _cursor_stack.size() - 1; + } + } + _cursor_stack.push_back (cursor); set_canvas_cursor (cursor); } @@ -2066,7 +2111,7 @@ EditingContext::pop_canvas_cursor () } _cursor_stack.pop_back(); - if (_cursor_stack.back()) { + if (!_cursor_stack.empty()) { /* Popped to an existing cursor, we're done. Otherwise, the context that created this cursor has been destroyed, so we need to skip to the next down the stack. */ @@ -2769,4 +2814,12 @@ EditingContext::update_all_enter_cursors () } } +void +EditingContext::play_note_selection_clicked () +{ +} +void +EditingContext::follow_playhead_clicked () +{ +} diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index c6c13ad801..1db0e6faca 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -494,6 +494,17 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider void snap_mode_chosen (Editing::SnapMode); void grid_type_chosen (Editing::GridType); + ArdourWidgets::ArdourButton play_note_selection_button; + ArdourWidgets::ArdourButton follow_playhead_button; + ArdourWidgets::ArdourButton full_zoom_button; + Gtk::Label visible_channel_label; + ArdourWidgets::ArdourDropdown visible_channel_selector; + + virtual void play_note_selection_clicked(); + virtual void follow_playhead_clicked (); + virtual void full_zoom_clicked() {}; + virtual void set_visible_channel (int) {} + DragManager* _drags; ArdourWidgets::ArdourButton snap_mode_button; @@ -674,6 +685,10 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider uint32_t autoscroll_cnt; ArdourCanvas::Rect autoscroll_boundary; + PBD::ScopedConnectionList parameter_connections; + virtual void parameter_changed (std::string); + virtual void ui_parameter_changed (std::string); + bool _mouse_changed_selection; ArdourMarker* entered_marker; TimeAxisView* entered_track; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 5f955913fc..b66772aa4d 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -305,8 +305,8 @@ Editor::Editor () , controls_layout (unused_adjustment, vertical_adjustment) , _scroll_callbacks (0) , _full_canvas_height (0) - , edit_controls_left_menu (nullptr) - , edit_controls_right_menu (nullptr) + , edit_controls_left_menu (0) + , edit_controls_right_menu (0) , _trigger_clip_picker (nullptr) , _tvl_no_redisplay(false) , _tvl_redisplay_on_resume(false) @@ -340,8 +340,8 @@ Editor::Editor () , new_transport_marker_menu (0) , marker_menu_item (0) , _visible_track_count (-1) - , toolbar_selection_clock_table (2,3) - , automation_mode_button (_("mode")) + , toolbar_selection_clock_table (2,3) + , automation_mode_button (_("mode")) , _all_region_actions_sensitized (false) , _ignore_region_action (false) , _last_region_menu_was_main (false) @@ -651,31 +651,22 @@ Editor::Editor () Location::end_changed.connect (*this, invalidator (*this), std::bind (&Editor::location_changed, this, _1), gui_context()); Location::changed.connect (*this, invalidator (*this), std::bind (&Editor::location_changed, this, _1), gui_context()); -#if SELECTION_PROPERTIES_BOX_TODO - add_notebook_page (_("Selection"), *_properties_box); -#warning Fix Properties Sidebar Layout to fit < 720px height +#ifndef LIVETRAX + add_notebook_page (_("Tracks & Busses"), _routes->widget ()); + add_notebook_page (_("Sources"), _sources->widget ()); + add_notebook_page (_("Regions"), _regions->widget ()); + add_notebook_page (_("Clips"), _trigger_clip_picker); + add_notebook_page (_("Arrangement"), _sections->widget ()); + add_notebook_page (_("Snapshots"), _snapshots->widget ()); + add_notebook_page (_("Track & Bus Groups"), _route_groups->widget ()); + add_notebook_page (_("Ranges & Marks"), _locations->widget ()); + + _the_notebook.set_show_tabs (true); + _the_notebook.set_scrollable (true); + _the_notebook.popup_disable (); + _the_notebook.set_tab_pos (Gtk::POS_RIGHT); + _the_notebook.show_all (); #endif - if (!Profile->get_livetrax()) { - - if (!Profile->get_livetrax()) { - _trigger_clip_picker = manage (new TriggerClipPicker ()); - } - - add_notebook_page (_("Tracks & Busses"), _routes->widget ()); - add_notebook_page (_("Sources"), _sources->widget ()); - add_notebook_page (_("Regions"), _regions->widget ()); - add_notebook_page (_("Clips"), *_trigger_clip_picker); - add_notebook_page (_("Arrangement"), _sections->widget ()); - add_notebook_page (_("Snapshots"), _snapshots->widget ()); - add_notebook_page (_("Track & Bus Groups"), _route_groups->widget ()); - add_notebook_page (_("Ranges & Marks"), _locations->widget ()); - - _the_notebook.set_show_tabs (true); - _the_notebook.set_scrollable (true); - _the_notebook.popup_disable (); - _the_notebook.set_tab_pos (Gtk::POS_RIGHT); - _the_notebook.show_all (); - } _notebook_shrunk = false; @@ -688,56 +679,82 @@ Editor::Editor () settings->get_property ("notebook-shrunk", _notebook_shrunk); } - if (!Profile->get_livetrax()) { +#ifndef LIVETRAX + editor_summary_pane.set_check_divider_position (true); + editor_summary_pane.add (edit_packer); + Button* summary_arrow_left = manage (new Button); + summary_arrow_left->add (*manage (new Arrow (ARROW_LEFT, SHADOW_NONE))); + summary_arrow_left->signal_pressed().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*this, &Editor::scroll_press), LEFT))); + summary_arrow_left->signal_released().connect (sigc::mem_fun (*this, &Editor::scroll_release)); + Button* summary_arrow_right = manage (new Button); + summary_arrow_right->add (*manage (new Arrow (ARROW_RIGHT, SHADOW_NONE))); + summary_arrow_right->signal_pressed().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*this, &Editor::scroll_press), RIGHT))); + summary_arrow_right->signal_released().connect (sigc::mem_fun (*this, &Editor::scroll_release)); + VBox* summary_arrows_left = manage (new VBox); + summary_arrows_left->pack_start (*summary_arrow_left); - editor_summary_pane.add (_summary_hbox); - _editor_list_vbox.pack_start (_the_notebook); - _editor_list_vbox.pack_start (*_properties_box, false, false, 0); + VBox* summary_arrows_right = manage (new VBox); + summary_arrows_right->pack_start (*summary_arrow_right); - content_right_pane.set_drag_cursor (*_cursors->expand_left_right); - editor_summary_pane.set_drag_cursor (*_cursors->expand_up_down); + Gtk::Frame* summary_frame = manage (new Gtk::Frame); + summary_frame->set_shadow_type (Gtk::SHADOW_ETCHED_IN); - float fract; - if (!settings || !settings->get_property ("edit-vertical-pane-pos", fract) || fract > 1.0) { - /* initial allocation is 90% to canvas, 10% to summary */ - fract = 0.90; - } + summary_frame->add (*_summary); + summary_frame->show (); + + _summary_hbox.pack_start (*summary_arrows_left, false, false); + _summary_hbox.pack_start (*summary_frame, true, true); + _summary_hbox.pack_start (*summary_arrows_right, false, false); + + editor_summary_pane.add (_summary_hbox); + _editor_list_vbox.pack_start (_the_notebook); + + content_right_pane.set_drag_cursor (*_cursors->expand_left_right); + editor_summary_pane.set_drag_cursor (*_cursors->expand_up_down); + + float fract; + if (!settings || !settings->get_property ("edit-vertical-pane-pos", fract) || fract > 1.0) { + /* initial allocation is 90% to canvas, 10% to summary */ + fract = 0.90; } + editor_summary_pane.set_divider (0, fract); +#endif global_vpacker.set_spacing (0); global_vpacker.set_border_width (0); - if (!Profile->get_livetrax()) { - ArdourWidgets::ArdourDropShadow *toolbar_shadow = manage (new (ArdourWidgets::ArdourDropShadow)); - toolbar_shadow->set_size_request (-1, 4); - toolbar_shadow->set_mode(ArdourWidgets::ArdourDropShadow::DropShadowBoth); - toolbar_shadow->set_name("EditorWindow"); - toolbar_shadow->show(); +#ifndef LIVETRAX + ArdourWidgets::ArdourDropShadow *toolbar_shadow = manage (new (ArdourWidgets::ArdourDropShadow)); + toolbar_shadow->set_size_request (-1, 4); + toolbar_shadow->set_mode(ArdourWidgets::ArdourDropShadow::DropShadowBoth); + toolbar_shadow->set_name("EditorWindow"); + toolbar_shadow->show(); - global_vpacker.pack_start (*toolbar_shadow, false, false); - global_vpacker.pack_start (ebox_hpacker, true, true); + global_vpacker.pack_start (*toolbar_shadow, false, false); + global_vpacker.pack_start (ebox_hpacker, true, true); - /* pack all the main pieces into appropriate containers from _tabbable - */ - content_app_bar.add (_application_bar); - content_att_right.add (_editor_list_vbox); - content_toolbar.add (global_vpacker); - content_innermost_hbox.add (editor_summary_pane); + /* pack all the main pieces into appropriate containers from _tabbable + */ + content_app_bar.add (_application_bar); + content_att_right.add (_editor_list_vbox); + content_att_bottom.add (*_properties_box); + content_toolbar.add (global_vpacker); + content_innermost_hbox.add (editor_summary_pane); - /* need to show the "contents" widget so that notebook will show if tab is switched to - */ + /* need to show the "contents" widget so that notebook will show if tab is switched to + */ - content_hbox.show (); - ebox_hpacker.show(); - global_vpacker.show(); - } else { - global_vpacker.pack_start (edit_packer, true, true); - content_innermost_hbox.add (global_vpacker); - global_vpacker.show(); - } + content_hbox.show (); + ebox_hpacker.show(); + global_vpacker.show(); +#else /* LIVETRAX */ + global_vpacker.pack_start (edit_packer, true, true); + content_innermost_hbox.add (global_vpacker); + global_vpacker.show(); +#endif /* register actions now so that set_state() can find them and set toggles/checks etc */ @@ -784,9 +801,6 @@ Editor::Editor () Session::AskAboutPlaylistDeletion.connect_same_thread (*this, std::bind (&Editor::playlist_deletion_dialog, this, _1)); Route::PluginSetup.connect_same_thread (*this, std::bind (&Editor::plugin_setup, this, _1, _2, _3)); - Config->ParameterChanged.connect (*this, invalidator (*this), std::bind (&Editor::parameter_changed, this, _1), gui_context()); - UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &Editor::ui_parameter_changed)); - TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), std::bind (&Editor::timeaxisview_deleted, this, _1), gui_context()); _ignore_region_action = false; @@ -2350,6 +2364,15 @@ Editor::set_state (const XMLNode& node, int version) tact->set_active (yn); } + yn = false; + node.get_property ("show-editor-props", yn); + { + Glib::RefPtr tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-editor-props")); + /* do it twice to force the change */ + tact->set_active (!yn); + tact->set_active (yn); + } + int32_t el_page; if (node.get_property (X_("editor-list-page"), el_page)) { _the_notebook.set_current_page (el_page); @@ -2457,6 +2480,9 @@ Editor::get_state () const tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-editor-list")); node->set_property (X_("show-editor-list"), tact->get_active()); + tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-editor-props")); + node->set_property (X_("show-editor-props"), tact->get_active()); + node->set_property (X_("editor-list-page"), _the_notebook.get_current_page ()); if (button_bindings) { @@ -5841,6 +5867,8 @@ Editor::zoom_vertical_modifier_released() void Editor::ui_parameter_changed (string parameter) { + EditingContext::ui_parameter_changed (parameter); + if (parameter == "icon-set") { while (!_cursor_stack.empty()) { _cursor_stack.pop_back(); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index f5c2015219..01c67629a9 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -1100,7 +1100,7 @@ Editor::marker_click_behavior_chosen (Editing::MarkerClickBehavior m) void Editor::parameter_changed (std::string p) { - ENSURE_GUI_THREAD (*this, &Editor::parameter_changed, p) + EditingContext::parameter_changed (p); if (p == "auto-loop") { update_loop_range_view (); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 16129ae2e1..4ef185ed5a 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -7540,3 +7540,81 @@ VelocityLineDrag::aborted (bool) { vd->end_line_drag (false); } + +ClipStartDrag::ClipStartDrag (EditingContext& ec, ArdourCanvas::Rectangle& r, Temporal::timepos_t const & os) + : Drag (ec, &r, os.time_domain(), nullptr, false) + , dragging_rect (&r) + , original_start (os) +{ +} + +ClipStartDrag::~ClipStartDrag () +{ +} + +void +ClipStartDrag::start_grab (GdkEvent* ev,Gdk::Cursor* c) +{ + Drag::start_grab (ev, c); +} + +bool +ClipStartDrag::end_grab (GdkEvent* ev) +{ + Drag::end_grab (ev); + return false; +} + +void +ClipStartDrag::motion (GdkEvent*, bool) +{ +} + +void +ClipStartDrag::finished (GdkEvent*, bool) +{ +} + +void +ClipStartDrag::aborted (bool) +{ +} + +ClipEndDrag::ClipEndDrag (EditingContext& ec, ArdourCanvas::Rectangle& r, Temporal::timepos_t const & oe) + : Drag (ec, &r, oe.time_domain(), nullptr, false) + , dragging_rect (&r) + , original_end (oe) +{ +} + +ClipEndDrag::~ClipEndDrag () +{ +} + +void +ClipEndDrag::start_grab (GdkEvent* ev,Gdk::Cursor* c) +{ + Drag::start_grab (ev, c); +} + +bool +ClipEndDrag::end_grab (GdkEvent* ev) +{ + Drag::end_grab (ev); + return false; +} + +void +ClipEndDrag::motion (GdkEvent*, bool) +{ +} + +void +ClipEndDrag::finished (GdkEvent*, bool) +{ +} + +void +ClipEndDrag::aborted (bool) +{ +} diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index cd9a9fe879..9775da2389 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1640,6 +1640,39 @@ class VelocityLineDrag : public FreehandLineDragsignal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &MidiCueEditor::automation_button_event), ARDOUR::MidiVelocityAutomation, 0), false); + pressure_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &MidiCueEditor::automation_button_event), ARDOUR::MidiChannelPressureAutomation, 0), false); + bender_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &MidiCueEditor::automation_button_event), ARDOUR::MidiPitchBenderAutomation, 0), false); + modulation_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &MidiCueEditor::automation_button_event), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_MODWHEEL), false); + expression_button->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &MidiCueEditor::automation_button_event), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_EXPRESSION), false); + + _toolbox.pack_start (button_bar, false, false); +} + +void +MidiCueEditor::build_upper_toolbar () +{ + using namespace Gtk::Menu_Helpers; + Gtk::HBox* mode_box = manage(new Gtk::HBox); mode_box->set_border_width (2); mode_box->set_spacing(2); @@ -169,13 +198,28 @@ MidiCueEditor::setup_toolbar () _toolbar_inner->pack_start (grid_box, false, false); _toolbar_inner->pack_start (draw_box, false, false); + set_tooltip (full_zoom_button, _("Zoom to full clip")); + + _toolbar_outer->set_border_width (6); + _toolbar_outer->set_spacing (12); + _toolbar_outer->pack_start (visible_channel_label, false, false); + _toolbar_outer->pack_start (visible_channel_selector, false, false); + _toolbar_outer->pack_start (play_note_selection_button, false, false); + _toolbar_outer->pack_start (follow_playhead_button, false, false); + _toolbar_outer->pack_start (full_zoom_button, false, false); _toolbar_outer->pack_start (*_toolbar_inner, true, false); + _toolbox.pack_start (*_toolbar_outer, false, false); Bindings* pr_bindings = Bindings::get_bindings (X_("Pianoroll")); _toolbox.set_data (X_("ardour-bindings"), pr_bindings); } +void +MidiCueEditor::set_visible_channel (int n) +{ +} + void MidiCueEditor::build_canvas () { @@ -268,7 +312,7 @@ MidiCueEditor::build_canvas () prh = new ArdourCanvas::PianoRollHeader (v_scroll_group, *bg); - view = new MidiCueView (nullptr, 0, *data_group, *this, *bg, 0xff0000ff); + view = new MidiCueView (nullptr, 0, *data_group, *no_scroll_group, *this, *bg, 0xff0000ff); bg->set_view (view); prh->set_view (view); @@ -282,6 +326,7 @@ MidiCueEditor::build_canvas () prh->set_position (Duple (0., n_timebars * timebar_height)); data_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars)); + no_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars)); cursor_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars)); h_scroll_group->set_position (Duple (_timeline_origin, 0.)); @@ -292,11 +337,14 @@ MidiCueEditor::build_canvas () _playhead_cursor->set_sensitive (UIConfiguration::instance().get_sensitize_playhead()); _playhead_cursor->set_color (UIConfiguration::instance().color ("play head")); _playhead_cursor->canvas_item().raise_to_top(); + h_scroll_group->raise_to_top (); _canvas->set_name ("MidiCueCanvas"); _canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK); _canvas->set_can_focus (); + _toolbox.pack_start (*_canvas_viewport, true, true); + bindings_changed (); } @@ -317,11 +365,6 @@ MidiCueEditor::maybe_update () return; } - if (_track->rec_enable_control()->get_value()) { - /* ::data_captured() will handle it */ - return; - } - ARDOUR::TriggerPtr trigger = _track->triggerbox()->currently_playing (); if (!trigger) { @@ -1613,8 +1656,6 @@ MidiCueEditor::which_canvas_cursor (ItemType type) const bool MidiCueEditor::enter_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_type) { - EditorAutomationLine* al; - choose_canvas_cursor_on_entry (item_type); switch (item_type) { @@ -1752,6 +1793,8 @@ MidiCueEditor::set_region (std::shared_ptr r) } view->set_region (r); + view->show_start (true); + view->show_end (true); /* Compute zoom level to show entire source plus some margin if possible */ @@ -1774,9 +1817,36 @@ MidiCueEditor::set_region (std::shared_ptr r) { EditingContext::TempoMapScope tms (*this, map); double width = bg->width(); - samplecnt_t samples = duration.samples(); + /* make it 20% wider than we need */ + samplecnt_t samples = (samplecnt_t) floor (1.2 * duration.samples()); std::cerr << "new spp from " << samples << " / " << width << std::endl; samplecnt_t spp = floor (samples / width); reset_zoom (spp); } } + +bool +MidiCueEditor::automation_button_event (GdkEventButton* ev, Evoral::ParameterType type, int id) +{ + SelectionOperation op = ArdourKeyboard::selection_type (ev->state); + + switch (ev->type) { + case GDK_BUTTON_RELEASE: + automation_button_click (type, id, op); + break; + default: + break; + } + + return false; +} + +void +MidiCueEditor::automation_button_click (Evoral::ParameterType type, int id, SelectionOperation op) +{ +#warning paul allow channel selection (2nd param) + if (view) { + view->update_automation_display (Evoral::Parameter (type, 0, id), op); + } +} + diff --git a/gtk2_ardour/midi_cue_editor.h b/gtk2_ardour/midi_cue_editor.h index 51ce9740de..0368d08fdc 100644 --- a/gtk2_ardour/midi_cue_editor.h +++ b/gtk2_ardour/midi_cue_editor.h @@ -109,6 +109,8 @@ class MidiCueEditor : public CueEditor Gdk::Cursor* which_trim_cursor (bool left_side) const; Gdk::Cursor* which_canvas_cursor (ItemType type) const; + void set_visible_channel (int chan); + protected: void register_actions (); @@ -171,11 +173,20 @@ class MidiCueEditor : public CueEditor Gtk::VBox _toolbox; + Gtk::HBox button_bar; + ArdourWidgets::ArdourButton* velocity_button; + ArdourWidgets::ArdourButton* bender_button; + ArdourWidgets::ArdourButton* pressure_button; + ArdourWidgets::ArdourButton* expression_button; + ArdourWidgets::ArdourButton* modulation_button; + CueMidiBackground* bg; MidiCueView* view; void build_canvas (); void canvas_allocate (Gtk::Allocation); + void build_upper_toolbar (); + void build_lower_toolbar (); RegionSelection region_selection(); @@ -199,7 +210,6 @@ class MidiCueEditor : public CueEditor BBTMetric bbt_metric; bool canvas_pre_event (GdkEvent*); - void setup_toolbar (); /* autoscrolling */ @@ -222,6 +232,11 @@ class MidiCueEditor : public CueEditor std::atomic idle_update_queued; PBD::ScopedConnectionList capture_connections; samplecnt_t data_capture_duration; + + bool automation_button_event (GdkEventButton*, Evoral::ParameterType type, int id); + void automation_button_click (Evoral::ParameterType type, int id, ARDOUR::SelectionOperation); + + int _visible_channel; }; diff --git a/gtk2_ardour/midi_cue_view.cc b/gtk2_ardour/midi_cue_view.cc index 5669e3ede4..8b8285b8dd 100644 --- a/gtk2_ardour/midi_cue_view.cc +++ b/gtk2_ardour/midi_cue_view.cc @@ -48,6 +48,7 @@ using namespace Gtkmm2ext; MidiCueView::MidiCueView (std::shared_ptr mt, uint32_t slot_index, ArdourCanvas::Item& parent, + ArdourCanvas::Item& noscroll_parent, EditingContext& ec, MidiViewBackground& bg, uint32_t basic_color) @@ -55,11 +56,10 @@ MidiCueView::MidiCueView (std::shared_ptr mt, , active_automation (nullptr) , velocity_display (nullptr) , _slot_index (slot_index) + , _height (0.) { CANVAS_DEBUG_NAME (_note_group, X_("note group for MIDI cue")); - _needs_active_notes_for_rec_enabled_track = true; - /* Containers don't get canvas events, so we need an invisible rect * that will. It will be resized as needed sothat it always covers the * entire canvas/view. @@ -79,46 +79,8 @@ MidiCueView::MidiCueView (std::shared_ptr mt, automation_group->set_fill_color (UIConfiguration::instance().color ("midi automation track fill")); automation_group->set_data ("linemerger", this); - button_bar = new ArdourCanvas::Box (&parent, ArdourCanvas::Box::Horizontal); - CANVAS_DEBUG_NAME (button_bar, "button bar"); - button_bar->set_spacing (12.); - /* Right-side padding only */ - button_bar->set_padding (0., 0., 0., 24.); - button_bar->set_margin (5., 5., 5., 5.); - - Pango::FontDescription button_font = UIConfiguration::instance().get_NormalFont(); - - velocity_button = new ArdourCanvas::Button (button_bar, _("Velocity"), button_font); - velocity_button->text()->set_color (UIConfiguration::instance().color ("neutral:foreground")); - CANVAS_DEBUG_NAME (velocity_button, "velocity button"); - - bender_button = new ArdourCanvas::Button (button_bar, _("Bender"), button_font); - bender_button->text()->set_color (UIConfiguration::instance().color ("neutral:foreground")); - CANVAS_DEBUG_NAME (bender_button, "bender button"); - - pressure_button = new ArdourCanvas::Button (button_bar, _("Pressure"), button_font); - pressure_button->text()->set_color (UIConfiguration::instance().color ("neutral:foreground")); - CANVAS_DEBUG_NAME (pressure_button, "pressure button"); - - expression_button = new ArdourCanvas::Button (button_bar, _("Expression"), button_font); - expression_button->text()->set_color (UIConfiguration::instance().color ("neutral:foreground")); - CANVAS_DEBUG_NAME (expression_button, "expression button"); - - modulation_button = new ArdourCanvas::Button (button_bar, _("Modulation"), button_font); - modulation_button->text()->set_color (UIConfiguration::instance().color ("neutral:foreground")); - CANVAS_DEBUG_NAME (modulation_button, "modulation button"); - - velocity_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &MidiCueView::automation_button_event), ARDOUR::MidiVelocityAutomation, 0)); - pressure_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &MidiCueView::automation_button_event), ARDOUR::MidiChannelPressureAutomation, 0)); - bender_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &MidiCueView::automation_button_event), ARDOUR::MidiPitchBenderAutomation, 0)); - modulation_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &MidiCueView::automation_button_event), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_MODWHEEL)); - expression_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &MidiCueView::automation_button_event), ARDOUR::MidiCCAutomation, MIDI_CTL_MSB_EXPRESSION)); set_extensible (true); - - /* show velocity by default */ - - update_automation_display (Evoral::Parameter (MidiVelocityAutomation, 0, 0), SelectionSet); } MidiCueView::~MidiCueView () @@ -129,11 +91,18 @@ MidiCueView::~MidiCueView () void MidiCueView::set_height (double h) { - double bbw, bbh; - button_bar->size_request (bbw, bbh); + _height = h; - double note_area_height = ceil ((h - bbh) / 2.); - double automation_height = ceil (h - bbh - note_area_height); + double note_area_height; + double automation_height; + + if (automation_map.empty()) { + note_area_height = h; + automation_height = 0.; + } else { + note_area_height = ceil (h / 2.); + automation_height = ceil (h - note_area_height); + } event_rect->set (ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, note_area_height)); midi_context().set_size (midi_context().width(), note_area_height); @@ -141,8 +110,6 @@ MidiCueView::set_height (double h) automation_group->set_position (ArdourCanvas::Duple (0., note_area_height)); automation_group->set (ArdourCanvas::Rect (0., 0., ArdourCanvas::COORD_MAX, automation_height)); - button_bar->size_allocate (ArdourCanvas::Rect (0., note_area_height + automation_height, ArdourCanvas::COORD_MAX, note_area_height + automation_height + bbh)); - for (auto & ads : automation_map) { ads.second.set_height (automation_height); } @@ -275,29 +242,6 @@ MidiCueView::update_hit (Hit* h) } } -bool -MidiCueView::automation_button_event (GdkEvent* ev, Evoral::ParameterType type, int id) -{ - SelectionOperation op = ArdourKeyboard::selection_type (ev->button.state); - - switch (ev->type) { - case GDK_BUTTON_RELEASE: - automation_button_click (type, id, op); - break; - default: - break; - } - - return false; -} - -void -MidiCueView::automation_button_click (Evoral::ParameterType type, int id, SelectionOperation op) -{ -#warning paul allow channel selection (2nd param) - update_automation_display (Evoral::Parameter (type, 0, id), op); -} - void MidiCueView::update_automation_display (Evoral::Parameter const & param, SelectionOperation op) { @@ -413,6 +357,8 @@ MidiCueView::update_automation_display (Evoral::Parameter const & param, Selecti /* undefined in this context */ break; } + + set_height (_height); } std::list diff --git a/gtk2_ardour/midi_cue_view.h b/gtk2_ardour/midi_cue_view.h index 05c15d0237..4ba97040e8 100644 --- a/gtk2_ardour/midi_cue_view.h +++ b/gtk2_ardour/midi_cue_view.h @@ -35,7 +35,6 @@ class MidiCueAutomationLine; namespace ArdourCanvas { class Box; - class Button; } class MidiCueView : public MidiView @@ -44,6 +43,7 @@ class MidiCueView : public MidiView MidiCueView (std::shared_ptr mt, uint32_t slot_index, ArdourCanvas::Item& parent, + ArdourCanvas::Item& noscroll_parent, EditingContext& ec, MidiViewBackground& bg, uint32_t basic_color @@ -109,13 +109,6 @@ class MidiCueView : public MidiView VelocityDisplay* velocity_display; - ArdourCanvas::Box* button_bar; - ArdourCanvas::Button* velocity_button; - ArdourCanvas::Button* bender_button; - ArdourCanvas::Button* pressure_button; - ArdourCanvas::Button* expression_button; - ArdourCanvas::Button* modulation_button; - std::shared_ptr tempo_map; ArdourCanvas::Rectangle* event_rect; uint32_t _slot_index; @@ -123,6 +116,5 @@ class MidiCueView : public MidiView void update_sustained (Note *); void update_hit (Hit *); - bool automation_button_event (GdkEvent*, Evoral::ParameterType type, int id); - void automation_button_click (Evoral::ParameterType type, int id, ARDOUR::SelectionOperation); + double _height; }; diff --git a/gtk2_ardour/midi_view.cc b/gtk2_ardour/midi_view.cc index e4d70be077..8a74295e9d 100644 --- a/gtk2_ardour/midi_view.cc +++ b/gtk2_ardour/midi_view.cc @@ -120,9 +120,10 @@ MidiView::MidiView (std::shared_ptr mt, , _step_edit_cursor (0) , _step_edit_cursor_width (1, 0) , _channel_selection_scoped_note (0) - , _needs_active_notes_for_rec_enabled_track (false) , _mouse_state(None) , _pressed_button(0) + , _start_boundary_rect (nullptr) + , _end_boundary_rect (nullptr) , _optimization_iterator (_events.end()) , _list_editor (nullptr) , _no_sound_notes (false) @@ -152,7 +153,6 @@ MidiView::MidiView (MidiView const & other) , _step_edit_cursor (0) , _step_edit_cursor_width (1, 0) , _channel_selection_scoped_note (0) - , _needs_active_notes_for_rec_enabled_track (false) , _mouse_state(None) , _pressed_button(0) , _optimization_iterator (_events.end()) @@ -186,6 +186,52 @@ MidiView::init (std::shared_ptr mt) _midi_context.NoteRangeChanged.connect (sigc::mem_fun (*this, &MidiView::view_changed)); } +void +MidiView::show_start (bool yn) +{ + if (!yn) { + delete _start_boundary_rect; + _start_boundary_rect = nullptr; + return; + } + + if (!_midi_region) { + return; + } + + if (!_start_boundary_rect) { + _start_boundary_rect = new ArdourCanvas::Rectangle (_note_group->parent()); + _start_boundary_rect->set_fill_color (0xff000087); + _start_boundary_rect->set_outline_color (0xff0000ff); + } + + double width = _editing_context.sample_to_pixel (_midi_region->start().samples()); + _start_boundary_rect->set (ArdourCanvas::Rect (0., 0., width, height())); +} + +void +MidiView::show_end (bool yn) +{ + if (!yn) { + delete _end_boundary_rect; + _end_boundary_rect = nullptr; + return; + } + + if (!_midi_region) { + return; + } + + if (!_end_boundary_rect) { + _end_boundary_rect = new ArdourCanvas::Rectangle (_note_group->parent()); + _end_boundary_rect->set_fill_color (0xff000087); + _end_boundary_rect->set_outline_color (0xff0000ff); + } + + double offset = _editing_context.sample_to_pixel ((_midi_region->start() + _midi_region->length()).samples()); + _end_boundary_rect->set (ArdourCanvas::Rect (offset, 0., ArdourCanvas::COORD_MAX, height())); +} + void MidiView::set_track (std::shared_ptr mt) { diff --git a/gtk2_ardour/midi_view.h b/gtk2_ardour/midi_view.h index 32355d242e..601042bdf2 100644 --- a/gtk2_ardour/midi_view.h +++ b/gtk2_ardour/midi_view.h @@ -348,6 +348,9 @@ class MidiView : public virtual sigc::trackable, public LineMerger void select_self () { select_self (false); } virtual void select_self_uniquely () {} + void show_start (bool yn); + void show_end (bool yn); + protected: void init (std::shared_ptr); virtual void region_resized (const PBD::PropertyChange&); @@ -503,9 +506,10 @@ class MidiView : public virtual sigc::trackable, public LineMerger Temporal::Beats _step_edit_cursor_width; Temporal::Beats _step_edit_cursor_position; NoteBase* _channel_selection_scoped_note; - bool _needs_active_notes_for_rec_enabled_track; MouseState _mouse_state; int _pressed_button; + ArdourCanvas::Rectangle* _start_boundary_rect; + ArdourCanvas::Rectangle* _end_boundary_rect; /** Currently selected NoteBase objects */ Selection _selection; diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index ceee6b1a32..391bd0798a 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -133,7 +133,7 @@ Mixer_UI::instance () } Mixer_UI::Mixer_UI () - : Tabbable (_("Mixer"), X_("mixer")) + : Tabbable (_("Mixer"), X_("mixer"), NULL, true, Tabbable::NoPanes) , plugin_search_clear_button (X_("Clear")) , _mixer_scene_release (0) , no_track_list_redisplay (false) @@ -164,13 +164,6 @@ Mixer_UI::Mixer_UI () contents().set_data ("ardour-bindings", bindings); - if (!Profile->get_mixbus ()) { - right_attachment_button.set_sensitive(false); - } else { - left_attachment_button.set_sensitive(false); - } - bottom_attachment_button.set_sensitive(false); - PresentationInfo::Change.connect (*this, invalidator (*this), std::bind (&Mixer_UI::presentation_info_changed, this, _1), gui_context()); Route::FanOut.connect (*this, invalidator (*this), std::bind (&Mixer_UI::fan_out, this, _1, false, true), gui_context()); @@ -390,7 +383,7 @@ Mixer_UI::Mixer_UI () favorite_plugins_scroller.show(); group_display_vbox.show(); group_display_frame.show(); - favorite_plugins_frame.show(); + favorite_plugins_frame.show_all(); rhs_pane1.show(); rhs_pane2.show(); strip_packer.show(); @@ -3737,7 +3730,6 @@ Mixer_UI::register_actions () act = ActionManager::register_toggle_action (group, "ToggleMixerList", _("(Mixer) Show Sidebar List"), sigc::mem_fun (*this, &Tabbable::att_left_button_toggled)); left_attachment_button.set_related_action (act); act = ActionManager::register_toggle_action (group, "ToggleMixerStrip", _("(Mixer) Show Sidebar Strip"), []{}); - content_right_pane.remove(content_right_vbox); } else { act = ActionManager::register_toggle_action (group, "ToggleMixerList", _("(Mixer) Show Sidebar List"), sigc::mem_fun (*this, &Tabbable::att_right_button_toggled)); right_attachment_button.set_related_action (act); @@ -3748,7 +3740,6 @@ Mixer_UI::register_actions () act = ActionManager::register_toggle_action (group, "ToggleMixerProps", _("(Mixer) Show Properties Bottom"), sigc::mem_fun (*this, &Tabbable::att_bottom_button_toggled)); bottom_attachment_button.set_related_action (act); #else - content_right_pane.remove(content_right_vbox); act = ActionManager::register_toggle_action (group, "ToggleMixerProps", _("(Mixer) Show Properties Bottom"), []{}); act = ActionManager::register_toggle_action (group, "ToggleMixerStrip", _("(Mixer) Show Sidebar Strip"), []{}); act = ActionManager::register_toggle_action (group, "ToggleMixerList", _("(Mixer) Show Sidebar List"), []{}); diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index 2bad8bbf13..b28f30fbc5 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -153,8 +153,6 @@ public: void toggle_mixer_strip (); void toggle_mixer_props (); - void showhide_mixer_list (bool yn); - void toggle_surround_master (); void toggle_monitor_section (); diff --git a/gtk2_ardour/prh.cc b/gtk2_ardour/prh.cc index 14ab4e540b..1b3164c88e 100644 --- a/gtk2_ardour/prh.cc +++ b/gtk2_ardour/prh.cc @@ -37,6 +37,7 @@ #include "gui_thread.h" #include "midi_view.h" #include "midi_view_background.h" +#include "mouse_cursors.h" #include "prh.h" #include "editing_context.h" #include "ui_config.h" @@ -630,21 +631,19 @@ PianoRollHeader::motion_handler (GdkEventMotion* ev) if (!_scroomer_drag && ev->x < _scroomer_size){ - Gdk::Cursor m_Cursor; - double scroomer_top = max(1.0, (1.0 - ((_adj.get_value()+_adj.get_page_size()) / 127.0)) * get().height()); + double scroomer_top = max (1.0, (1.0 - ((_adj.get_value()+_adj.get_page_size()) / 127.0)) * get().height()); double scroomer_bottom = (1.0 - (_adj.get_value () / 127.0)) * get().height(); + double edge = 5. * UIConfiguration::instance().get_ui_scale(); - if (evd.y > scroomer_top - 5 && evd.y < scroomer_top + 5){ - m_Cursor = Gdk::Cursor (Gdk::TOP_SIDE); - _view->editing_context().push_canvas_cursor (&m_Cursor); + if (evd.y > scroomer_top - 5 && evd.y < scroomer_top + edge){ + _view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->resize_top); _scroomer_state = TOP; - } else if (evd.y > scroomer_bottom - 5 && evd.y < scroomer_bottom + 5){ - m_Cursor = Gdk::Cursor (Gdk::BOTTOM_SIDE); - _view->editing_context().push_canvas_cursor (&m_Cursor); + } else if (evd.y > scroomer_bottom - edge && evd.y < scroomer_bottom + edge){ + _view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->resize_bottom); _scroomer_state = BOTTOM; } else { + _view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->grabber); _scroomer_state = MOVE; - _view->editing_context().pop_canvas_cursor (); } } diff --git a/gtk2_ardour/public_editor.cc b/gtk2_ardour/public_editor.cc index 5fa0cf7610..53eddf1c8d 100644 --- a/gtk2_ardour/public_editor.cc +++ b/gtk2_ardour/public_editor.cc @@ -33,7 +33,7 @@ ARDOUR::DataType PublicEditor::pbdid_dragged_dt = ARDOUR::DataType::NIL; PublicEditor::PublicEditor () : EditingContext (X_("Editor")) - , Tabbable (_("Editor"), X_("editor")) + , Tabbable (_("Editor"), X_("editor"), NULL, true, Tabbable::NoPanes) , mouse_mode_hbox (nullptr) { _suspend_route_redisplay_counter.store (0); diff --git a/gtk2_ardour/recorder_ui.cc b/gtk2_ardour/recorder_ui.cc index 5d8fa3b7ea..9dcc1c039b 100644 --- a/gtk2_ardour/recorder_ui.cc +++ b/gtk2_ardour/recorder_ui.cc @@ -78,7 +78,7 @@ using namespace Menu_Helpers; #define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ())) RecorderUI::RecorderUI () - : Tabbable (_("Recorder"), X_("recorder")) + : Tabbable (_("Recorder"), X_("recorder"), NULL, true, Tabbable::NoPanes) , _toolbar_sep (1.0) , _btn_rec_all (_("All")) , _btn_rec_none (_("None")) @@ -101,11 +101,6 @@ RecorderUI::RecorderUI () load_bindings (); register_actions (); - content_right_pane.remove(content_right_vbox); - left_attachment_button.set_sensitive(false); - bottom_attachment_button.set_sensitive(false); - right_attachment_button.set_sensitive(false); - /* monitoring */ _auto_input_button.set_related_action (ActionManager::get_action ("Transport", "ToggleAutoInput")); _auto_input_button.set_name ("transport option button"); diff --git a/gtk2_ardour/route_properties_box.cc b/gtk2_ardour/route_properties_box.cc new file mode 100644 index 0000000000..8820abc17e --- /dev/null +++ b/gtk2_ardour/route_properties_box.cc @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011-2017 Paul Davis + * Copyright (C) 2024 Ben Loftis + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "pbd/compose.h" +#include + +#include "gtkmm2ext/actions.h" +#include "gtkmm2ext/gui_thread.h" +#include "gtkmm2ext/utils.h" + +#include "ardour/location.h" +#include "ardour/profile.h" +#include "ardour/session.h" + +#include "audio_clock.h" +#include "automation_line.h" +#include "control_point.h" +#include "editor.h" +#include "region_view.h" + +#include "route_properties_box.h" + +#include "pbd/i18n.h" + +using namespace Gtk; +using namespace ARDOUR; +using namespace ArdourWidgets; +using std::max; +using std::min; + +RoutePropertiesBox::RoutePropertiesBox () +{ + show_all(); +} + +RoutePropertiesBox::~RoutePropertiesBox () +{ +} + +void +RoutePropertiesBox::set_route (std::shared_ptr rt) +{ + //TODO: route properties +// rt->PropertyChanged.connect (state_connection, invalidator (*this), boost::bind (&RoutePropertiesBox::region_changed, this, _1), gui_context ()); +} + +void +RoutePropertiesBox::property_changed (const PBD::PropertyChange& what_changed) +{ + + +} diff --git a/gtk2_ardour/route_properties_box.h b/gtk2_ardour/route_properties_box.h new file mode 100644 index 0000000000..bedb5dacc9 --- /dev/null +++ b/gtk2_ardour/route_properties_box.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 Paul Davis + * Copyright (C) 2024 Ben Loftis + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include + +#include +#include +#include + +#include "ardour/ardour.h" +#include "ardour/session_handle.h" + +#include "widgets/ardour_button.h" + +#include "gtkmm2ext/cairo_packer.h" + +#include "region_editor.h" +#include "audio_clock.h" + +namespace ARDOUR +{ + class Session; + class Location; +} + +class RoutePropertiesBox : public Gtk::HBox, public ARDOUR::SessionHandlePtr +{ +public: + RoutePropertiesBox (); + ~RoutePropertiesBox (); + + virtual void set_route (std::shared_ptr); + +protected: + std::shared_ptr _route; + + Gtk::Label _header_label; + +private: + void property_changed (const PBD::PropertyChange& what_changed); + + PBD::ScopedConnection state_connection; +}; + diff --git a/gtk2_ardour/selection_properties_box.cc b/gtk2_ardour/selection_properties_box.cc index 5283c944ea..00b738af3d 100644 --- a/gtk2_ardour/selection_properties_box.cc +++ b/gtk2_ardour/selection_properties_box.cc @@ -46,6 +46,8 @@ #include "slot_properties_box.h" +#include "audio_route_properties_box.h" + #include "selection_properties_box.h" #include "pbd/i18n.h" @@ -65,12 +67,10 @@ SelectionPropertiesBox::SelectionPropertiesBox () _time_info_box = new TimeInfoBox ("EditorTimeInfo", true); pack_start(*_time_info_box, false, false, 0); -#if SELECTION_PROPERTIES_BOX_TODO /* Region ops (mute/unmute), for multiple-Region selections */ _mregions_prop_box = new MultiRegionPropertiesBox (); pack_start(*_mregions_prop_box, false, false, 0); - /* MIDI Region props, for Clips */ _midi_prop_box = new MidiRegionPropertiesBox (); pack_start(*_midi_prop_box, false, false, 0); @@ -79,7 +79,6 @@ SelectionPropertiesBox::SelectionPropertiesBox () _audio_prop_box = new AudioRegionPropertiesBox (); pack_start(*_audio_prop_box, false, false, 0); - /* MIDI Region ops (transpose, quantize), for only-midi selections */ _midi_ops_box = new MidiRegionOperationsBox (); pack_start(*_midi_ops_box, false, false, 0); @@ -88,11 +87,62 @@ SelectionPropertiesBox::SelectionPropertiesBox () _audio_ops_box = new AudioRegionOperationsBox (); pack_start(*_audio_ops_box, false, false, 0); - /* SLOT properties, for Trigger slot selections */ _slot_prop_box = new SlotPropertiesBox (); pack_start(*_slot_prop_box, false, false, 0); -#endif + + /* ROUTE properties, for Track selections */ + _route_prop_box = new RoutePropertiesBox (); + pack_start(*_route_prop_box, false, false, 0); + + _time_info_box->set_no_show_all(); + _mregions_prop_box->set_no_show_all(); + _audio_prop_box->set_no_show_all(); + _midi_ops_box->set_no_show_all(); + _audio_ops_box->set_no_show_all(); + _slot_prop_box->set_no_show_all(); + _route_prop_box->set_no_show_all(); +} + +SelectionPropertiesBox::~SelectionPropertiesBox () +{ + delete _time_info_box; + + delete _mregions_prop_box; + + delete _slot_prop_box; + + delete _midi_ops_box; + delete _audio_ops_box; + + delete _midi_prop_box; + delete _audio_prop_box; + + delete _route_prop_box; //todo: split into midi/audio +} + +void +SelectionPropertiesBox::set_session (Session* s) +{ + SessionHandlePtr::set_session (s); + + if (!s) { + return; + } + + _time_info_box->set_session(s); + + _mregions_prop_box->set_session(s); + + _midi_prop_box->set_session(s); + _audio_prop_box->set_session(s); + + _midi_ops_box->set_session(s); + _audio_ops_box->set_session(s); + + _slot_prop_box->set_session(s); + + _route_prop_box->set_session(s); /* watch for any change in our selection, so we can show an appropriate property editor */ Editor::instance().get_selection().TracksChanged.connect (sigc::mem_fun (*this, &SelectionPropertiesBox::selection_changed)); @@ -111,47 +161,6 @@ SelectionPropertiesBox::SelectionPropertiesBox () selection_changed(); } -SelectionPropertiesBox::~SelectionPropertiesBox () -{ - delete _time_info_box; - -#if SELECTION_PROPERTIES_BOX_TODO - delete _mregions_prop_box; - - delete _slot_prop_box; - - delete _midi_ops_box; - delete _audio_ops_box; - - delete _midi_prop_box; - delete _audio_prop_box; -#endif -} - -void -SelectionPropertiesBox::set_session (Session* s) -{ - SessionHandlePtr::set_session (s); - - if (!s) { - return; - } - - _time_info_box->set_session(s); - -#if SELECTION_PROPERTIES_BOX_TODO - _mregions_prop_box->set_session(s); - - _midi_prop_box->set_session(s); - _audio_prop_box->set_session(s); - - _midi_ops_box->set_session(s); - _audio_ops_box->set_session(s); - - _slot_prop_box->set_session(s); -#endif -} - void SelectionPropertiesBox::track_mouse_mode () { @@ -165,7 +174,6 @@ SelectionPropertiesBox::selection_changed () _time_info_box->hide(); -#if SELECTION_PROPERTIES_BOX_TODO _mregions_prop_box->hide(); _midi_ops_box->hide(); @@ -175,7 +183,8 @@ SelectionPropertiesBox::selection_changed () _audio_prop_box->hide(); _slot_prop_box->hide(); -#endif + + _route_prop_box->hide(); _header_label.hide(); @@ -185,6 +194,16 @@ SelectionPropertiesBox::selection_changed () _header_label.show(); } + if (!selection.tracks.empty()) { + _route_prop_box->show(); + TimeAxisView *tav = *(selection.tracks.begin()); + RouteTimeAxisView *rtav = dynamic_cast(tav); + _route_prop_box->set_route(rtav->route()); + _header_label.set_text(_("Track Properties (Press ESC to Deselect All)")); + _header_label.hide(); + + } + #if SELECTION_PROPERTIES_BOX_TODO /* one or more regions, show the multi-region operations box (just MUTE? kinda boring) */ if (!selection.regions.empty()) { @@ -215,8 +234,10 @@ SelectionPropertiesBox::selection_changed () if (found_audio_regions && ! found_midi_regions) { _audio_ops_box->show(); } +#endif std::shared_ptr selected_region = std::shared_ptr(); + RegionView *selected_regionview = NULL; if (!selection.triggers.empty()) { TriggerSelection ts = selection.triggers; @@ -227,21 +248,21 @@ SelectionPropertiesBox::selection_changed () _slot_prop_box->set_slot(ref); _slot_prop_box->show(); - selected_region = ref.trigger()->region(); +// selected_region = ref.trigger()->region(); } else if (selection.regions.size()==1) { - selected_region = (*(selection.regions.begin()))->region(); + selected_regionview = *(selection.regions.begin()); } - if (selected_region) { +#if 0 // TODO pack region-properties here + if (selected_regionview) { + std::shared_ptr r = selected_regionview->region(); //region properties - if (selected_region->data_type() == DataType::MIDI) { - _midi_prop_box->set_region(selected_region); + if (r && r->data_type() == DataType::MIDI) { + _midi_prop_box->set_regionview(selected_regionview); _midi_prop_box->show(); - _midi_ops_box->show(); - } else { - _audio_prop_box->set_region(selected_region); + } else if (r) { + _audio_prop_box->set_regionview(selected_regionview); //retains a SessionHandler reference somewhere @robin _audio_prop_box->show(); - _audio_ops_box->show(); } } #endif diff --git a/gtk2_ardour/selection_properties_box.h b/gtk2_ardour/selection_properties_box.h index 447eabb4a6..93864bed9d 100644 --- a/gtk2_ardour/selection_properties_box.h +++ b/gtk2_ardour/selection_properties_box.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2021 Paul Davis - * Copyright (C) 2021 Ben Loftis + * Copyright (C) 2024 Ben Loftis * * 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 @@ -47,7 +47,9 @@ class MidiRegionPropertiesBox; class AudioRegionOperationsBox; class MidiRegionOperationsBox; -class SelectionPropertiesBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr +class RoutePropertiesBox; + +class SelectionPropertiesBox : public Gtk::HBox, public ARDOUR::SessionHandlePtr { public: SelectionPropertiesBox (); @@ -74,6 +76,8 @@ private: SlotPropertiesBox* _slot_prop_box; + RoutePropertiesBox* _route_prop_box; + void selection_changed (); void track_mouse_mode (); diff --git a/gtk2_ardour/trigger_page.cc b/gtk2_ardour/trigger_page.cc index 5ef25a44b1..c805971781 100644 --- a/gtk2_ardour/trigger_page.cc +++ b/gtk2_ardour/trigger_page.cc @@ -77,8 +77,6 @@ TriggerPage::TriggerPage () load_bindings (); register_actions (); - left_attachment_button.set_sensitive(false); - /* Match TriggerStrip::_name_button height */ ArdourButton* spacer = manage (new ArdourButton (ArdourButton::Text)); spacer->set_name ("mixer strip button"); diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 1cea1bea79..c572a52cdf 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -45,6 +45,7 @@ gtk2_ardour_sources = [ 'audio_region_view.cc', 'audio_region_operations_box.cc', 'audio_region_properties_box.cc', + 'audio_route_properties_box.cc', 'audio_trigger_properties_box.cc', 'audio_streamview.cc', 'audio_time_axis.cc', @@ -268,6 +269,7 @@ gtk2_ardour_sources = [ 'route_group_menu.cc', 'route_list_base.cc', 'route_params_ui.cc', + 'route_properties_box.cc', 'route_processor_selection.cc', 'route_time_axis.cc', 'route_ui.cc', diff --git a/libs/widgets/tabbable.cc b/libs/widgets/tabbable.cc index 5f56f23050..75cbe9d9ac 100644 --- a/libs/widgets/tabbable.cc +++ b/libs/widgets/tabbable.cc @@ -37,10 +37,11 @@ using namespace Gtk; using namespace Gtkmm2ext; using namespace ArdourWidgets; -Tabbable::Tabbable (const string& visible_name, string const & nontranslatable_name, Widget* w, bool tabbed_by_default) +Tabbable::Tabbable (const string& visible_name, string const & nontranslatable_name, Widget* w, bool tabbed_by_default, PaneLayout pl) : WindowProxy (visible_name, nontranslatable_name) , _parent_notebook (0) , tab_requested_by_state (tabbed_by_default) + , _panelayout (pl) { if (w) { _contents = w; @@ -78,6 +79,10 @@ Tabbable::default_layout () right_attachment_button.set_tweaks (ArdourButton::ExpandtoSquare); bottom_attachment_button.set_tweaks (ArdourButton::ExpandtoSquare); + left_attachment_button.set_sensitive (0 != (_panelayout & (PaneLeft | AttLeft))); + right_attachment_button.set_sensitive (0 != (_panelayout & PaneRight)); + bottom_attachment_button.set_sensitive (0 != (_panelayout & AttBottom)); + content_attachment_hbox.set_border_width(3); content_attachment_hbox.set_spacing(3); content_attachment_hbox.pack_end (right_attachment_button, false, false); @@ -99,27 +104,43 @@ Tabbable::default_layout () _content_vbox.pack_start (*toolbar_frame, false, false); #endif - _content_vbox.pack_start (content_hbox, true, true); - content_hbox.pack_start (content_att_left, false, false); - content_hbox.pack_start (content_midlevel_vbox, true, true); + + if (_panelayout & PaneLeft) { + _content_vbox.pack_start (content_left_pane, true, true); + content_left_pane.add (content_att_left); + content_left_pane.add (content_midlevel_vbox); + } else { + _content_vbox.pack_start (content_hbox, true, true); + content_hbox.pack_start (content_att_left, false, false); + content_hbox.pack_start (content_midlevel_vbox, true, true); + } content_midlevel_vbox.pack_start (content_right_pane, true, true); content_midlevel_vbox.pack_start (content_att_bottom, false, false); content_right_pane.add (content_inner_vbox); - content_right_pane.add (content_right_vbox); - //TODO: menu switcher here? - content_right_vbox.pack_start (content_att_right, true, true); + if (_panelayout & PaneRight) { + content_right_pane.add (content_right_vbox); + content_right_vbox.pack_start (content_att_right, true, true); + } content_inner_vbox.pack_start (content_toolbar, false, false); content_inner_vbox.pack_start (content_innermost_hbox, true, true); - content_right_pane.set_child_minsize (content_att_right, 160); /* rough guess at width of notebook tabs */ + if (_panelayout & PaneRight) { + content_right_pane.set_child_minsize (content_att_right, 160); /* rough guess at width of notebook tabs */ + } content_right_pane.set_check_divider_position (true); content_right_pane.set_divider (0, 0.85); + if (_panelayout & PaneLeft) { + content_left_pane.set_child_minsize (content_att_left, 80); + } + content_left_pane.set_check_divider_position (true); + content_left_pane.set_divider (0, 0.15); + _content_vbox.show_all(); } @@ -412,7 +433,8 @@ Tabbable::get_state() const node.set_property (X_("tabbed"), tabbed()); - node.set_property (string_compose("%1%2", _menu_name, X_("-listpane-pos")).c_str(), content_right_pane.get_divider ()); + node.set_property (string_compose("%1%2", _menu_name, X_("-rightpane-pos")).c_str(), content_right_pane.get_divider ()); + node.set_property (string_compose("%1%2", _menu_name, X_("-leftpane-pos")).c_str(), content_left_pane.get_divider ()); return node; } @@ -436,10 +458,14 @@ Tabbable::set_state (const XMLNode& node, int version) if (window_node) { window_node->get_property (X_("tabbed"), tab_requested_by_state); float fract; - if ( window_node->get_property (string_compose("%1%2", _menu_name, X_("-listpane-pos")).c_str(), fract) ) { + if ( window_node->get_property (string_compose("%1%2", _menu_name, X_("-rightpane-pos")).c_str(), fract) ) { fract = std::max (.05f, std::min (.95f, fract)); content_right_pane.set_divider (0, fract); } + if ( window_node->get_property (string_compose("%1%2", _menu_name, X_("-leftpane-pos")).c_str(), fract) ) { + fract = std::max (.05f, std::min (.95f, fract)); + content_left_pane.set_divider (0, fract); + } } diff --git a/libs/widgets/widgets/tabbable.h b/libs/widgets/widgets/tabbable.h index a7be3cd8e8..1f807b22ca 100644 --- a/libs/widgets/widgets/tabbable.h +++ b/libs/widgets/widgets/tabbable.h @@ -48,7 +48,17 @@ namespace ArdourWidgets { class LIBWIDGETS_API Tabbable : public Gtkmm2ext::WindowProxy { public: - Tabbable (const std::string& user_visible_name, std::string const & untranslated_name, Gtk::Widget* top = NULL, bool tabbed_by_default = true); + enum PaneLayout { + NoPanes = 0x0, ///< disable all attachment buttons, do not pack any panes or attachments + PaneLeft = 0x1, ///< left side attachment is a resizable pane + PaneRight = 0x2, ///< pack a resizable Pane on the right-side + AttBottom = 0x4, ///< bottom is a fixed size EBox attachment + PaneLeftBtm = 0x5, + PaneRightBtm = 0x6, + AttLeft = 0x8, ///< if PaneLeft is not set, pack a fixed size Ebox on the left (Editor-Mixer) + }; + + Tabbable (const std::string& user_visible_name, std::string const & untranslated_name, Gtk::Widget* top = NULL, bool tabbed_by_default = true, PaneLayout pl = PaneRightBtm); ~Tabbable (); void add_to_notebook (Gtk::Notebook& notebook); @@ -101,9 +111,54 @@ protected: bool delete_event_handler (GdkEventAny *ev); /* This is the heirarchy of a Tabbable's widget packing. - * The end result is to provide 8(ish) event-boxen where the tab can put its contents - * Please maintain the indention here so the hierarchy is visible - */ + * + * The end result is to provide 7 event-boxes (marked with a $) where the tab can put its contents. + * + * +--_content_vbox----------------------------------------------------------------------------------+ + * | | + * | /--toolbar_frame------------------------------------------------------------------------------\ | + * | | +--content_header_hbox--------------------------------------------------------------------+ | | + * | | | | | | + * | | | +--content_app_bar--------------------+ +--attachment_hbox--+ +--content_tabbables--+ | | | + * | | | $ (EBOX) | | (internal) | $ (EBOX) | | | | + * | | | | MAIN APPLICATION BAR | | (attachment btns) | | PAGE SWITCHER BTN | | | | + * | | | | | | | | | | | | + * | | | +-------------------------------------+ +-------------------+ +---------------------+ | | | + * | | | | | | + * | | +-----------------------------------------------------------------------------------------+ | | + * | \---------------------------------------------------------------------------------------------/ | + * | | + * | +--content_hbox--OR--content_left_pane--------------------------------------------------------+ | + * | | | | + * | | +--att_left--+ +--content_midlevel_vbox-------------------------------------------------+ | | + * | | $ (EBOX) | | +--content_right_pane------------------------------------------------+ | | | + * | | | | | | +--content_inner_vbox-----------------+ +--content_right_vbox--+ | | | | + * | | | O | | | | | | | | | | | + * | | | P S | | | | +--content_toolbar----------------+ | | +--att_right-------+ | | | | | + * | | | T I | | | | $ OPTIONAL TOOLBAR (EBOX) | | | $ (EBOX) | | | | | | + * | | | I D | | | | +---------------------------------+ |<->| | | | | | | | + * | | | O E |<->| | | | P | | OPTIONAL | | | | | | + * | | | N B | O | | | +--content_innermost_hbox---------+ | A | | SIDEBAR | | | | | | + * | | | A A | P | | | $ (HBOX) | | N | | | | | | | | + * | | | L R | T | | | | | | E | | | | | | | | + * | | | | . | | | | !! MAIN PAGE CONTENT !! | |<->| | (LIST) | | | | | | + * | | | | P | | | | | | | | | | | | | | + * | | | | A | | | | | | | | | | | | | | + * | | | | N | | | +---------------------------------+ | | +------------------+ | | | | | + * | | | (STRIP) | E | | +-------------------------------------+ +----------------------+ | | | | + * | | | |<->| +--------------------------------------------------------------------+ | | | + * | | | | | | | | + * | | | | | +-content_att_bottom-------------------------------------------------+ | | | + * | | | | | $ (EBOX) | | | | + * | | | | | | OPTIONAL BOTTOM (PROPERTIES) | | | | + * | | | | | | | | | | + * | | | | | +--------------------------------------------------------------------+ | | | + * | | +------------+ +------------------------------------------------------------------------+ | | + * | +---------------------------------------------------------------------------------------------+ | + * | | + * +-------------------------------------------------------------------------------------------------+ + * + */ /* clang-format off */ /* _content_vbox * toplevel @@ -113,6 +168,7 @@ protected: Gtk::EventBox content_attachments; /* a placeholder the (strip, list, props) visibility buttons for this tab */ Gtk::HBox content_attachment_hbox; EventBoxExt content_tabbables; /* a placeholder for the tabbable switching buttons (used by ArdourUI) */ + HPane content_left_pane; Gtk::HBox content_hbox; EventBoxExt content_att_left; /* a placeholder for the mixer strip, if you want one */ Gtk::VBox content_midlevel_vbox; @@ -144,6 +200,7 @@ private: Gtk::Notebook _own_notebook; Gtk::Notebook* _parent_notebook; bool tab_requested_by_state; + PaneLayout _panelayout; }; diff --git a/wscript b/wscript index 8ef65243d0..e9d1e7b94b 100644 --- a/wscript +++ b/wscript @@ -749,14 +749,10 @@ int main() { return 0; }''', compiler_flags.append ('-DMIXBUS') conf.define('MIXBUS', 1) - if Options.options.program_name.lower() == "mixbus32c": - conf.define('MIXBUS32C', 1) - compiler_flags.append ('-DMIXBUS32C') - if Options.options.program_name.lower() == "livetrax": compiler_flags.append ('-DLIVETRAX') conf.define ('LIVETRAX', 1) - + compiler_flags.append ('-DPROGRAM_NAME="' + Options.options.program_name + '"') compiler_flags.append ('-DPROGRAM_VERSION="' + PROGRAM_VERSION + '"')