13
0

Merge branch 'ardour'

This commit is contained in:
Robin Gareus 2024-11-15 14:31:06 +01:00
commit 90d45ac428
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
31 changed files with 905 additions and 273 deletions

View File

@ -163,6 +163,29 @@ bool drag_failed (const Glib::RefPtr<Gdk::DragContext>& context, DragResult resu
void void
ARDOUR_UI::setup_transport () ARDOUR_UI::setup_transport ()
{ {
/* NOTE - LIVETRAX does not call this */
RefPtr<Action> 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)); 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)); mixer_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), mixer));
#ifndef LIVETRAX #ifndef LIVETRAX

View File

@ -525,6 +525,11 @@ ARDOUR_UI::livetrax_setup_windows ()
act = ActionManager::get_action (X_("Common"), X_("open-media-folder")); act = ActionManager::get_action (X_("Common"), X_("open-media-folder"));
livetrax_view_in_folder_button->set_related_action (act); 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)); _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 /* pack the main vpacker into the main window and show everything

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2011-2017 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2024 Ben Loftis <ben@harrisonconsoles.com>
*
* 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 <algorithm>
#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 ()
{
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2024 Ben Loftis <ben@harrisonconsoles.com>
*
* 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 <map>
#include <gtkmm/box.h>
#include <gtkmm/label.h>
#include <gtkmm/table.h>
#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:
};

View File

@ -61,6 +61,7 @@ using namespace Gtk;
using namespace Gtkmm2ext; using namespace Gtkmm2ext;
using namespace PBD; using namespace PBD;
using namespace Temporal; using namespace Temporal;
using namespace ArdourWidgets;
using std::string; using std::string;
sigc::signal<void> EditingContext::DropDownKeys; sigc::signal<void> EditingContext::DropDownKeys;
@ -124,11 +125,15 @@ EditingContext::EditingContext (std::string const & name)
#endif #endif
, _snap_mode (SnapOff) , _snap_mode (SnapOff)
, _timeline_origin (0.) , _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)) , _drags (new DragManager (this))
, _leftmost_sample (0) , _leftmost_sample (0)
, _playhead_cursor (nullptr) , _playhead_cursor (nullptr)
, _snapped_cursor (nullptr) , _snapped_cursor (nullptr)
, _follow_playhead (false) , _follow_playhead (false)
, visible_channel_label (_("MIDI|Channel"))
, selection (new Selection (this, true)) , selection (new Selection (this, true))
, cut_buffer (new Selection (this, false)) , cut_buffer (new Selection (this, false))
, _selection_memento (new SelectionMemento()) , _selection_memento (new SelectionMemento())
@ -153,6 +158,8 @@ EditingContext::EditingContext (std::string const & name)
, entered_regionview (nullptr) , entered_regionview (nullptr)
, clear_entered_track (false) , clear_entered_track (false)
{ {
using namespace Gtk::Menu_Helpers;
if (!button_bindings) { if (!button_bindings) {
button_bindings = new Bindings ("editor-mouse"); 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 (grid_type_selector, _("Grid Mode"));
set_tooltip (snap_mode_button, _("Snap Mode\n\nRight-click to visit Snap preferences.")); 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 */ /* handle escape */
ARDOUR_UI::instance()->Escape.connect (escape_connection, MISSING_INVALIDATOR, std::bind (&EditingContext::escape, this), gui_context()); 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() EditingContext::~EditingContext()
{ {
} }
void
EditingContext::ui_parameter_changed (string parameter)
{
if (parameter == "sound-midi-note") {
}
}
void
EditingContext::parameter_changed (string parameter)
{
}
void void
EditingContext::set_session (ARDOUR::Session* s) 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 For now, drop down and use C API
*/ */
gdk_window_set_cursor (win->gobj(), cursor ? cursor->gobj() : 0); 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) EditingContext::push_canvas_cursor (Gdk::Cursor* cursor)
{ {
if (!_cursors->is_invalid (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); _cursor_stack.push_back (cursor);
set_canvas_cursor (cursor); set_canvas_cursor (cursor);
} }
@ -2066,7 +2111,7 @@ EditingContext::pop_canvas_cursor ()
} }
_cursor_stack.pop_back(); _cursor_stack.pop_back();
if (_cursor_stack.back()) { if (!_cursor_stack.empty()) {
/* Popped to an existing cursor, we're done. Otherwise, the /* Popped to an existing cursor, we're done. Otherwise, the
context that created this cursor has been destroyed, so we need context that created this cursor has been destroyed, so we need
to skip to the next down the stack. */ 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 ()
{
}

View File

@ -494,6 +494,17 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
void snap_mode_chosen (Editing::SnapMode); void snap_mode_chosen (Editing::SnapMode);
void grid_type_chosen (Editing::GridType); 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; DragManager* _drags;
ArdourWidgets::ArdourButton snap_mode_button; ArdourWidgets::ArdourButton snap_mode_button;
@ -674,6 +685,10 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
uint32_t autoscroll_cnt; uint32_t autoscroll_cnt;
ArdourCanvas::Rect autoscroll_boundary; 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; bool _mouse_changed_selection;
ArdourMarker* entered_marker; ArdourMarker* entered_marker;
TimeAxisView* entered_track; TimeAxisView* entered_track;

View File

@ -305,8 +305,8 @@ Editor::Editor ()
, controls_layout (unused_adjustment, vertical_adjustment) , controls_layout (unused_adjustment, vertical_adjustment)
, _scroll_callbacks (0) , _scroll_callbacks (0)
, _full_canvas_height (0) , _full_canvas_height (0)
, edit_controls_left_menu (nullptr) , edit_controls_left_menu (0)
, edit_controls_right_menu (nullptr) , edit_controls_right_menu (0)
, _trigger_clip_picker (nullptr) , _trigger_clip_picker (nullptr)
, _tvl_no_redisplay(false) , _tvl_no_redisplay(false)
, _tvl_redisplay_on_resume(false) , _tvl_redisplay_on_resume(false)
@ -651,20 +651,11 @@ Editor::Editor ()
Location::end_changed.connect (*this, invalidator (*this), std::bind (&Editor::location_changed, this, _1), gui_context()); 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()); Location::changed.connect (*this, invalidator (*this), std::bind (&Editor::location_changed, this, _1), gui_context());
#if SELECTION_PROPERTIES_BOX_TODO #ifndef LIVETRAX
add_notebook_page (_("Selection"), *_properties_box);
#warning Fix Properties Sidebar Layout to fit < 720px height
#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 (_("Tracks & Busses"), _routes->widget ());
add_notebook_page (_("Sources"), _sources->widget ()); add_notebook_page (_("Sources"), _sources->widget ());
add_notebook_page (_("Regions"), _regions->widget ()); add_notebook_page (_("Regions"), _regions->widget ());
add_notebook_page (_("Clips"), *_trigger_clip_picker); add_notebook_page (_("Clips"), _trigger_clip_picker);
add_notebook_page (_("Arrangement"), _sections->widget ()); add_notebook_page (_("Arrangement"), _sections->widget ());
add_notebook_page (_("Snapshots"), _snapshots->widget ()); add_notebook_page (_("Snapshots"), _snapshots->widget ());
add_notebook_page (_("Track & Bus Groups"), _route_groups->widget ()); add_notebook_page (_("Track & Bus Groups"), _route_groups->widget ());
@ -675,7 +666,7 @@ Editor::Editor ()
_the_notebook.popup_disable (); _the_notebook.popup_disable ();
_the_notebook.set_tab_pos (Gtk::POS_RIGHT); _the_notebook.set_tab_pos (Gtk::POS_RIGHT);
_the_notebook.show_all (); _the_notebook.show_all ();
} #endif
_notebook_shrunk = false; _notebook_shrunk = false;
@ -688,14 +679,38 @@ Editor::Editor ()
settings->get_property ("notebook-shrunk", _notebook_shrunk); 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);
VBox* summary_arrows_right = manage (new VBox);
summary_arrows_right->pack_start (*summary_arrow_right);
Gtk::Frame* summary_frame = manage (new Gtk::Frame);
summary_frame->set_shadow_type (Gtk::SHADOW_ETCHED_IN);
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_summary_pane.add (_summary_hbox);
_editor_list_vbox.pack_start (_the_notebook); _editor_list_vbox.pack_start (_the_notebook);
_editor_list_vbox.pack_start (*_properties_box, false, false, 0);
content_right_pane.set_drag_cursor (*_cursors->expand_left_right); content_right_pane.set_drag_cursor (*_cursors->expand_left_right);
editor_summary_pane.set_drag_cursor (*_cursors->expand_up_down); editor_summary_pane.set_drag_cursor (*_cursors->expand_up_down);
@ -705,12 +720,13 @@ Editor::Editor ()
/* initial allocation is 90% to canvas, 10% to summary */ /* initial allocation is 90% to canvas, 10% to summary */
fract = 0.90; fract = 0.90;
} }
} editor_summary_pane.set_divider (0, fract);
#endif
global_vpacker.set_spacing (0); global_vpacker.set_spacing (0);
global_vpacker.set_border_width (0); global_vpacker.set_border_width (0);
if (!Profile->get_livetrax()) { #ifndef LIVETRAX
ArdourWidgets::ArdourDropShadow *toolbar_shadow = manage (new (ArdourWidgets::ArdourDropShadow)); ArdourWidgets::ArdourDropShadow *toolbar_shadow = manage (new (ArdourWidgets::ArdourDropShadow));
toolbar_shadow->set_size_request (-1, 4); toolbar_shadow->set_size_request (-1, 4);
toolbar_shadow->set_mode(ArdourWidgets::ArdourDropShadow::DropShadowBoth); toolbar_shadow->set_mode(ArdourWidgets::ArdourDropShadow::DropShadowBoth);
@ -724,6 +740,7 @@ Editor::Editor ()
*/ */
content_app_bar.add (_application_bar); content_app_bar.add (_application_bar);
content_att_right.add (_editor_list_vbox); content_att_right.add (_editor_list_vbox);
content_att_bottom.add (*_properties_box);
content_toolbar.add (global_vpacker); content_toolbar.add (global_vpacker);
content_innermost_hbox.add (editor_summary_pane); content_innermost_hbox.add (editor_summary_pane);
@ -733,11 +750,11 @@ Editor::Editor ()
content_hbox.show (); content_hbox.show ();
ebox_hpacker.show(); ebox_hpacker.show();
global_vpacker.show(); global_vpacker.show();
} else { #else /* LIVETRAX */
global_vpacker.pack_start (edit_packer, true, true); global_vpacker.pack_start (edit_packer, true, true);
content_innermost_hbox.add (global_vpacker); content_innermost_hbox.add (global_vpacker);
global_vpacker.show(); global_vpacker.show();
} #endif
/* register actions now so that set_state() can find them and set toggles/checks etc */ /* 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)); 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)); 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()); TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), std::bind (&Editor::timeaxisview_deleted, this, _1), gui_context());
_ignore_region_action = false; _ignore_region_action = false;
@ -2350,6 +2364,15 @@ Editor::set_state (const XMLNode& node, int version)
tact->set_active (yn); tact->set_active (yn);
} }
yn = false;
node.get_property ("show-editor-props", yn);
{
Glib::RefPtr<ToggleAction> 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; int32_t el_page;
if (node.get_property (X_("editor-list-page"), el_page)) { if (node.get_property (X_("editor-list-page"), el_page)) {
_the_notebook.set_current_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")); tact = ActionManager::get_toggle_action (X_("Editor"), X_("show-editor-list"));
node->set_property (X_("show-editor-list"), tact->get_active()); 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 ()); node->set_property (X_("editor-list-page"), _the_notebook.get_current_page ());
if (button_bindings) { if (button_bindings) {
@ -5841,6 +5867,8 @@ Editor::zoom_vertical_modifier_released()
void void
Editor::ui_parameter_changed (string parameter) Editor::ui_parameter_changed (string parameter)
{ {
EditingContext::ui_parameter_changed (parameter);
if (parameter == "icon-set") { if (parameter == "icon-set") {
while (!_cursor_stack.empty()) { while (!_cursor_stack.empty()) {
_cursor_stack.pop_back(); _cursor_stack.pop_back();

View File

@ -1100,7 +1100,7 @@ Editor::marker_click_behavior_chosen (Editing::MarkerClickBehavior m)
void void
Editor::parameter_changed (std::string p) Editor::parameter_changed (std::string p)
{ {
ENSURE_GUI_THREAD (*this, &Editor::parameter_changed, p) EditingContext::parameter_changed (p);
if (p == "auto-loop") { if (p == "auto-loop") {
update_loop_range_view (); update_loop_range_view ();

View File

@ -7540,3 +7540,81 @@ VelocityLineDrag::aborted (bool)
{ {
vd->end_line_drag (false); 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)
{
}

View File

@ -1640,6 +1640,39 @@ class VelocityLineDrag : public FreehandLineDrag<Evoral::ControlList::OrderedPoi
bool drag_did_change; bool drag_did_change;
}; };
class ClipStartDrag : public Drag
{
public:
ClipStartDrag (EditingContext&, ArdourCanvas::Rectangle &, Temporal::timepos_t const &);
~ClipStartDrag ();
void start_grab (GdkEvent*,Gdk::Cursor*);
bool end_grab (GdkEvent*);
void motion (GdkEvent*, bool);
void finished (GdkEvent*, bool);
void aborted (bool);
private:
ArdourCanvas::Rectangle* dragging_rect;
Temporal::timepos_t original_start;
};
class ClipEndDrag : public Drag
{
public:
ClipEndDrag (EditingContext&, ArdourCanvas::Rectangle &, Temporal::timepos_t const &);
~ClipEndDrag ();
void start_grab (GdkEvent*,Gdk::Cursor*);
bool end_grab (GdkEvent*);
void motion (GdkEvent*, bool);
void finished (GdkEvent*, bool);
void aborted (bool);
private:
ArdourCanvas::Rectangle* dragging_rect;
Temporal::timepos_t original_end;
};
#endif /* __gtk2_ardour_editor_drag_h_ */ #endif /* __gtk2_ardour_editor_drag_h_ */

View File

@ -69,6 +69,8 @@ enum ItemType {
GridZoneItem, GridZoneItem,
VelocityItem, VelocityItem,
VelocityBaseItem, VelocityBaseItem,
ClipStartItem,
ClipEndItem,
/* don't remove this */ /* don't remove this */

View File

@ -31,6 +31,8 @@
#include "gtkmm2ext/actions.h" #include "gtkmm2ext/actions.h"
#include "widgets/ardour_button.h" #include "widgets/ardour_button.h"
#include "widgets/ardour_dropdown.h"
#include "widgets/tooltips.h"
#include "ardour_ui.h" #include "ardour_ui.h"
#include "editor_cursors.h" #include "editor_cursors.h"
@ -74,10 +76,9 @@ MidiCueEditor::MidiCueEditor()
build_grid_type_menu (); build_grid_type_menu ();
build_draw_midi_menus(); build_draw_midi_menus();
build_upper_toolbar ();
build_canvas (); build_canvas ();
setup_toolbar (); build_lower_toolbar ();
_toolbox.pack_start (viewport(), true, true);
set_mouse_mode (Editing::MouseContent, true); set_mouse_mode (Editing::MouseContent, true);
} }
@ -126,8 +127,36 @@ MidiCueEditor::canvas_pre_event (GdkEvent* ev)
} }
void void
MidiCueEditor::setup_toolbar () MidiCueEditor::build_lower_toolbar ()
{ {
velocity_button = new ArdourButton (_("Velocity"), ArdourButton::Text, true);
bender_button = new ArdourButton (_("Bender"), ArdourButton::Text, true);
pressure_button = new ArdourButton (_("Pressure"), ArdourButton::Text, true);
expression_button = new ArdourButton (_("Expression"), ArdourButton::Text, true);
modulation_button = new ArdourButton (_("Modulation"), ArdourButton::Text, true);
// button_bar.set_homogeneous (true);
button_bar.set_spacing (6);
button_bar.set_border_width (6);
button_bar.pack_start (*velocity_button, false, false);
button_bar.pack_start (*bender_button, false, false);
button_bar.pack_start (*pressure_button, false, false);
button_bar.pack_start (*modulation_button, false, false);
velocity_button->signal_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); Gtk::HBox* mode_box = manage(new Gtk::HBox);
mode_box->set_border_width (2); mode_box->set_border_width (2);
mode_box->set_spacing(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 (grid_box, false, false);
_toolbar_inner->pack_start (draw_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); _toolbar_outer->pack_start (*_toolbar_inner, true, false);
_toolbox.pack_start (*_toolbar_outer, false, false); _toolbox.pack_start (*_toolbar_outer, false, false);
Bindings* pr_bindings = Bindings::get_bindings (X_("Pianoroll")); Bindings* pr_bindings = Bindings::get_bindings (X_("Pianoroll"));
_toolbox.set_data (X_("ardour-bindings"), pr_bindings); _toolbox.set_data (X_("ardour-bindings"), pr_bindings);
} }
void
MidiCueEditor::set_visible_channel (int n)
{
}
void void
MidiCueEditor::build_canvas () MidiCueEditor::build_canvas ()
{ {
@ -268,7 +312,7 @@ MidiCueEditor::build_canvas ()
prh = new ArdourCanvas::PianoRollHeader (v_scroll_group, *bg); 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); bg->set_view (view);
prh->set_view (view); prh->set_view (view);
@ -282,6 +326,7 @@ MidiCueEditor::build_canvas ()
prh->set_position (Duple (0., n_timebars * timebar_height)); prh->set_position (Duple (0., n_timebars * timebar_height));
data_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars)); 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)); cursor_scroll_group->set_position (ArdourCanvas::Duple (_timeline_origin, timebar_height * n_timebars));
h_scroll_group->set_position (Duple (_timeline_origin, 0.)); 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_sensitive (UIConfiguration::instance().get_sensitize_playhead());
_playhead_cursor->set_color (UIConfiguration::instance().color ("play head")); _playhead_cursor->set_color (UIConfiguration::instance().color ("play head"));
_playhead_cursor->canvas_item().raise_to_top(); _playhead_cursor->canvas_item().raise_to_top();
h_scroll_group->raise_to_top ();
_canvas->set_name ("MidiCueCanvas"); _canvas->set_name ("MidiCueCanvas");
_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK); _canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
_canvas->set_can_focus (); _canvas->set_can_focus ();
_toolbox.pack_start (*_canvas_viewport, true, true);
bindings_changed (); bindings_changed ();
} }
@ -317,11 +365,6 @@ MidiCueEditor::maybe_update ()
return; return;
} }
if (_track->rec_enable_control()->get_value()) {
/* ::data_captured() will handle it */
return;
}
ARDOUR::TriggerPtr trigger = _track->triggerbox()->currently_playing (); ARDOUR::TriggerPtr trigger = _track->triggerbox()->currently_playing ();
if (!trigger) { if (!trigger) {
@ -1613,8 +1656,6 @@ MidiCueEditor::which_canvas_cursor (ItemType type) const
bool bool
MidiCueEditor::enter_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_type) MidiCueEditor::enter_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType item_type)
{ {
EditorAutomationLine* al;
choose_canvas_cursor_on_entry (item_type); choose_canvas_cursor_on_entry (item_type);
switch (item_type) { switch (item_type) {
@ -1752,6 +1793,8 @@ MidiCueEditor::set_region (std::shared_ptr<ARDOUR::MidiRegion> r)
} }
view->set_region (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 */ /* Compute zoom level to show entire source plus some margin if possible */
@ -1774,9 +1817,36 @@ MidiCueEditor::set_region (std::shared_ptr<ARDOUR::MidiRegion> r)
{ {
EditingContext::TempoMapScope tms (*this, map); EditingContext::TempoMapScope tms (*this, map);
double width = bg->width(); 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; std::cerr << "new spp from " << samples << " / " << width << std::endl;
samplecnt_t spp = floor (samples / width); samplecnt_t spp = floor (samples / width);
reset_zoom (spp); 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);
}
}

View File

@ -109,6 +109,8 @@ class MidiCueEditor : public CueEditor
Gdk::Cursor* which_trim_cursor (bool left_side) const; Gdk::Cursor* which_trim_cursor (bool left_side) const;
Gdk::Cursor* which_canvas_cursor (ItemType type) const; Gdk::Cursor* which_canvas_cursor (ItemType type) const;
void set_visible_channel (int chan);
protected: protected:
void register_actions (); void register_actions ();
@ -171,11 +173,20 @@ class MidiCueEditor : public CueEditor
Gtk::VBox _toolbox; 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; CueMidiBackground* bg;
MidiCueView* view; MidiCueView* view;
void build_canvas (); void build_canvas ();
void canvas_allocate (Gtk::Allocation); void canvas_allocate (Gtk::Allocation);
void build_upper_toolbar ();
void build_lower_toolbar ();
RegionSelection region_selection(); RegionSelection region_selection();
@ -199,7 +210,6 @@ class MidiCueEditor : public CueEditor
BBTMetric bbt_metric; BBTMetric bbt_metric;
bool canvas_pre_event (GdkEvent*); bool canvas_pre_event (GdkEvent*);
void setup_toolbar ();
/* autoscrolling */ /* autoscrolling */
@ -222,6 +232,11 @@ class MidiCueEditor : public CueEditor
std::atomic<int> idle_update_queued; std::atomic<int> idle_update_queued;
PBD::ScopedConnectionList capture_connections; PBD::ScopedConnectionList capture_connections;
samplecnt_t data_capture_duration; 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;
}; };

View File

@ -48,6 +48,7 @@ using namespace Gtkmm2ext;
MidiCueView::MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt, MidiCueView::MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt,
uint32_t slot_index, uint32_t slot_index,
ArdourCanvas::Item& parent, ArdourCanvas::Item& parent,
ArdourCanvas::Item& noscroll_parent,
EditingContext& ec, EditingContext& ec,
MidiViewBackground& bg, MidiViewBackground& bg,
uint32_t basic_color) uint32_t basic_color)
@ -55,11 +56,10 @@ MidiCueView::MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt,
, active_automation (nullptr) , active_automation (nullptr)
, velocity_display (nullptr) , velocity_display (nullptr)
, _slot_index (slot_index) , _slot_index (slot_index)
, _height (0.)
{ {
CANVAS_DEBUG_NAME (_note_group, X_("note group for MIDI cue")); 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 /* 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 * that will. It will be resized as needed sothat it always covers the
* entire canvas/view. * entire canvas/view.
@ -79,46 +79,8 @@ MidiCueView::MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt,
automation_group->set_fill_color (UIConfiguration::instance().color ("midi automation track fill")); automation_group->set_fill_color (UIConfiguration::instance().color ("midi automation track fill"));
automation_group->set_data ("linemerger", this); 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); set_extensible (true);
/* show velocity by default */
update_automation_display (Evoral::Parameter (MidiVelocityAutomation, 0, 0), SelectionSet);
} }
MidiCueView::~MidiCueView () MidiCueView::~MidiCueView ()
@ -129,11 +91,18 @@ MidiCueView::~MidiCueView ()
void void
MidiCueView::set_height (double h) MidiCueView::set_height (double h)
{ {
double bbw, bbh; _height = h;
button_bar->size_request (bbw, bbh);
double note_area_height = ceil ((h - bbh) / 2.); double note_area_height;
double automation_height = ceil (h - bbh - 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)); 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); 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_position (ArdourCanvas::Duple (0., note_area_height));
automation_group->set (ArdourCanvas::Rect (0., 0., ArdourCanvas::COORD_MAX, automation_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) { for (auto & ads : automation_map) {
ads.second.set_height (automation_height); 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 void
MidiCueView::update_automation_display (Evoral::Parameter const & param, SelectionOperation op) 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 */ /* undefined in this context */
break; break;
} }
set_height (_height);
} }
std::list<SelectableOwner*> std::list<SelectableOwner*>

View File

@ -35,7 +35,6 @@ class MidiCueAutomationLine;
namespace ArdourCanvas { namespace ArdourCanvas {
class Box; class Box;
class Button;
} }
class MidiCueView : public MidiView class MidiCueView : public MidiView
@ -44,6 +43,7 @@ class MidiCueView : public MidiView
MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt, MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt,
uint32_t slot_index, uint32_t slot_index,
ArdourCanvas::Item& parent, ArdourCanvas::Item& parent,
ArdourCanvas::Item& noscroll_parent,
EditingContext& ec, EditingContext& ec,
MidiViewBackground& bg, MidiViewBackground& bg,
uint32_t basic_color uint32_t basic_color
@ -109,13 +109,6 @@ class MidiCueView : public MidiView
VelocityDisplay* velocity_display; 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<Temporal::TempoMap const> tempo_map; std::shared_ptr<Temporal::TempoMap const> tempo_map;
ArdourCanvas::Rectangle* event_rect; ArdourCanvas::Rectangle* event_rect;
uint32_t _slot_index; uint32_t _slot_index;
@ -123,6 +116,5 @@ class MidiCueView : public MidiView
void update_sustained (Note *); void update_sustained (Note *);
void update_hit (Hit *); void update_hit (Hit *);
bool automation_button_event (GdkEvent*, Evoral::ParameterType type, int id); double _height;
void automation_button_click (Evoral::ParameterType type, int id, ARDOUR::SelectionOperation);
}; };

View File

@ -120,9 +120,10 @@ MidiView::MidiView (std::shared_ptr<MidiTrack> mt,
, _step_edit_cursor (0) , _step_edit_cursor (0)
, _step_edit_cursor_width (1, 0) , _step_edit_cursor_width (1, 0)
, _channel_selection_scoped_note (0) , _channel_selection_scoped_note (0)
, _needs_active_notes_for_rec_enabled_track (false)
, _mouse_state(None) , _mouse_state(None)
, _pressed_button(0) , _pressed_button(0)
, _start_boundary_rect (nullptr)
, _end_boundary_rect (nullptr)
, _optimization_iterator (_events.end()) , _optimization_iterator (_events.end())
, _list_editor (nullptr) , _list_editor (nullptr)
, _no_sound_notes (false) , _no_sound_notes (false)
@ -152,7 +153,6 @@ MidiView::MidiView (MidiView const & other)
, _step_edit_cursor (0) , _step_edit_cursor (0)
, _step_edit_cursor_width (1, 0) , _step_edit_cursor_width (1, 0)
, _channel_selection_scoped_note (0) , _channel_selection_scoped_note (0)
, _needs_active_notes_for_rec_enabled_track (false)
, _mouse_state(None) , _mouse_state(None)
, _pressed_button(0) , _pressed_button(0)
, _optimization_iterator (_events.end()) , _optimization_iterator (_events.end())
@ -186,6 +186,52 @@ MidiView::init (std::shared_ptr<MidiTrack> mt)
_midi_context.NoteRangeChanged.connect (sigc::mem_fun (*this, &MidiView::view_changed)); _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 void
MidiView::set_track (std::shared_ptr<MidiTrack> mt) MidiView::set_track (std::shared_ptr<MidiTrack> mt)
{ {

View File

@ -348,6 +348,9 @@ class MidiView : public virtual sigc::trackable, public LineMerger
void select_self () { select_self (false); } void select_self () { select_self (false); }
virtual void select_self_uniquely () {} virtual void select_self_uniquely () {}
void show_start (bool yn);
void show_end (bool yn);
protected: protected:
void init (std::shared_ptr<ARDOUR::MidiTrack>); void init (std::shared_ptr<ARDOUR::MidiTrack>);
virtual void region_resized (const PBD::PropertyChange&); 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_width;
Temporal::Beats _step_edit_cursor_position; Temporal::Beats _step_edit_cursor_position;
NoteBase* _channel_selection_scoped_note; NoteBase* _channel_selection_scoped_note;
bool _needs_active_notes_for_rec_enabled_track;
MouseState _mouse_state; MouseState _mouse_state;
int _pressed_button; int _pressed_button;
ArdourCanvas::Rectangle* _start_boundary_rect;
ArdourCanvas::Rectangle* _end_boundary_rect;
/** Currently selected NoteBase objects */ /** Currently selected NoteBase objects */
Selection _selection; Selection _selection;

View File

@ -133,7 +133,7 @@ Mixer_UI::instance ()
} }
Mixer_UI::Mixer_UI () Mixer_UI::Mixer_UI ()
: Tabbable (_("Mixer"), X_("mixer")) : Tabbable (_("Mixer"), X_("mixer"), NULL, true, Tabbable::NoPanes)
, plugin_search_clear_button (X_("Clear")) , plugin_search_clear_button (X_("Clear"))
, _mixer_scene_release (0) , _mixer_scene_release (0)
, no_track_list_redisplay (false) , no_track_list_redisplay (false)
@ -164,13 +164,6 @@ Mixer_UI::Mixer_UI ()
contents().set_data ("ardour-bindings", bindings); 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()); 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()); 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(); favorite_plugins_scroller.show();
group_display_vbox.show(); group_display_vbox.show();
group_display_frame.show(); group_display_frame.show();
favorite_plugins_frame.show(); favorite_plugins_frame.show_all();
rhs_pane1.show(); rhs_pane1.show();
rhs_pane2.show(); rhs_pane2.show();
strip_packer.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)); 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); left_attachment_button.set_related_action (act);
act = ActionManager::register_toggle_action (group, "ToggleMixerStrip", _("(Mixer) Show Sidebar Strip"), []{}); act = ActionManager::register_toggle_action (group, "ToggleMixerStrip", _("(Mixer) Show Sidebar Strip"), []{});
content_right_pane.remove(content_right_vbox);
} else { } else {
act = ActionManager::register_toggle_action (group, "ToggleMixerList", _("(Mixer) Show Sidebar List"), sigc::mem_fun (*this, &Tabbable::att_right_button_toggled)); 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); 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)); 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); bottom_attachment_button.set_related_action (act);
#else #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, "ToggleMixerProps", _("(Mixer) Show Properties Bottom"), []{});
act = ActionManager::register_toggle_action (group, "ToggleMixerStrip", _("(Mixer) Show Sidebar Strip"), []{}); act = ActionManager::register_toggle_action (group, "ToggleMixerStrip", _("(Mixer) Show Sidebar Strip"), []{});
act = ActionManager::register_toggle_action (group, "ToggleMixerList", _("(Mixer) Show Sidebar List"), []{}); act = ActionManager::register_toggle_action (group, "ToggleMixerList", _("(Mixer) Show Sidebar List"), []{});

View File

@ -153,8 +153,6 @@ public:
void toggle_mixer_strip (); void toggle_mixer_strip ();
void toggle_mixer_props (); void toggle_mixer_props ();
void showhide_mixer_list (bool yn);
void toggle_surround_master (); void toggle_surround_master ();
void toggle_monitor_section (); void toggle_monitor_section ();

View File

@ -37,6 +37,7 @@
#include "gui_thread.h" #include "gui_thread.h"
#include "midi_view.h" #include "midi_view.h"
#include "midi_view_background.h" #include "midi_view_background.h"
#include "mouse_cursors.h"
#include "prh.h" #include "prh.h"
#include "editing_context.h" #include "editing_context.h"
#include "ui_config.h" #include "ui_config.h"
@ -630,21 +631,19 @@ PianoRollHeader::motion_handler (GdkEventMotion* ev)
if (!_scroomer_drag && ev->x < _scroomer_size){ 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 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){ if (evd.y > scroomer_top - 5 && evd.y < scroomer_top + edge){
m_Cursor = Gdk::Cursor (Gdk::TOP_SIDE); _view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->resize_top);
_view->editing_context().push_canvas_cursor (&m_Cursor);
_scroomer_state = TOP; _scroomer_state = TOP;
} else if (evd.y > scroomer_bottom - 5 && evd.y < scroomer_bottom + 5){ } else if (evd.y > scroomer_bottom - edge && evd.y < scroomer_bottom + edge){
m_Cursor = Gdk::Cursor (Gdk::BOTTOM_SIDE); _view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->resize_bottom);
_view->editing_context().push_canvas_cursor (&m_Cursor);
_scroomer_state = BOTTOM; _scroomer_state = BOTTOM;
} else { } else {
_view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->grabber);
_scroomer_state = MOVE; _scroomer_state = MOVE;
_view->editing_context().pop_canvas_cursor ();
} }
} }

View File

@ -33,7 +33,7 @@ ARDOUR::DataType PublicEditor::pbdid_dragged_dt = ARDOUR::DataType::NIL;
PublicEditor::PublicEditor () PublicEditor::PublicEditor ()
: EditingContext (X_("Editor")) : EditingContext (X_("Editor"))
, Tabbable (_("Editor"), X_("editor")) , Tabbable (_("Editor"), X_("editor"), NULL, true, Tabbable::NoPanes)
, mouse_mode_hbox (nullptr) , mouse_mode_hbox (nullptr)
{ {
_suspend_route_redisplay_counter.store (0); _suspend_route_redisplay_counter.store (0);

View File

@ -78,7 +78,7 @@ using namespace Menu_Helpers;
#define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ())) #define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ()))
RecorderUI::RecorderUI () RecorderUI::RecorderUI ()
: Tabbable (_("Recorder"), X_("recorder")) : Tabbable (_("Recorder"), X_("recorder"), NULL, true, Tabbable::NoPanes)
, _toolbar_sep (1.0) , _toolbar_sep (1.0)
, _btn_rec_all (_("All")) , _btn_rec_all (_("All"))
, _btn_rec_none (_("None")) , _btn_rec_none (_("None"))
@ -101,11 +101,6 @@ RecorderUI::RecorderUI ()
load_bindings (); load_bindings ();
register_actions (); 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 */ /* monitoring */
_auto_input_button.set_related_action (ActionManager::get_action ("Transport", "ToggleAutoInput")); _auto_input_button.set_related_action (ActionManager::get_action ("Transport", "ToggleAutoInput"));
_auto_input_button.set_name ("transport option button"); _auto_input_button.set_name ("transport option button");

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2011-2017 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2024 Ben Loftis <ben@harrisonconsoles.com>
*
* 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 <algorithm>
#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<ARDOUR::Route> 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)
{
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2021 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2024 Ben Loftis <ben@harrisonconsoles.com>
*
* 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 <map>
#include <gtkmm/box.h>
#include <gtkmm/label.h>
#include <gtkmm/table.h>
#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<ARDOUR::Route>);
protected:
std::shared_ptr<ARDOUR::Region> _route;
Gtk::Label _header_label;
private:
void property_changed (const PBD::PropertyChange& what_changed);
PBD::ScopedConnection state_connection;
};

View File

@ -46,6 +46,8 @@
#include "slot_properties_box.h" #include "slot_properties_box.h"
#include "audio_route_properties_box.h"
#include "selection_properties_box.h" #include "selection_properties_box.h"
#include "pbd/i18n.h" #include "pbd/i18n.h"
@ -65,12 +67,10 @@ SelectionPropertiesBox::SelectionPropertiesBox ()
_time_info_box = new TimeInfoBox ("EditorTimeInfo", true); _time_info_box = new TimeInfoBox ("EditorTimeInfo", true);
pack_start(*_time_info_box, false, false, 0); pack_start(*_time_info_box, false, false, 0);
#if SELECTION_PROPERTIES_BOX_TODO
/* Region ops (mute/unmute), for multiple-Region selections */ /* Region ops (mute/unmute), for multiple-Region selections */
_mregions_prop_box = new MultiRegionPropertiesBox (); _mregions_prop_box = new MultiRegionPropertiesBox ();
pack_start(*_mregions_prop_box, false, false, 0); pack_start(*_mregions_prop_box, false, false, 0);
/* MIDI Region props, for Clips */ /* MIDI Region props, for Clips */
_midi_prop_box = new MidiRegionPropertiesBox (); _midi_prop_box = new MidiRegionPropertiesBox ();
pack_start(*_midi_prop_box, false, false, 0); pack_start(*_midi_prop_box, false, false, 0);
@ -79,7 +79,6 @@ SelectionPropertiesBox::SelectionPropertiesBox ()
_audio_prop_box = new AudioRegionPropertiesBox (); _audio_prop_box = new AudioRegionPropertiesBox ();
pack_start(*_audio_prop_box, false, false, 0); pack_start(*_audio_prop_box, false, false, 0);
/* MIDI Region ops (transpose, quantize), for only-midi selections */ /* MIDI Region ops (transpose, quantize), for only-midi selections */
_midi_ops_box = new MidiRegionOperationsBox (); _midi_ops_box = new MidiRegionOperationsBox ();
pack_start(*_midi_ops_box, false, false, 0); pack_start(*_midi_ops_box, false, false, 0);
@ -88,11 +87,62 @@ SelectionPropertiesBox::SelectionPropertiesBox ()
_audio_ops_box = new AudioRegionOperationsBox (); _audio_ops_box = new AudioRegionOperationsBox ();
pack_start(*_audio_ops_box, false, false, 0); pack_start(*_audio_ops_box, false, false, 0);
/* SLOT properties, for Trigger slot selections */ /* SLOT properties, for Trigger slot selections */
_slot_prop_box = new SlotPropertiesBox (); _slot_prop_box = new SlotPropertiesBox ();
pack_start(*_slot_prop_box, false, false, 0); 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 */ /* 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)); Editor::instance().get_selection().TracksChanged.connect (sigc::mem_fun (*this, &SelectionPropertiesBox::selection_changed));
@ -111,47 +161,6 @@ SelectionPropertiesBox::SelectionPropertiesBox ()
selection_changed(); 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 void
SelectionPropertiesBox::track_mouse_mode () SelectionPropertiesBox::track_mouse_mode ()
{ {
@ -165,7 +174,6 @@ SelectionPropertiesBox::selection_changed ()
_time_info_box->hide(); _time_info_box->hide();
#if SELECTION_PROPERTIES_BOX_TODO
_mregions_prop_box->hide(); _mregions_prop_box->hide();
_midi_ops_box->hide(); _midi_ops_box->hide();
@ -175,7 +183,8 @@ SelectionPropertiesBox::selection_changed ()
_audio_prop_box->hide(); _audio_prop_box->hide();
_slot_prop_box->hide(); _slot_prop_box->hide();
#endif
_route_prop_box->hide();
_header_label.hide(); _header_label.hide();
@ -185,6 +194,16 @@ SelectionPropertiesBox::selection_changed ()
_header_label.show(); _header_label.show();
} }
if (!selection.tracks.empty()) {
_route_prop_box->show();
TimeAxisView *tav = *(selection.tracks.begin());
RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView *>(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 #if SELECTION_PROPERTIES_BOX_TODO
/* one or more regions, show the multi-region operations box (just MUTE? kinda boring) */ /* one or more regions, show the multi-region operations box (just MUTE? kinda boring) */
if (!selection.regions.empty()) { if (!selection.regions.empty()) {
@ -215,8 +234,10 @@ SelectionPropertiesBox::selection_changed ()
if (found_audio_regions && ! found_midi_regions) { if (found_audio_regions && ! found_midi_regions) {
_audio_ops_box->show(); _audio_ops_box->show();
} }
#endif
std::shared_ptr<ARDOUR::Region> selected_region = std::shared_ptr<ARDOUR::Region>(); std::shared_ptr<ARDOUR::Region> selected_region = std::shared_ptr<ARDOUR::Region>();
RegionView *selected_regionview = NULL;
if (!selection.triggers.empty()) { if (!selection.triggers.empty()) {
TriggerSelection ts = selection.triggers; TriggerSelection ts = selection.triggers;
@ -227,21 +248,21 @@ SelectionPropertiesBox::selection_changed ()
_slot_prop_box->set_slot(ref); _slot_prop_box->set_slot(ref);
_slot_prop_box->show(); _slot_prop_box->show();
selected_region = ref.trigger()->region(); // selected_region = ref.trigger()->region();
} else if (selection.regions.size()==1) { } 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<ARDOUR::Region> r = selected_regionview->region();
//region properties //region properties
if (selected_region->data_type() == DataType::MIDI) { if (r && r->data_type() == DataType::MIDI) {
_midi_prop_box->set_region(selected_region); _midi_prop_box->set_regionview(selected_regionview);
_midi_prop_box->show(); _midi_prop_box->show();
_midi_ops_box->show(); } else if (r) {
} else { _audio_prop_box->set_regionview(selected_regionview); //retains a SessionHandler reference somewhere @robin
_audio_prop_box->set_region(selected_region);
_audio_prop_box->show(); _audio_prop_box->show();
_audio_ops_box->show();
} }
} }
#endif #endif

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2021 Paul Davis <paul@linuxaudiosystems.com> * Copyright (C) 2021 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2021 Ben Loftis <ben@harrisonconsoles.com> * Copyright (C) 2024 Ben Loftis <ben@harrisonconsoles.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -47,7 +47,9 @@ class MidiRegionPropertiesBox;
class AudioRegionOperationsBox; class AudioRegionOperationsBox;
class MidiRegionOperationsBox; class MidiRegionOperationsBox;
class SelectionPropertiesBox : public Gtk::VBox, public ARDOUR::SessionHandlePtr class RoutePropertiesBox;
class SelectionPropertiesBox : public Gtk::HBox, public ARDOUR::SessionHandlePtr
{ {
public: public:
SelectionPropertiesBox (); SelectionPropertiesBox ();
@ -74,6 +76,8 @@ private:
SlotPropertiesBox* _slot_prop_box; SlotPropertiesBox* _slot_prop_box;
RoutePropertiesBox* _route_prop_box;
void selection_changed (); void selection_changed ();
void track_mouse_mode (); void track_mouse_mode ();

View File

@ -77,8 +77,6 @@ TriggerPage::TriggerPage ()
load_bindings (); load_bindings ();
register_actions (); register_actions ();
left_attachment_button.set_sensitive(false);
/* Match TriggerStrip::_name_button height */ /* Match TriggerStrip::_name_button height */
ArdourButton* spacer = manage (new ArdourButton (ArdourButton::Text)); ArdourButton* spacer = manage (new ArdourButton (ArdourButton::Text));
spacer->set_name ("mixer strip button"); spacer->set_name ("mixer strip button");

View File

@ -45,6 +45,7 @@ gtk2_ardour_sources = [
'audio_region_view.cc', 'audio_region_view.cc',
'audio_region_operations_box.cc', 'audio_region_operations_box.cc',
'audio_region_properties_box.cc', 'audio_region_properties_box.cc',
'audio_route_properties_box.cc',
'audio_trigger_properties_box.cc', 'audio_trigger_properties_box.cc',
'audio_streamview.cc', 'audio_streamview.cc',
'audio_time_axis.cc', 'audio_time_axis.cc',
@ -268,6 +269,7 @@ gtk2_ardour_sources = [
'route_group_menu.cc', 'route_group_menu.cc',
'route_list_base.cc', 'route_list_base.cc',
'route_params_ui.cc', 'route_params_ui.cc',
'route_properties_box.cc',
'route_processor_selection.cc', 'route_processor_selection.cc',
'route_time_axis.cc', 'route_time_axis.cc',
'route_ui.cc', 'route_ui.cc',

View File

@ -37,10 +37,11 @@ using namespace Gtk;
using namespace Gtkmm2ext; using namespace Gtkmm2ext;
using namespace ArdourWidgets; 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) : WindowProxy (visible_name, nontranslatable_name)
, _parent_notebook (0) , _parent_notebook (0)
, tab_requested_by_state (tabbed_by_default) , tab_requested_by_state (tabbed_by_default)
, _panelayout (pl)
{ {
if (w) { if (w) {
_contents = w; _contents = w;
@ -78,6 +79,10 @@ Tabbable::default_layout ()
right_attachment_button.set_tweaks (ArdourButton::ExpandtoSquare); right_attachment_button.set_tweaks (ArdourButton::ExpandtoSquare);
bottom_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_border_width(3);
content_attachment_hbox.set_spacing(3); content_attachment_hbox.set_spacing(3);
content_attachment_hbox.pack_end (right_attachment_button, false, false); 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); _content_vbox.pack_start (*toolbar_frame, false, false);
#endif #endif
_content_vbox.pack_start (content_hbox, 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_att_left, false, false);
content_hbox.pack_start (content_midlevel_vbox, true, true); 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_right_pane, true, true);
content_midlevel_vbox.pack_start (content_att_bottom, false, false); content_midlevel_vbox.pack_start (content_att_bottom, false, false);
content_right_pane.add (content_inner_vbox); content_right_pane.add (content_inner_vbox);
content_right_pane.add (content_right_vbox);
//TODO: menu switcher here? if (_panelayout & PaneRight) {
content_right_pane.add (content_right_vbox);
content_right_vbox.pack_start (content_att_right, true, true); 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_toolbar, false, false);
content_inner_vbox.pack_start (content_innermost_hbox, true, true); content_inner_vbox.pack_start (content_innermost_hbox, true, true);
if (_panelayout & PaneRight) {
content_right_pane.set_child_minsize (content_att_right, 160); /* rough guess at width of notebook tabs */ 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_check_divider_position (true);
content_right_pane.set_divider (0, 0.85); 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(); _content_vbox.show_all();
} }
@ -412,7 +433,8 @@ Tabbable::get_state() const
node.set_property (X_("tabbed"), tabbed()); 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; return node;
} }
@ -436,10 +458,14 @@ Tabbable::set_state (const XMLNode& node, int version)
if (window_node) { if (window_node) {
window_node->get_property (X_("tabbed"), tab_requested_by_state); window_node->get_property (X_("tabbed"), tab_requested_by_state);
float fract; 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)); fract = std::max (.05f, std::min (.95f, fract));
content_right_pane.set_divider (0, 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);
}
} }

View File

@ -48,7 +48,17 @@ namespace ArdourWidgets {
class LIBWIDGETS_API Tabbable : public Gtkmm2ext::WindowProxy class LIBWIDGETS_API Tabbable : public Gtkmm2ext::WindowProxy
{ {
public: 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 (); ~Tabbable ();
void add_to_notebook (Gtk::Notebook& notebook); void add_to_notebook (Gtk::Notebook& notebook);
@ -101,8 +111,53 @@ protected:
bool delete_event_handler (GdkEventAny *ev); bool delete_event_handler (GdkEventAny *ev);
/* This is the heirarchy of a Tabbable's widget packing. /* 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 */ /* clang-format off */
@ -113,6 +168,7 @@ protected:
Gtk::EventBox content_attachments; /* a placeholder the (strip, list, props) visibility buttons for this tab */ Gtk::EventBox content_attachments; /* a placeholder the (strip, list, props) visibility buttons for this tab */
Gtk::HBox content_attachment_hbox; Gtk::HBox content_attachment_hbox;
EventBoxExt content_tabbables; /* a placeholder for the tabbable switching buttons (used by ArdourUI) */ EventBoxExt content_tabbables; /* a placeholder for the tabbable switching buttons (used by ArdourUI) */
HPane content_left_pane;
Gtk::HBox content_hbox; Gtk::HBox content_hbox;
EventBoxExt content_att_left; /* a placeholder for the mixer strip, if you want one */ EventBoxExt content_att_left; /* a placeholder for the mixer strip, if you want one */
Gtk::VBox content_midlevel_vbox; Gtk::VBox content_midlevel_vbox;
@ -144,6 +200,7 @@ private:
Gtk::Notebook _own_notebook; Gtk::Notebook _own_notebook;
Gtk::Notebook* _parent_notebook; Gtk::Notebook* _parent_notebook;
bool tab_requested_by_state; bool tab_requested_by_state;
PaneLayout _panelayout;
}; };

View File

@ -749,10 +749,6 @@ int main() { return 0; }''',
compiler_flags.append ('-DMIXBUS') compiler_flags.append ('-DMIXBUS')
conf.define('MIXBUS', 1) 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": if Options.options.program_name.lower() == "livetrax":
compiler_flags.append ('-DLIVETRAX') compiler_flags.append ('-DLIVETRAX')
conf.define ('LIVETRAX', 1) conf.define ('LIVETRAX', 1)