Compare commits

...

117 Commits

Author SHA1 Message Date
Paul Davis 70ea5a6a68 fix up error during manual rebase correction 2024-04-24 21:42:13 -06:00
Paul Davis 4464a540e3 mock logo 2024-04-24 21:24:24 -06:00
Paul Davis 7c132795b7 use UTF for lock icon 2024-04-24 21:24:24 -06:00
Paul Davis cbcb5fea2c split EngineDialog into a widget and a dialog 2024-04-24 21:24:24 -06:00
Paul Davis 50a0786fba sometimes concision with variable naming is of no help 2024-04-24 21:24:24 -06:00
Paul Davis 4736eab0b6 no namespace needed 2024-04-24 21:24:24 -06:00
Paul Davis c7259f0167 profile initialization per-program needs to happen earlier, in ARDOUR::init() 2024-04-24 21:24:24 -06:00
Paul Davis 8eca454da4 first steps towards livetrax prefs editor 2024-04-24 21:24:24 -06:00
Paul Davis 15218efc1d copied skeleton for livetrax rc option editor 2024-04-24 21:24:23 -06:00
Paul Davis fdd67f2a13 initial preparations for a distinct livetrax rc option editor 2024-04-24 21:24:23 -06:00
Paul Davis 247dac49c9 use program name to define Livetrax 2024-04-24 21:24:23 -06:00
Paul Davis c287f76b97 some file copies/renaming for ardour->livetrax 2024-04-24 21:24:23 -06:00
Paul Davis 5004ebf2f9 remove debug output 2024-04-24 21:24:23 -06:00
Paul Davis a307bf1ec9 display MIDI scene markers
Note: this commit is valid for Ardour as well as LiveTrax
2024-04-24 21:24:23 -06:00
Paul Davis d9f1105589 some libardour support for MIDI scene support 2024-04-24 21:24:23 -06:00
Paul Davis f372a20a32 basics of the livetrax TC widget 2024-04-24 21:24:23 -06:00
Paul Davis fc2d5690f2 some basic but incomplete logic for track autoconnect in livetrax 2024-04-24 21:24:23 -06:00
Paul Davis 21bfa8e580 fix reordering of newly added tracks in livetrax scenario 2024-04-24 21:24:23 -06:00
Paul Davis 6d4197d764 add and use simplified livetrax add tracks dialog 2024-04-24 21:24:23 -06:00
Paul Davis e1eb672198 add a channel mask to AudioBackend
This can be used to identify channels not to be used during
auto-connect, particularly for livetrax
2024-04-24 21:24:23 -06:00
Paul Davis c389382a53 some tweaks to get initial state of gain controls for virtual soundccheck correct 2024-04-24 21:24:23 -06:00
Paul Davis 88a142962a for livetrax, use a knob for panning
While we're here, cleanup PannerUI initialization and some whitespace/brace issues.

Note: the knob does not yet actually control panning at all yet (not clear why)
2024-04-24 21:24:23 -06:00
Paul Davis 690091946b better GUI handling of virtual soundcheck 2024-04-24 21:24:23 -06:00
Paul Davis 3a1bbbc6bc better libardour infrastructure for virtual soundcheck 2024-04-24 21:24:23 -06:00
Paul Davis 751be84be5 GUI steps for virtual soundcheck 2024-04-24 21:24:23 -06:00
Paul Davis 6f4383f346 libardour infrastructure for virtual soundcheck 2024-04-24 21:24:23 -06:00
Paul Davis fbc91164b5 fix restore of master send from XML 2024-04-24 21:24:23 -06:00
Paul Davis 64323b8da5 fix missing conditions in Route:is_internal_processor() to cover master send 2024-04-24 21:24:23 -06:00
Paul Davis cfc719753b most of the mechanism for livetrax signal routing via as master send 2024-04-24 21:24:23 -06:00
Paul Davis 4a1a0e8495 MasterSend IS-A send for Delivery purposes 2024-04-24 21:24:23 -06:00
Paul Davis 4e234e4040 don't set monitor_out for livetrax 2024-04-24 21:24:23 -06:00
Paul Davis c7167ab9a7 for livetrax, Route::panner{._panner_shell}() should not use the Route's own 2024-04-24 21:24:23 -06:00
Paul Davis 0611f931ce NO-OP: move Route::remove_monitor_send() to be near ::enable_monitor_send() 2024-04-24 21:24:23 -06:00
Paul Davis d08d60e4d9 when positioning master send in processor list, use cheaper conditional than is_track() 2024-04-24 21:24:23 -06:00
Paul Davis 041f26e9ea don't bother asking for a monitor section if livetrax 2024-04-24 21:24:23 -06:00
Paul Davis a7d81bc3c0 master send uses _role == MasterSend, not _role == Aux 2024-04-24 21:24:23 -06:00
Paul Davis 7c7ab14746 MasterSend is a type of (aux) send 2024-04-24 21:24:23 -06:00
Paul Davis 020d962742 make send return a sensible name if it is a MasterSend 2024-04-24 21:24:23 -06:00
Paul Davis 0de1aebdd3 auto-fication of a loop in InternalReturn 2024-04-24 21:24:23 -06:00
Paul Davis ede8557f82 internal sends in livetrax are never linked to the Route panner
Note: this could discriminate based on _role == MasterSend, but
livetrax doesn't allow any other type of internal send anyway.
2024-04-24 21:24:23 -06:00
Paul Davis 9f30bdfc33 NO-OP: add space before bracket 2024-04-24 21:24:23 -06:00
Paul Davis 72109adeba NO-OP: linebeeak removed 2024-04-24 21:24:23 -06:00
Paul Davis 90a1c45ff6 no monitor section for livetrax plus minor code rearrangement 2024-04-24 21:24:23 -06:00
Paul Davis cb97ce18fe more crash avoidance in sfdb UI if there's no auditioner 2024-04-24 21:24:23 -06:00
Paul Davis 1c8cca1939 sfdb UI should not crash if there's no auditioner 2024-04-24 21:24:23 -06:00
Paul Davis d09b3fc326 NO-OP: fix space near braces/brackets 2024-04-24 21:24:23 -06:00
Paul Davis 4914588188 sfdb_ui should be smart if there's no auditioner 2024-04-24 21:24:23 -06:00
Paul Davis b6a6dad729 port group display should not crash if there's no auditioner 2024-04-24 21:24:23 -06:00
Paul Davis a60d7acefe panner UI in mixer should leave choice of panner shell & panner to Route 2024-04-24 21:24:23 -06:00
Paul Davis 75ffe7c536 no plugins in MixerUI for livetrax 2024-04-24 21:24:23 -06:00
Paul Davis 6efbced63a no crash if instrument selector has no _instrument_list 2024-04-24 21:24:23 -06:00
Paul Davis c88dc10bd2 do not save or restore tabbable state for livetrax 2024-04-24 21:24:23 -06:00
Paul Davis f5c274b443 add some enums and rc vars related to master send/return design 2024-04-24 21:24:23 -06:00
Paul Davis 52c895f397 no context menus for solo, mute, rec-enable with livetrax 2024-04-24 21:24:23 -06:00
Paul Davis 3181e6d375 remove debug output 2024-04-24 21:24:23 -06:00
Paul Davis 787eb26683 functional file format dropdown UI 2024-04-24 21:24:23 -06:00
Paul Davis 967b567c52 change design for doing "both" file format changes at once 2024-04-24 21:24:23 -06:00
Paul Davis 351ba91330 library infrastructure for changing both aspects of audio file format at once 2024-04-24 21:24:23 -06:00
Paul Davis 614c461f99 no region gain line for livetrax 2024-04-24 21:24:18 -06:00
Paul Davis 8bced2fc0d no plugin-related GUI elements (and no editor notebook) for livetrax 2024-04-24 21:21:28 -06:00
Paul Davis 70162d5bf0 no fleshed out plugin manager for livetrax 2024-04-24 21:21:28 -06:00
Paul Davis d971e2858f no auditioner for livetrax 2024-04-24 21:21:28 -06:00
Paul Davis e1e780e19d NO-OP indentation fix 2024-04-24 21:21:28 -06:00
Paul Davis 63c5836899 remove fade handles for livetrax 2024-04-24 21:21:28 -06:00
Paul Davis 5034c0ecea define actions to control livetrax section visibility 2024-04-24 21:21:28 -06:00
Paul Davis 0a4edf32d6 attach bindings to boxes in livetrax view, and steal focus appropriately 2024-04-24 21:21:28 -06:00
Paul Davis a484a63929 initial work on livetrax all-mono, direct outs and send-to-(master/monitor?) GUI edition 2024-04-24 21:21:28 -06:00
Paul Davis 21fc887eea initial work on livetrax all-mono, direct outs and send-to-(master/monitor?) 2024-04-24 21:21:28 -06:00
Paul Davis c7bbd0bc41 continuing tweaks for livetrax 2024-04-24 21:21:28 -06:00
Paul Davis 4dea5443e5 working input meters, among other improvements for livetrax 2024-04-24 21:21:28 -06:00
Paul Davis 0a7bda3d5b don't compute scope info for livetrax (never displayed) 2024-04-24 21:21:28 -06:00
Paul Davis 27c378451e work on livetrax continues 2024-04-24 21:21:28 -06:00
Paul Davis 92c1a65968 remove over-wide meter hack 2024-04-24 21:21:28 -06:00
Paul Davis d11f8302f4 more work on livetrax layout 2024-04-24 21:21:28 -06:00
Paul Davis c5dad17975 NOOP: reformat and reflow 2024-04-24 21:21:28 -06:00
Paul Davis 513645f1a3 initial work on livetrax 2024-04-24 21:21:28 -06:00
Paul Davis 93dda8ead7 add a new Profile flag for livetrax 2024-04-24 21:21:28 -06:00
Paul Davis cdfdeccfe7 allow true boxy buttons for ArdourButtons
Also add a default tweaks static member to force all buttons to a given tweak state
2024-04-24 21:21:28 -06:00
Paul Davis b91a0009cf add unrounded rectangle methods to Gtkmm2ext for use in truly boxy buttons 2024-04-24 21:21:28 -06:00
Robin Gareus 4665cdcb6b
Add icons for livetrax (lock, mixer, meter) 2024-04-25 02:21:10 +02:00
Robin Gareus b00ddcfe1c
Fix -Waddress (and expand tabs)
The expansion of the macro resulted in:
"the comparison will always evaluate as 'true' for the address of .."
2024-04-24 18:06:27 +02:00
agfline 8ea3a14cd6
Update AAF import UI 2024-04-24 17:13:00 +02:00
agfline 41587d3c06
Update libaaf to v1.0-11-gb04c547 2024-04-24 17:13:00 +02:00
Robin Gareus 895fe2f753
Fix Windows builds 2/2 (amend b2d4280e0) 2024-04-24 06:08:26 +02:00
Robin Gareus df12126909
Fix Windows builds 1/2 (amend bcbb4393fc) 2024-04-24 06:02:13 +02:00
Robin Gareus 38adfdf79e
Add custom color for region effect automation 2024-04-23 21:56:26 +02:00
Robin Gareus b2d4280e0f
Add support for Region Fx Automation 2024-04-23 21:56:22 +02:00
Robin Gareus e5506d281a
GUI support for Region Fx (in Region Properties) 2024-04-23 21:56:18 +02:00
Robin Gareus 457238ec2e
Per [Audio] Region Fx
* apply effects during region-read in non-rt context
* Add multi-channel audioregion read cache
  to process stereo effects
2024-04-23 21:56:15 +02:00
Robin Gareus 1996945353
Add custom RegionFxPlugin
Less than a PluginInsert but more than an IOPlug.
2024-04-23 21:56:10 +02:00
Robin Gareus ad9a3ae103
Fix region-gain envelope auto-enable when dragging
When using freehand drawing of automation, the line itself
is not notified (no ::start_drag(), ::end_drag() calls).

This adds a end_draw() call which allows the AutomatioLine
to perform additional actions.
2024-04-23 21:56:05 +02:00
Robin Gareus b04fa05f20
NO-OP: sort debug bits 2024-04-23 21:55:59 +02:00
Robin Gareus 1cd9a9b57d
Only show automation mode button for PluginInsert ctrls
Previously the generic UI of I/O plugins (and upcoming Region
Fx showed an insensitive Automation mode (manual, play, touch etc)
dropdown for all controls.

That accomplished nothing but wasted space.
2024-04-23 21:55:54 +02:00
Robin Gareus 59b2369736
Remove unused gain-buffer for master-read (NOOP) 2024-04-23 21:52:02 +02:00
Robin Gareus f3823e8d7c
Fix redeclaration of DnDVbox 2024-04-23 21:51:55 +02:00
Robin Gareus 2bb4a9ac4e
Add API to configure plugins for non-realtime offline processing 2024-04-23 21:51:50 +02:00
Robin Gareus 598ff1cb9a
Separate PluginWindowProxy into public class 2024-04-23 21:51:31 +02:00
Robin Gareus f858316503
Plugins: Ignore offset for scratch/silent buffers
This allows to process buffers at an offset, as long
as the number of processed samples is less or equal to the
current buffersize.
2024-04-23 21:51:19 +02:00
Robin Gareus 2ca5f28910
NO-OP: whitespace 2024-04-23 21:51:07 +02:00
Robin Gareus 2f6a428f05
Overhaul and optimize thread-buffer allocation
Every route calls Session::ensure_buffers when configuring
processors. Previously that unconditionally invoked the
BufferManager, even if no change was required.

This also fixes a potential issue when bouncing tracks.
::write_one_track() increases the buffersize to 8k, but only for
the ChanCount required to bounce. This was never properly reset.

Furthermore this is in preparation for RegionFX which may
need to increase the ChanCount of Threadbuffers.
2024-04-23 21:51:04 +02:00
Robin Gareus 6dfcb60763
Automatable find_next/prev_ac_event requires no context
This allows to use the functions from a class that
does not inherit from Automatable but has AutomationControls
with an AutomationList.
2024-04-23 21:50:58 +02:00
Robin Gareus f111f200c1
Fix signal analysis when buffer-size changes
PI::signal-analysis buffers were not updated when a user
changes the buffersize.

This also remove a single use Session API.
2024-04-23 21:49:48 +02:00
Robin Gareus df8106bd85
PluginInsert match I/O: skip div by zero 2024-04-23 21:49:41 +02:00
Robin Gareus 92183430b9
IOPlug: various small fixes (port-names, VST compat, etc) 2024-04-23 21:49:28 +02:00
Robin Gareus 5216a6d987
Refactor and consolidate setting and copying plugin state 2024-04-21 16:32:47 +02:00
Robin Gareus f5b53a6d14
Consolidate PluginInsert Match, move to parent class 2024-04-21 16:32:47 +02:00
Robin Gareus 2da3141706
Consolidate plugin_factory, move to parent class 2024-04-21 16:32:47 +02:00
Robin Gareus d2bdf440c8
Consolidate PluginControl Code
This code was (for the most part) duplicated, and with
preparation for Region FX, a third copy motivated this
consolidation.
2024-04-21 16:32:47 +02:00
Robin Gareus 6191f89d55
Properly update Solo state when setting multiple ctrls 2024-04-21 16:32:13 +02:00
Robin Gareus bcbb4393fc
Allow Lua [session] script to directly set controllables 2024-04-21 16:32:10 +02:00
Paul Davis 894e6d27a4 NOOP: whitespace cleanup 2024-04-19 10:43:10 -06:00
Paul Davis c96e12ba58 expand null/destroyed tests for gdk objects in NSView methods 2024-04-19 10:42:59 -06:00
Robin Gareus e64a071e39
(YDK) amend previous commit, call parent method 2024-04-19 16:46:49 +02:00
Robin Gareus 08e394f681
(YDK) possible fix for Catalina event loop crashes
```
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libydk.dylib 0x0000000110d8942d -[GdkQuartzView setNeedsDisplay:] + 93
1 com.apple.AppKit 0x00007fff34af6848 -[NSView(NSViewContentStyle) _recursivelyInvalidateCachedContentStyle] + 120
2 com.apple.AppKit 0x00007fff34af60fb -[NSView _setSuperview:] + 521
3 com.apple.AppKit 0x00007fff34b200a6 -[NSView removeFromSuperview] + 140
4 com.apple.AppKit 0x00007fff34ba882f -[NSView removeFromSuperviewWithoutNeedingDisplay] + 36
5 com.apple.AppKit 0x00007fff34b27168 -[NSView _finalize] + 977
6 com.apple.AppKit 0x00007fff34b26c0c -[NSView dealloc] + 121
7 com.apple.AppKit 0x00007fff34e30db4 -[NSFrameView dealloc] + 119
8 com.apple.AppKit 0x00007fff34e30d36 -[NSTitledFrame dealloc] + 62
9 com.apple.AppKit 0x00007fff34e30ce9 -[NSThemeFrame dealloc] + 603
10 com.apple.Foundation 0x00007fff39ed5992 NSKVODeallocate + 172
11 com.apple.AppKit 0x00007fff34d85884 -[NSWindow dealloc] + 1083
12 com.apple.AppKit 0x00007fff34d85442 -[NSWindow _dealloc] + 76
13 libobjc.A.dylib 0x00007fff6f6f3054 AutoreleasePoolPage::releaseUntil(objc_object**) + 134
14 libobjc.A.dylib 0x00007fff6f6d7dba objc_autoreleasePoolPop + 175
15 com.apple.CoreFoundation 0x00007fff377c9cb5 _CFAutoreleasePoolPop + 22
16 com.apple.Foundation 0x00007fff39e7d04e -[NSAutoreleasePool drain] + 126
17 libydk.dylib 0x0000000110d8ef29 gdk_event_prepare + 73
18 libglib-2.0.0.dylib 0x00000001110ded45 g_main_context_prepare + 533
19 libglib-2.0.0.dylib 0x00000001110df800 g_main_context_iterate + 128
20 libglib-2.0.0.dylib 0x00000001110dfcc2 g_main_loop_run + 210
21 libytk.dylib 0x0000000110a4f11f gtk_main + 191
22 libgtkmm2ext.dylib 0x00000001104cef1e Gtkmm2ext::UI::run(Receiver&) + 318
23 com.harrisonconsoles.Mixbus10 0x000000010dc6fb9c main + 2652
```
2024-04-19 15:38:12 +02:00
Robin Gareus 136b7f42d5
Skip tags for plugins that are not installed
This prevents empty sub-menus in the "By Tag" Plugin menu.
2024-04-18 17:07:12 +02:00
Robin Gareus 4b6e372ce7
Fix deleting the same point multiple times (#9689)
When iterating over automation tracks, previously it was
possible that the same point was added multiple times to
the selection.
2024-04-15 00:39:20 +02:00
Edgar Aichinger c9c419213f
update german translation 2024-04-14 00:42:09 +02:00
194 changed files with 19029 additions and 8807 deletions

View File

@ -627,7 +627,11 @@ AddRouteDialog::maybe_update_name_template_entry ()
switch (type_wanted()) {
case AudioTrack:
name_template_entry.set_text (_("Audio"));
if (Profile->get_livetrax()) {
name_template_entry.set_text (_("Track"));
} else {
name_template_entry.set_text (_("Audio"));
}
break;
case MidiTrack:
/* set name of instrument or _("MIDI") */

View File

@ -553,6 +553,7 @@
<menuitem action="toggle-arrangement-ruler"/>
<menuitem action="toggle-marker-ruler"/>
<menuitem action="toggle-cue-marker-ruler"/>
<menuitem action="toggle-scene-marker-ruler"/>
<separator/>
<menuitem action="toggle-video-ruler"/>
</menu>
@ -805,6 +806,7 @@
<menuitem action="toggle-cd-marker-ruler"/>
<menuitem action="toggle-marker-ruler"/>
<menuitem action="toggle-cue-marker-ruler"/>
<menuitem action="toggle-scene-marker-ruler"/>
<separator/>
<menuitem action="toggle-video-ruler"/>
</popup>

View File

@ -191,3 +191,9 @@ ArdourDialog::set_ui_sensitive (bool yn)
{
_sensitive = yn;
}
void
ArdourDialog::add_widget_action (Gtk::Widget& w)
{
get_action_area()->add (w);
}

View File

@ -51,10 +51,13 @@ public:
void on_show ();
virtual void on_response (int);
void set_ui_sensitive (bool);
bool ui_sensitive () const { return _sensitive; }
void disallow_idle ();
protected:
void pop_splash ();
void add_widget_action (Gtk::Widget&);
protected:
void close_self ();
bool _sensitive;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2012-2017 Robin Gareus <robin@gareus.org>
* Copyright (C) 2012-2018 Paul Davis <paul@linuxaudiosystems.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.
*/
#ifndef __gtk_ardour_rc_option_editor_h__
#define __gtk_ardour_rc_option_editor_h__
#include "widgets/tabbable.h"
#include "option_editor.h"
#include "visibility_group.h"
#include "transport_masters_dialog.h"
/** @file rc_option_editor.h
* @brief Editing of options which are obtained from and written back to one of the .rc files.
*
* This is subclassed from OptionEditor. Simple options (e.g. boolean and simple choices)
* are expressed using subclasses of Option. More complex UI elements are represented
* using individual classes subclassed from OptionEditorBox.
*/
/** Editor for options which are obtained from and written back to one of the .rc files. */
class RCOptionEditor : public OptionEditorContainer, public ARDOUR::SessionHandlePtr, public ArdourWidgets::Tabbable
{
public:
RCOptionEditor ();
void set_session (ARDOUR::Session*);
Gtk::Window* use_own_window (bool and_fill_it);
XMLNode& get_state () const;
bool on_key_release_event (GdkEventKey*);
private:
void parameter_changed (std::string const &);
void ltc_generator_volume_changed ();
ARDOUR::RCConfiguration* _rc_config;
BoolOption* _solo_control_is_listen_control;
ComboOption<ARDOUR::ListenPosition>* _listen_position;
VisibilityGroup _mixer_strip_visibility;
BoolOption* _sync_framerate;
HSliderOption* _ltc_volume_slider;
Gtk::Adjustment* _ltc_volume_adjustment;
BoolOption* _ltc_send_continuously;
BoolOption* _plugin_prefer_inline;
BoolOption* _cairo_image_surface;
TransportMastersWidget _transport_masters_widget;
PBD::ScopedConnection parameter_change_connection;
PBD::ScopedConnection engine_started_connection;
void show_audio_setup ();
void show_transport_masters ();
void reset_clip_library_dir ();
EntryOption* mrl_option;
EntryOption* mru_option;
std::string get_default_lower_midi_note ();
bool set_default_lower_midi_note (std::string);
std::string get_default_upper_midi_note ();
bool set_default_upper_midi_note (std::string);
/* plugin actions */
void plugin_scan_refresh ();
void plugin_reset_stats ();
void clear_vst2_cache ();
void clear_vst2_blacklist ();
void clear_vst3_cache ();
void clear_vst3_blacklist ();
void clear_au_cache ();
void clear_au_blacklist ();
void edit_vst_path (std::string const&, std::string const&, sigc::slot<std::string>, sigc::slot<bool, std::string>);
};
#endif /* __gtk_ardour_rc_option_editor_h__ */

View File

@ -151,6 +151,7 @@
#include "keyboard.h"
#include "keyeditor.h"
#include "library_download_dialog.h"
#include "livetrax_add_track_dialog.h"
#include "location_ui.h"
#include "lua_script_manager.h"
#include "luawindow.h"
@ -339,6 +340,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
, plugin_dsp_load_window (X_("plugin-dsp-load"), _("Plugin DSP Load"))
, dsp_statistics_window (X_("dsp-statistics"), _("Performance Meters"))
, transport_masters_window (X_("transport-masters"), _("Transport Masters"))
, livetrax_track_dialog (nullptr)
, session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this))
, add_video_dialog (X_("add-video"), _("Add Video"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this))
, bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this))
@ -1254,13 +1256,22 @@ ARDOUR_UI::set_fps_timeout_connection ()
void
ARDOUR_UI::update_sample_rate ()
{
std::string label = string_compose (X_("<span weight=\"ultralight\">%1</span>:"), _("Audio"));
std::string label;
if (!Profile->get_livetrax()) {
label = string_compose (X_("<span weight=\"ultralight\">%1</span>:"), _("Audio"));
}
ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_sample_rate, ignored)
if (!AudioEngine::instance()->running()) {
sample_rate_label.set_markup (label + _("none"));
if (Profile->get_livetrax()) {
livetrax_sr_button->set_text (_("Stopped"), true);
} else {
const std::string str (label + _("none"));
sample_rate_label.set_markup (str);
}
} else {
@ -1269,14 +1280,23 @@ ARDOUR_UI::update_sample_rate ()
if (rate == 0) {
/* no sample rate available */
sample_rate_label.set_markup (label + _("none"));
if (Profile->get_livetrax()) {
livetrax_sr_button->set_text (_("Unknown"), true);
} else {
sample_rate_label.set_markup (label + _("none"));
}
} else {
char buf[64];
snprintf (buf, sizeof (buf), "%4.1f", (AudioEngine::instance()->usecs_per_cycle() / 1000.0f));
const char* const bg = (_session && _session->nominal_sample_rate () != rate) ? " background=\"red\" foreground=\"white\"" : "";
sample_rate_label.set_markup (string_compose ("%1 <span%2>%3</span> %4 %5", label, bg, ARDOUR_UI_UTILS::rate_as_string (rate), buf, _("ms")));
const std::string str (string_compose ("%1 <span%2>%3</span> %4 %5", label, bg, ARDOUR_UI_UTILS::rate_as_string (rate), buf, _("ms")));
sample_rate_label.set_markup (str);
if (Profile->get_livetrax()) {
livetrax_sr_button->set_text (str, true);
}
}
}
@ -1341,6 +1361,42 @@ ARDOUR_UI::update_format ()
}
format_label.set_markup (s.str ());
if (Profile->get_livetrax()) {
s.str ("");
s.clear ();
/* LiveTrax only allows a very limited set of options */
/* This looks like we could just unconditionally add "24bit" to
* the string, but this logic allows us to potentially detect
* logic glitches where somehow we end up with a different
* format.
*/
switch (_session->config.get_native_file_data_format ()) {
case FormatInt24:
s << _("24 bit");
break;
default:
break;
}
s << ' ';
switch (_session->config.get_native_file_header_format ()) {
case RF64_WAV:
s << _("WAV/RF64");
break;
case FLAC:
s << _("FLAC");
default:
break;
}
livetrax_ff_dropdown->set_active (s.str());
}
}
void
@ -2809,6 +2865,16 @@ ARDOUR_UI::add_route ()
return;
}
if (Profile->get_livetrax()) {
if (!livetrax_track_dialog) {
livetrax_track_dialog = new LiveTraxAddTrackDialog;
livetrax_track_dialog->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::add_route_dialog_response));
}
livetrax_track_dialog->set_position (WIN_POS_MOUSE);
livetrax_track_dialog->present ();
return;
}
if (!add_route_dialog.get (false)) {
add_route_dialog->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::add_route_dialog_response));
}
@ -2830,6 +2896,15 @@ ARDOUR_UI::add_route_dialog_response (int r)
return;
}
if (Profile->get_livetrax()) {
if (r == RESPONSE_OK) {
int nchan = livetrax_track_dialog->stereo() ? 2 : 1;
session_add_audio_route (true, nchan, nchan, ARDOUR::Normal, nullptr, livetrax_track_dialog->num_tracks(), string(), false, PresentationInfo::max_order, false);
}
livetrax_track_dialog->hide ();
return;
}
if (!AudioEngine::instance()->running ()) {
switch (r) {
case AddRouteDialog::Add:
@ -2916,7 +2991,7 @@ ARDOUR_UI::add_route_dialog_response (int r)
}
}
if (oac & AutoConnectMaster) {
if (!Profile->get_livetrax() && (oac & AutoConnectMaster)) {
output_chan.set (DataType::AUDIO, (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan.n_audio()));
output_chan.set (DataType::MIDI, 0);
} else {
@ -3197,3 +3272,13 @@ ARDOUR_UI::stop_cues (int col, bool immediately)
_basic_ui->trigger_stop_col (col, immediately);
}
void
ARDOUR_UI::open_media_folder ()
{
if (!_session) {
return;
}
PBD::open_folder (_session->session_directory().sound_path());
}

View File

@ -132,7 +132,7 @@ class AddVideoDialog;
class BigClockWindow;
class BigTransportWindow;
class BundleManager;
class EngineControl;
class EngineControlDialog;
class ExportVideoDialog;
class KeyEditor;
class LocationUIWindow;
@ -176,6 +176,8 @@ class NSM_Client;
class LevelMeterHBox;
class GUIObjectState;
class BasicUI;
class LiveTraxMeters;
class LiveTraxAddTrackDialog;
namespace ARDOUR {
class ControlProtocolInfo;
@ -220,6 +222,7 @@ public:
void launch_howto_report ();
void show_about ();
void hide_about ();
void open_media_folder ();
void load_from_application_api (const std::string& path);
void finish();
@ -403,6 +406,14 @@ public:
void gui_idle_handler ();
enum LiveTraxVisibility {
LiveTraxEditorVisible = 0x1,
LiveTraxMixerVisible = 0x2,
LiveTraxMeterVisible = 0x4,
};
void livetrax_toggle_visibility (LiveTraxVisibility);
protected:
friend class PublicEditor;
@ -460,6 +471,7 @@ private:
int setup_windows ();
void apply_window_settings (bool);
void connect_transport_elements ();
void setup_transport ();
void setup_clock ();
@ -486,6 +498,7 @@ private:
void update_autosave();
sigc::connection _autosave_connection;
void virtual_soundcheck_changed (bool);
void session_dirty_changed ();
void update_title ();
@ -620,6 +633,29 @@ private:
void primary_clock_value_changed ();
void secondary_clock_value_changed ();
/* LiveTrax */
Gtk::HBox livetrax_top_bar;
Gtk::HBox livetrax_transport_bar;
Gtk::HBox livetrax_meter_bar;
Gtk::HBox livetrax_editor_bar;
Gtk::HBox livetrax_mixer_bar;
TimeInfoBox* livetrax_time_info_box;
ArdourWidgets::ArdourButton* livetrax_multi_out_button;
ArdourWidgets::ArdourButton* livetrax_stereo_out_button;
ArdourWidgets::ArdourButton* livetrax_meter_view_button;
ArdourWidgets::ArdourButton* livetrax_editor_view_button;
ArdourWidgets::ArdourButton* livetrax_mixer_view_button;
ArdourWidgets::ArdourButton* livetrax_lock_button;
ArdourWidgets::ArdourButton* livetrax_view_in_folder_button;
ArdourWidgets::ArdourDropdown* livetrax_ff_dropdown;
ArdourWidgets::ArdourButton* livetrax_sr_button;
Gtk::HScrollbar* livetrax_edit_hscrollbar;
Gtk::VScrollbar* livetrax_edit_vscrollbar;
Gtk::HScrollbar* livetrax_mix_hscrollbar;
LiveTraxMeters* livetrax_meters;
int livetrax_setup_windows ();
/* menu bar and associated stuff */
Gtk::MenuBar* menu_bar;
@ -749,7 +785,7 @@ private:
WM::Proxy<About> about;
WM::Proxy<LocationUIWindow> location_ui;
WM::Proxy<RouteParams_UI> route_params;
WM::Proxy<EngineControl> audio_midi_setup;
WM::Proxy<EngineControlDialog> audio_midi_setup;
WM::Proxy<ExportVideoDialog> export_video_dialog;
WM::Proxy<LuaScriptManager> lua_script_window;
WM::Proxy<IdleOMeter> idleometer;
@ -759,6 +795,8 @@ private:
WM::Proxy<DspStatisticsWindow> dsp_statistics_window;
WM::Proxy<TransportMastersWindow> transport_masters_window;
LiveTraxAddTrackDialog* livetrax_track_dialog;
/* Windows/Dialogs that require a creator method */
WM::ProxyWithConstructor<SessionOptionEditor> session_option_editor;
@ -846,6 +884,8 @@ private:
void toggle_send_mmc ();
void toggle_send_mtc ();
void toggle_send_midi_clock ();
void disable_virtual_soundcheck ();
void enable_virtual_soundcheck ();
void toggle_use_osc ();
@ -954,6 +994,11 @@ private:
bool nsm_first_session_opened;
PBD::ScopedConnectionList clock_state_connection;
LiveTraxVisibility _livetrax_visibility;
void livetrax_visibility_change ();
void livetrax_set_file_format (ARDOUR::LiveTraxFileFormat const &);
};
#endif /* __ardour_gui_h__ */

View File

@ -317,7 +317,7 @@ ARDOUR_UI::update_clock_visibility ()
}
void
ARDOUR_UI::setup_transport ()
ARDOUR_UI::connect_transport_elements ()
{
RefPtr<Action> act;
/* setup actions */
@ -337,11 +337,13 @@ ARDOUR_UI::setup_transport ()
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
act = ActionManager::get_action ("Transport", "ToggleAutoReturn");
auto_return_button.set_related_action (act);
@ -360,6 +362,11 @@ ARDOUR_UI::setup_transport ()
act = ActionManager::get_action (X_("Monitor Section"), X_("monitor-cut-all"));
monitor_mute_button.set_related_action (act);
if (Profile->get_livetrax()) {
act = ActionManager::get_action (X_("Common"), X_("open-media-folder"));
livetrax_view_in_folder_button->set_related_action (act);
}
act = ActionManager::get_action ("Main", "ToggleLatencyCompensation");
latency_disable_button.set_related_action (act);
@ -375,10 +382,18 @@ ARDOUR_UI::setup_transport ()
secondary_clock->ValueChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::secondary_clock_value_changed));
secondary_clock->change_display_delta_mode_signal.connect (sigc::mem_fun(UIConfiguration::instance(), &UIConfiguration::set_secondary_clock_delta_mode));
big_clock->ValueChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::big_clock_value_changed));
}
void
ARDOUR_UI::setup_transport ()
{
connect_transport_elements ();
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
prefs_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), rc_option_editor));
#endif
recorder_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), recorder));
trigger_page_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), trigger_page));
@ -473,9 +488,11 @@ ARDOUR_UI::setup_transport ()
string_compose (_("Left-Click to show the %1 window\n"
"Right-click to show more options"), mixer->name()));
#ifndef LIVETRAX
Gtkmm2ext::UI::instance()->set_tip (prefs_visibility_button,
string_compose (_("Left-Click to show the %1 window\n"
"Right-click to show more options"), rc_option_editor->name()));
#endif
Gtkmm2ext::UI::instance()->set_tip (recorder_visibility_button,
string_compose (_("Left-Click to show the %1 window\n"
@ -969,7 +986,11 @@ void
ARDOUR_UI::show_ui_prefs ()
{
if (rc_option_editor) {
#ifdef LIVETRAX
rc_option_editor->present();
#else
show_tabbable (rc_option_editor);
#endif
rc_option_editor->set_current_page (_("Appearance"));
}
}
@ -978,7 +999,11 @@ void
ARDOUR_UI::show_mixer_prefs ()
{
if (rc_option_editor) {
#ifdef LIVETRAX
rc_option_editor->present();
#else
show_tabbable (rc_option_editor);
#endif
rc_option_editor->set_current_page (_("Signal Flow"));
}
}
@ -987,7 +1012,11 @@ void
ARDOUR_UI::show_plugin_prefs ()
{
if (rc_option_editor) {
#ifdef LIVETRAX
rc_option_editor->present ();
#else
show_tabbable (rc_option_editor);
#endif
rc_option_editor->set_current_page (_("Plugins"));
}
}
@ -1000,7 +1029,11 @@ ARDOUR_UI::click_button_clicked (GdkEventButton* ev)
return false;
}
#ifdef LIVETRAX
rc_option_editor->present();
#else
show_tabbable (rc_option_editor);
#endif
rc_option_editor->set_current_page (_("Metronome"));
return true;
}
@ -1060,4 +1093,3 @@ ARDOUR_UI::update_title ()
}
snapshot_name_label.set_markup (snap_label.str());
}

View File

@ -17,7 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <fcntl.h> // O_WRONLY
#include <fcntl.h> // O_WRONLY
#include <glib/gstdio.h> // g_unlink()
#include "pbd/basename.h"
@ -50,26 +50,38 @@ using namespace ARDOUR;
static void
aaf_debug_callback (struct aafLog* log, void* ctxdata, int libid, int type, const char* srcfile, const char* srcfunc, int lineno, const char* msg, void* user)
{
const char *eol = "";
const char* eol = "";
if ( libid != LOG_SRC_ID_TRACE && libid != LOG_SRC_ID_DUMP ) {
switch ( type ) {
case VERB_SUCCESS: PBD::info << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
case VERB_ERROR: PBD::error << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
case VERB_WARNING: PBD::warning << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
// case VERB_DEBUG: PBD::debug << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
if (libid != LOG_SRC_ID_TRACE && libid != LOG_SRC_ID_DUMP) {
switch (type) {
case VERB_SUCCESS:
PBD::info << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc);
break;
case VERB_ERROR:
PBD::error << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc);
break;
case VERB_WARNING:
PBD::warning << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc);
break;
// case VERB_DEBUG: PBD::debug << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
}
}
if ( libid != LOG_SRC_ID_DUMP ) {
if (libid != LOG_SRC_ID_DUMP) {
eol = "\n";
}
switch ( type ) {
case VERB_SUCCESS: PBD::info << msg << eol; break;
case VERB_ERROR: PBD::error << msg << eol; break;
case VERB_WARNING: PBD::warning << msg << eol; break;
// case VERB_DEBUG: PBD::debug << msg << eol; break;
switch (type) {
case VERB_SUCCESS:
PBD::info << msg << eol;
break;
case VERB_ERROR:
PBD::error << msg << eol;
break;
case VERB_WARNING:
PBD::warning << msg << eol;
break;
// case VERB_DEBUG: PBD::debug << msg << eol; break;
}
LOG_BUFFER_RESET (log);
@ -121,84 +133,96 @@ prepare_audio_track (aafiAudioTrack* aafTrack, Session* s)
}
static bool
import_sndfile_as_region (Session* s, struct aafiAudioEssencePointer* aafAudioEssencePtrList, SrcQuality quality, timepos_t& pos, SourceList& sources, ImportStatus& status, vector<std::shared_ptr<Region>>& regions)
import_sndfile_as_region (Session* s, struct aafiAudioEssencePointer* aafAudioEssencePtrList, SrcQuality quality, timepos_t& pos, SourceList** oneClipSources, ImportStatus& status, vector<std::shared_ptr<Region>>& regions)
{
/* Import the source */
status.clear ();
SourceList* sources = NULL;
status.current = 1;
status.total = 1;
status.freeze = false;
status.quality = quality;
status.replace_existing_source = false;
status.split_midi_channels = false;
status.import_markers = false;
status.done = false;
status.cancel = false;
if (aafAudioEssencePtrList->user) {
sources = (SourceList*)aafAudioEssencePtrList->user;
} else {
sources = new SourceList;
int channelCount = 0;
/* Import the source */
status.clear ();
aafiAudioEssencePointer *aafAudioEssencePtr = NULL;
AAFI_foreachEssencePointer (aafAudioEssencePtrList, aafAudioEssencePtr) {
if ( aafAudioEssencePtr->essenceFile->usable_file_path )
status.paths.push_back (aafAudioEssencePtr->essenceFile->usable_file_path);
else
status.paths.push_back (aafAudioEssencePtr->essenceFile->original_file_path);
status.current = 1;
status.total = 1;
status.freeze = false;
status.quality = quality;
status.replace_existing_source = false;
status.split_midi_channels = false;
status.import_markers = false;
status.done = false;
status.cancel = false;
channelCount++;
PBD::info << string_compose ("AAF: Preparing to import clip channel %1: %2\n", channelCount, aafAudioEssencePtr->essenceFile->unique_name);
int channelCount = 0;
aafiAudioEssencePointer* aafAudioEssencePtr = NULL;
AAFI_foreachEssencePointer (aafAudioEssencePtrList, aafAudioEssencePtr)
{
if (aafAudioEssencePtr->essenceFile->usable_file_path)
status.paths.push_back (aafAudioEssencePtr->essenceFile->usable_file_path);
else
status.paths.push_back (aafAudioEssencePtr->essenceFile->original_file_path);
channelCount++;
PBD::info << string_compose ("AAF: Preparing to import clip channel %1: %2\n", channelCount, aafAudioEssencePtr->essenceFile->unique_name);
}
s->import_files (status);
status.progress = 1.0;
sources->clear ();
/* FIXME: There is no way to tell if cancel button was pressed
* or if the file failed to import, just that one of these occurred.
* We want status.cancel to reflect the user's choice only
*/
if (status.cancel && status.current > 1) {
/* Succeeded to import file, assume user hit cancel */
return false;
} else if (status.cancel && status.current == 1) {
/* Failed to import file, assume user did not hit cancel */
status.cancel = false;
return false;
}
for (int i = 0; i < channelCount; i++) {
sources->push_back (status.sources.at (i));
}
/* build peakfiles */
for (SourceList::iterator x = sources->begin (); x != sources->end (); ++x) {
SourceFactory::setup_peakfile (*x, true);
}
aafAudioEssencePtrList->user = sources;
}
s->import_files (status);
status.progress = 1.0;
sources.clear ();
/* FIXME: There is no way to tell if cancel button was pressed
* or if the file failed to import, just that one of these occurred.
* We want status.cancel to reflect the user's choice only
*/
if (status.cancel && status.current > 1) {
/* Succeeded to import file, assume user hit cancel */
return false;
} else if (status.cancel && status.current == 1) {
/* Failed to import file, assume user did not hit cancel */
status.cancel = false;
return false;
}
for (int i = 0; i < channelCount; i++) {
sources.push_back (status.sources.at (i));
}
/* build peakfiles */
for (SourceList::iterator x = sources.begin (); x != sources.end (); ++x) {
SourceFactory::setup_peakfile (*x, true);
}
*oneClipSources = sources;
/* Put the source on a region */
std::shared_ptr<Region> region;
string region_name;
/* take all the sources we have and package them up as a region */
region_name = region_name_from_path (status.paths.front (), (sources.size () > 1), false);
region_name = region_name_from_path (status.paths.front (), (sources->size () > 1), false);
/* we checked in import_sndfiles() that there were not too many */
while (RegionFactory::region_by_name (region_name)) {
region_name = bump_name_once (region_name, '.');
}
PropertyList proplist;
proplist.add (ARDOUR::Properties::start, 0);
proplist.add (ARDOUR::Properties::length, timecnt_t (sources[0]->length (), pos));
proplist.add (ARDOUR::Properties::length, timecnt_t ((*sources)[0]->length (), pos));
proplist.add (ARDOUR::Properties::name, aafAudioEssencePtrList->essenceFile->unique_name);
proplist.add (ARDOUR::Properties::layer, 0);
proplist.add (ARDOUR::Properties::whole_file, true);
proplist.add (ARDOUR::Properties::external, true);
region = RegionFactory::create (sources, proplist);
region = RegionFactory::create (*sources, proplist);
regions.push_back (region);
return true;
}
@ -302,14 +326,14 @@ set_region_fade (aafiAudioClip* aafAudioClip, std::shared_ptr<Region> region, aa
samplecnt_t fade_len;
if (fadein != NULL) {
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e) (fadein->flags & AAFI_INTERPOL_MASK));
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e)(fadein->flags & AAFI_INTERPOL_MASK));
fade_len = aafi_convertUnit (fadein->len, aafAudioClip->track->edit_rate, samplerate);
std::dynamic_pointer_cast<AudioRegion> (region)->set_fade_in (fade_shape, fade_len);
}
if (fadeout != NULL) {
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e) (fadeout->flags & AAFI_INTERPOL_MASK));
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e)(fadeout->flags & AAFI_INTERPOL_MASK));
fade_len = aafi_convertUnit (fadeout->len, aafAudioClip->track->edit_rate, samplerate);
std::dynamic_pointer_cast<AudioRegion> (region)->set_fade_out (fade_shape, fade_len);
@ -437,7 +461,6 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
aafi_set_debug (aafi, VERB_DEBUG, 0, NULL, &aaf_debug_callback, this);
if (aafi_load_file (aafi, aaf.c_str ())) {
error << "AAF: Could not load AAF file." << endmsg;
aafi_release (&aafi);
@ -446,8 +469,8 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
/* extract or set session name */
if (aafi->compositionName && aafi->compositionName[0] != 0x00) {
string compositionName = string(aafi->compositionName);
snapshot = laaf_util_clean_filename (&compositionName[0]);
string compositionName = string (aafi->compositionName);
snapshot = laaf_util_clean_filename (&compositionName[0]);
} else {
snapshot = basename_nosuffix (aaf);
}
@ -456,7 +479,7 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
path = Glib::build_filename (target_dir, snapshot);
if (Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
error << string_compose (_("AAF: Destination '%1' already exists."), path) << endmsg;
error << string_compose (_ ("AAF: Destination '%1' already exists."), path) << endmsg;
snapshot = ""; // XXX?
path = "";
aafi_release (&aafi);
@ -465,10 +488,10 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
/* Create media cache */
GError* err = NULL;
char* td = g_dir_make_tmp ("aaf-cache-XXXXXX", &err);
char* td = g_dir_make_tmp ("aaf-cache-XXXXXX", &err);
if (!td) {
error << string_compose (_("AAF: Could not prepare media cache: %1"), err->message) << endmsg;
error << string_compose (_ ("AAF: Could not prepare media cache: %1"), err->message) << endmsg;
aafi_release (&aafi);
return -1;
}
@ -487,16 +510,16 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
samplerate_r.denominator = 1;
std::string restore_backend;
if (!AudioEngine::instance()->running ()) {
AudioEngine* e = AudioEngine::instance();
if (!AudioEngine::instance ()->running ()) {
AudioEngine* e = AudioEngine::instance ();
restore_backend = e->current_backend_name ();
e->set_backend ("None (Dummy)", "", "");
e->start ();
PluginManager::instance ().refresh (true);
attach_to_engine ();
}
if (!AudioEngine::instance()->running ()) {
PBD::error << _("AAF: Could not start [dummy] engine for AAF import .") << endmsg;
if (!AudioEngine::instance ()->running ()) {
PBD::error << _ ("AAF: Could not start [dummy] engine for AAF import .") << endmsg;
return -1;
}
@ -506,10 +529,10 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
aafi_release (&aafi);
PBD::remove_directory (media_cache_path);
if (!restore_backend.empty ()) {
AudioEngine::instance()->stop ();
AudioEngine::instance()->set_backend (restore_backend, "", "");
AudioEngine::instance ()->stop ();
AudioEngine::instance ()->set_backend (restore_backend, "", "");
}
error << _("AAF: Could not create new session for AAF import .") << endmsg;
error << _ ("AAF: Could not create new session for AAF import .") << endmsg;
return -1;
}
@ -547,15 +570,15 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
/* Import Sources */
SourceList oneClipSources;
SourceList* oneClipSources;
ARDOUR::ImportStatus import_status;
vector<std::shared_ptr<Region>> source_regions;
timepos_t pos = timepos_t::max (Temporal::AudioTime);
aafiAudioTrack* aafAudioTrack = NULL;
aafiTimelineItem* aafAudioItem = NULL;
aafiAudioClip* aafAudioClip = NULL;
aafiAudioEssencePointer *aafAudioEssencePtr = NULL;
aafiAudioTrack* aafAudioTrack = NULL;
aafiTimelineItem* aafAudioItem = NULL;
aafiAudioClip* aafAudioClip = NULL;
aafiAudioEssencePointer* aafAudioEssencePtr = NULL;
aafPosition_t sessionStart = aafi_convertUnit (aafi->compositionStart, aafi->compositionStart_editRate, &samplerate_r);
@ -572,19 +595,19 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
}
if (aafAudioClip->essencePointerList == NULL) {
error << _("AAF: Clip has no essence.") << endmsg;
error << _ ("AAF: Clip has no essence.") << endmsg;
continue;
}
int essenceError = 0;
char *essenceName = aafAudioClip->essencePointerList->essenceFile->name;
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr) {
int essenceError = 0;
char* essenceName = aafAudioClip->essencePointerList->essenceFile->name;
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr)
{
struct aafiAudioEssenceFile* audioEssenceFile = aafAudioEssencePtr->essenceFile;
if (!audioEssenceFile) {
PBD::error << string_compose (_("AAF: Could not create new region for clip '%1': Missing audio essence"), audioEssenceFile->unique_name) << endmsg;
PBD::error << string_compose (_ ("AAF: Could not create new region for clip '%1': Missing audio essence"), audioEssenceFile->unique_name) << endmsg;
essenceError++;
continue;
}
@ -607,27 +630,27 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
continue;
}
if (!import_sndfile_as_region (_session, aafAudioClip->essencePointerList, SrcBest, pos, oneClipSources, import_status, source_regions)) {
if (!import_sndfile_as_region (_session, aafAudioClip->essencePointerList, SrcBest, pos, &oneClipSources, import_status, source_regions)) {
PBD::error << string_compose ("AAF: Could not import '%1' to session.", essenceName) << endmsg;
continue;
}
else {
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr) {
} else {
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr)
{
if (aafAudioEssencePtr->essenceFile->is_embedded) {
g_unlink (aafAudioEssencePtr->essenceFile->usable_file_path);
}
}
}
if (oneClipSources.size () == 0) {
error << string_compose (_("AAF: Could not create new region for clip '%1': Region has no source"), essenceName) << endmsg;
if (!oneClipSources || oneClipSources->size () == 0) {
error << string_compose (_ ("AAF: Could not create new region for clip '%1': Region has no source"), essenceName) << endmsg;
continue;
}
std::shared_ptr<Region> region = create_region (source_regions, aafAudioClip, oneClipSources, sessionStart, samplerate_r);
std::shared_ptr<Region> region = create_region (source_regions, aafAudioClip, *oneClipSources, sessionStart, samplerate_r);
if (!region) {
error << string_compose (_("AAF: Could not create new region for clip '%1'"), essenceName) << endmsg;
error << string_compose (_ ("AAF: Could not create new region for clip '%1'"), essenceName) << endmsg;
continue;
}
@ -643,11 +666,12 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
}
}
oneClipSources.clear ();
// oneClipSources.clear ();
aafiMarker* marker = NULL;
AAFI_foreachMarker (aafi, marker) {
AAFI_foreachMarker (aafi, marker)
{
aafPosition_t markerStart = sessionStart + aafi_convertUnit (marker->start, marker->edit_rate, &samplerate_r);
aafPosition_t markerEnd = sessionStart + aafi_convertUnit ((marker->start + marker->length), marker->edit_rate, &samplerate_r);
@ -691,8 +715,8 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
aafi_release (&aafi);
if (!restore_backend.empty ()) {
AudioEngine::instance()->stop ();
AudioEngine::instance()->set_backend (restore_backend, "", "");
AudioEngine::instance ()->stop ();
AudioEngine::instance ()->set_backend (restore_backend, "", "");
}
return 0;
}

View File

@ -36,9 +36,12 @@
#include "ardour/session.h"
#include "ardour/lv2_plugin.h"
#include "ardour/profile.h"
#include "gtkmm2ext/bindings.h"
#include "widgets/ardour_button.h"
#include "actions.h"
#include "ardour_message.h"
#include "ardour_ui.h"
@ -47,6 +50,10 @@
#include "meterbridge.h"
#include "luainstance.h"
#include "luawindow.h"
#include "livetrax_meters.h"
#include "livetrax_tc_widget.h"
#include "main_clock.h"
#include "meterbridge.h"
#include "mixer_ui.h"
#include "recorder_ui.h"
#include "trigger_page.h"
@ -54,6 +61,7 @@
#include "keyeditor.h"
#include "rc_option_editor.h"
#include "route_params_ui.h"
#include "selection_properties_box.h"
#include "time_info_box.h"
#include "trigger_ui.h"
#include "step_entry.h"
@ -67,6 +75,7 @@
using namespace Gtk;
using namespace PBD;
using namespace ArdourWidgets;
namespace ARDOUR {
class Session;
@ -130,9 +139,14 @@ ARDOUR_UI::connect_dependents_to_session (ARDOUR::Session *s)
editor->set_session (s);
BootMessage (_("Setup Mixer"));
mixer->set_session (s);
recorder->set_session (s);
trigger_page->set_session (s);
meterbridge->set_session (s);
if (!Profile->get_livetrax()) {
recorder->set_session (s);
trigger_page->set_session (s);
meterbridge->set_session (s);
} else {
livetrax_time_info_box->set_session (s);
}
/* its safe to do this now */
@ -172,8 +186,10 @@ ARDOUR_UI::tab_window_root_drop (GtkNotebook* src,
tabbable = editor;
} else if (w == GTK_WIDGET(mixer->contents().gobj())) {
tabbable = mixer;
#ifndef LIVETRAX
} else if (w == GTK_WIDGET(rc_option_editor->contents().gobj())) {
tabbable = rc_option_editor;
#endif
} else if (w == GTK_WIDGET(recorder->contents().gobj())) {
tabbable = recorder;
} else if (w == GTK_WIDGET(trigger_page->contents().gobj())) {
@ -249,13 +265,19 @@ tab_window_root_drop (GtkNotebook* src,
int
ARDOUR_UI::setup_windows ()
{
if (ARDOUR::Profile->get_livetrax()) {
return livetrax_setup_windows ();
}
_tabs.set_show_border(false);
_tabs.signal_switch_page().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_switch));
_tabs.signal_page_added().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_page_added));
_tabs.signal_page_removed().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_page_removed));
rc_option_editor = new RCOptionEditor;
#ifndef LIVETRAX
rc_option_editor->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
#endif
if (create_editor ()) {
error << _("UI: cannot setup editor") << endmsg;
@ -289,7 +311,9 @@ ARDOUR_UI::setup_windows ()
/* order of addition affects order seen in initial window display */
#ifndef LIVETRAX
rc_option_editor->add_to_notebook (_tabs);
#endif
mixer->add_to_notebook (_tabs);
editor->add_to_notebook (_tabs);
recorder->add_to_notebook (_tabs);
@ -360,6 +384,185 @@ ARDOUR_UI::setup_windows ()
return 0;
}
int
ARDOUR_UI::livetrax_setup_windows ()
{
using namespace Menu_Helpers;
using namespace Gtk;
rc_option_editor = new RCOptionEditor;
ArdourButton::set_default_tweaks (ArdourButton::Tweaks (ArdourButton::ForceBoxy|ArdourButton::ForceFlat));
if (create_editor()) {
error << _("UI: cannot setup editor") << endmsg;
return -1;
}
if (create_mixer()) {
error << _("UI: cannot setup mixer") << endmsg;
return -1;
}
livetrax_time_info_box = new TimeInfoBox ("LiveTraxTimeInfo", false);
Image* icon = manage (new Image (ARDOUR_UI_UTILS::get_icon ("allenheath")));
VBox* vb;
HBox* hb;
ArdourButton::Element elements (ArdourButton::Element (ArdourButton::Text|ArdourButton::VectorIcon));
Gtkmm2ext::Bindings* bindings;
Glib::RefPtr<Action> act;
livetrax_top_bar.set_spacing (12);
livetrax_top_bar.set_border_width (12);
livetrax_top_bar.pack_start (*icon, false, false);
livetrax_top_bar.pack_start (*livetrax_time_info_box, false, false);
livetrax_top_bar.pack_start (*primary_clock, false, false);
EventBox* ev_dsp = manage (new EventBox);
EventBox* ev_timecode = manage (new EventBox);
ev_dsp->set_name ("MainMenuBar");
ev_timecode->set_name ("MainMenuBar");
ev_dsp->add (dsp_load_label);
ev_timecode->add (timecode_format_label);
livetrax_ff_dropdown = manage (new ArdourDropdown ());
Menu_Helpers::MenuList& items (livetrax_ff_dropdown->items());
items.push_back (MenuElem (_("24 bit WAV/RF64"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::livetrax_set_file_format), LiveTraxFileFormat (ARDOUR::FormatInt24, ARDOUR::RF64_WAV))));
items.push_back (MenuElem (_("24 bit FLAC"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::livetrax_set_file_format), LiveTraxFileFormat (ARDOUR::FormatInt24, ARDOUR::FLAC))));
livetrax_sr_button = manage (new ArdourButton (""));
vb = manage (new VBox);
vb->pack_start (*livetrax_ff_dropdown, false, false);
vb->pack_start (*livetrax_sr_button, false, false);
livetrax_top_bar.pack_start (*vb, false, false);
CairoWidget* cw = new LiveTraxTCWidget;
cw->show ();
livetrax_top_bar.pack_start (*cw, false, false);
vb = manage (new VBox);
vb->pack_start (*ev_dsp, true, true);
vb->pack_start (disk_space_label, true, true);
vb->show_all ();
livetrax_top_bar.pack_end (*vb, false, false);
livetrax_multi_out_button = manage (new ArdourButton (_("Multi Out")));
livetrax_stereo_out_button = manage (new ArdourButton (_("Stereo Out")));
act = ActionManager::get_action (X_("Common"), X_("disable-virtual-soundcheck"));
livetrax_stereo_out_button->set_related_action (act);
act = ActionManager::get_action (X_("Common"), X_("enable-virtual-soundcheck"));
livetrax_multi_out_button->set_related_action (act);
vb = manage (new VBox);
vb->pack_start (*livetrax_stereo_out_button, true, true);
vb->pack_start (*livetrax_multi_out_button, true, true);
vb->show_all ();
livetrax_top_bar.pack_end (*vb, false, false);
/* transport bar */
livetrax_meter_view_button = manage (new ArdourButton (_("METERS"), ArdourButton::Element (ArdourButton::Text|ArdourButton::Edge|ArdourButton::Body), true));;
act = ActionManager::get_action (X_("Common"), X_("livetrax-toggle-meter"));
livetrax_meter_view_button->set_related_action (act);
livetrax_mixer_view_button = manage (new ArdourButton (_("MIXER"), ArdourButton::Element (ArdourButton::Text|ArdourButton::Edge|ArdourButton::Body), true));
act = ActionManager::get_action (X_("Common"), X_("livetrax-toggle-mixer"));
livetrax_mixer_view_button->set_related_action (act);
livetrax_editor_view_button = manage (new ArdourButton (_("TRACKS"), ArdourButton::Element (ArdourButton::Text|ArdourButton::Edge|ArdourButton::Body), true));
act = ActionManager::get_action (X_("Common"), X_("livetrax-toggle-editor"));
livetrax_editor_view_button->set_related_action (act);
livetrax_transport_bar.pack_start (*livetrax_editor_view_button, false, false);
livetrax_transport_bar.pack_start (*livetrax_mixer_view_button, false, false);
livetrax_transport_bar.pack_start (*livetrax_meter_view_button, false, false);
hb = manage (new HBox);
hb->pack_start (transport_ctrl, false, false);
livetrax_lock_button = manage (new ArdourButton (_("🔒"), elements));
livetrax_lock_button->set_layout_font (UIConfiguration::instance().get_LargerBoldMonospaceFont());
editor->mouse_mode_hbox->pack_start (*livetrax_lock_button, false, false, 12);
livetrax_transport_bar.pack_start (*hb, true, false);
livetrax_transport_bar.pack_start (*editor->mouse_mode_hbox, true, false);
livetrax_view_in_folder_button = manage (new ArdourButton (_("MEDIA"), elements));
editor->_zoom_box.pack_start (*livetrax_view_in_folder_button, false, false, 12);
livetrax_transport_bar.pack_end (editor->_zoom_box, false, false);
livetrax_transport_bar.show_all ();
/* meter display */
livetrax_meters = manage (new LiveTraxMeters (48));
livetrax_meters->show_all ();
livetrax_meter_bar.set_border_width (12);
livetrax_meter_bar.pack_start (*livetrax_meters, true, true, 12);
hb = manage (new HBox);
livetrax_edit_vscrollbar = manage (new VScrollbar (editor->vertical_adjustment));
livetrax_edit_vscrollbar->show ();
hb->pack_start (editor->contents(), true, true);
hb->pack_start (*livetrax_edit_vscrollbar, false, false);
vb = manage (new VBox);
livetrax_edit_hscrollbar = manage (new HScrollbar (editor->horizontal_adjustment));
livetrax_edit_hscrollbar->show ();
vb->pack_start (*hb, true, true);
vb->pack_start (*livetrax_edit_hscrollbar, false, false);
livetrax_editor_bar.pack_start (*vb, true, true);
livetrax_mixer_bar.pack_start (mixer->contents(), true, true);
we_have_dependents ();
/* order of addition affects order seen in initial window display */
main_vpacker.pack_start (menu_bar_base, false, false);
main_vpacker.pack_start (livetrax_top_bar, false, false);
main_vpacker.pack_start (livetrax_transport_bar, false, false);
main_vpacker.pack_start (livetrax_meter_bar, false, false);
main_vpacker.pack_start (livetrax_editor_bar, true, true);
main_vpacker.pack_start (livetrax_mixer_bar, true, true);
connect_transport_elements ();
setup_tooltips ();
build_menu_bar ();
bindings = Bindings::get_bindings (X_("Editor"));
livetrax_editor_bar.set_data ("ardour-bindings", bindings);
bindings = Bindings::get_bindings (X_("Mixer"));
livetrax_mixer_bar.set_data ("ardour-bindings", bindings);
_livetrax_visibility = LiveTraxVisibility (LiveTraxMeterVisible|LiveTraxMixerVisible|LiveTraxEditorVisible);
livetrax_visibility_change ();
// setup_tooltips ();
_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
*/
_main_window.add (main_vpacker);
apply_window_settings (true);
setup_toplevel_window (_main_window, "", this);
_main_window.show_all ();
#ifdef GDK_WINDOWING_X11
/* allow externalUIs to be transient, on top of the main window */
LV2Plugin::set_main_window_id (GDK_DRAWABLE_XID(_main_window.get_window()->gobj()));
#endif
return 0;
}
void
ARDOUR_UI::apply_window_settings (bool with_size)
{
@ -416,8 +619,10 @@ ARDOUR_UI::apply_window_settings (bool with_size)
if (mixer && current_tab == "mixer") {
_tabs.set_current_page (_tabs.page_num (mixer->contents()));
#ifndef LIVETRAX
} else if (rc_option_editor && current_tab == "preferences") {
_tabs.set_current_page (_tabs.page_num (rc_option_editor->contents()));
#endif
} else if (recorder && current_tab == "recorder") {
_tabs.set_current_page (_tabs.page_num (recorder->contents()));
} else if (trigger_page && current_tab == "trigger") {
@ -482,3 +687,78 @@ ARDOUR_UI::action_script_changed (int i, const std::string& n)
}
KeyEditor::UpdateBindings ();
}
void
ARDOUR_UI::livetrax_visibility_change ()
{
if (_livetrax_visibility & LiveTraxMeterVisible) {
livetrax_meter_bar.show ();
livetrax_meter_view_button->set_active_state (Gtkmm2ext::ExplicitActive);
} else {
livetrax_meter_bar.hide ();
livetrax_meter_view_button->set_active_state (Gtkmm2ext::Off);
}
if (_livetrax_visibility & LiveTraxEditorVisible) {
livetrax_editor_bar.show ();
livetrax_editor_view_button->set_active_state (Gtkmm2ext::ExplicitActive);
} else {
livetrax_editor_bar.hide ();
livetrax_editor_view_button->set_active_state (Gtkmm2ext::Off);
}
if (_livetrax_visibility & LiveTraxMixerVisible) {
livetrax_mixer_bar.show ();
livetrax_mixer_view_button->set_active_state (Gtkmm2ext::ExplicitActive);
} else {
livetrax_mixer_bar.hide ();
livetrax_mixer_view_button->set_active_state (Gtkmm2ext::Off);
}
}
void
ARDOUR_UI::livetrax_toggle_visibility (LiveTraxVisibility v)
{
if (_livetrax_visibility & v) {
_livetrax_visibility = LiveTraxVisibility (_livetrax_visibility & ~v);
} else {
_livetrax_visibility = LiveTraxVisibility (_livetrax_visibility | v);
}
livetrax_visibility_change ();
}
void
ARDOUR_UI::livetrax_set_file_format (LiveTraxFileFormat const & ff)
{
if (!_session) {
return;
}
/* Don't reset write sources on header format change */
_session->disable_file_format_reset ();
_session->config.set_native_file_header_format (ff.hf);
_session->config.set_native_file_data_format (ff.sf);
_session->enable_file_format_reset ();
_session->reset_native_file_format ();
}
void
ARDOUR_UI::virtual_soundcheck_changed (bool onoff)
{
if (!Profile->get_livetrax()) {
return;
}
if (onoff) {
livetrax_stereo_out_button->set_active_state (Gtkmm2ext::Off);
livetrax_multi_out_button->set_active_state (Gtkmm2ext::ExplicitActive);
} else {
livetrax_stereo_out_button->set_active_state (Gtkmm2ext::ExplicitActive);
livetrax_multi_out_button->set_active_state (Gtkmm2ext::Off);
}
}

View File

@ -156,15 +156,18 @@ ARDOUR_UI::set_session (Session *s)
AutomationWatch::instance().set_session (s);
shuttle_box.set_session (s);
mini_timeline.set_session (s);
time_info_box->set_session (s);
primary_clock->set_session (s);
secondary_clock->set_session (s);
big_clock->set_session (s);
video_timeline->set_session (s);
rc_option_editor->set_session (s);
if (!Profile->get_livetrax()) {
shuttle_box.set_session (s);
mini_timeline.set_session (s);
time_info_box->set_session (s);
secondary_clock->set_session (s);
big_clock->set_session (s);
video_timeline->set_session (s);
rc_option_editor->set_session (s);
}
roll_controllable->set_session (s);
stop_controllable->set_session (s);
@ -206,6 +209,11 @@ ARDOUR_UI::set_session (Session *s)
_session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
_session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
if (Profile->get_livetrax()) {
_session->VirtualSoundCheckChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::virtual_soundcheck_changed, this, _1), gui_context());
virtual_soundcheck_changed (_session->virtual_soundcheck());
}
_session->PunchLoopConstraintChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::set_punch_sensitivity, this), gui_context());
_session->auto_punch_location_changed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::set_punch_sensitivity, this), gui_context ());
@ -488,10 +496,11 @@ ARDOUR_UI::step_up_through_tabs ()
candidates.push_back (trigger_page);
}
#ifndef LIVETRAX
if (rc_option_editor->tabbed()) {
candidates.push_back (rc_option_editor);
}
#endif
if (candidates.size() < 2) {
/* nothing to be done with zero or one visible in tabs */
return;
@ -537,10 +546,11 @@ ARDOUR_UI::step_down_through_tabs ()
candidates.push_back (trigger_page);
}
#ifndef LIVETRAX
if (rc_option_editor->tabbed()) {
candidates.push_back (rc_option_editor);
}
#endif
if (candidates.size() < 2) {
/* nothing to be done with zero or one visible in tabs */
return;
@ -667,10 +677,12 @@ ARDOUR_UI::tabs_page_added (Widget*,guint)
Pango::FontDescription ("Sans 24"),
0, 0,
Gdk::Color ("red")));
#ifndef LIVETRAX
prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
Pango::FontDescription ("Sans 24"),
0, 0,
Gdk::Color ("red")));
#endif
recorder_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (recorder->name(),
Pango::FontDescription ("Sans 24"),
0, 0,
@ -705,9 +717,11 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#ifndef LIVETRAX
if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#endif
if (recorder && (recorder->tabbed() || recorder->tabbed_by_default())) {
recorder_visibility_button.set_active_state (Gtkmm2ext::Off);
@ -725,9 +739,11 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
#ifndef LIVETRAX
if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#endif
if (recorder && (recorder->tabbed() || recorder->tabbed_by_default())) {
recorder_visibility_button.set_active_state (Gtkmm2ext::Off);
@ -737,6 +753,7 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
trigger_page_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#ifndef LIVETRAX
} else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
@ -756,7 +773,7 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
if (trigger_page && (trigger_page->tabbed() || trigger_page->tabbed_by_default())) {
trigger_page_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#endif
} else if (page == (guint) _tabs.page_num (recorder->contents())) {
if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
@ -767,9 +784,11 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#ifndef LIVETRAX
if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#endif
recorder_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
@ -787,9 +806,11 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#ifndef LIVETRAX
if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
}
#endif
if (recorder && (recorder->tabbed() || recorder->tabbed_by_default())) {
recorder_visibility_button.set_active_state (Gtkmm2ext::Off);
@ -883,8 +904,10 @@ ARDOUR_UI::tabbable_state_change (Tabbable& t)
vis_button = &editor_visibility_button;
} else if (&t == mixer) {
vis_button = &mixer_visibility_button;
#ifndef LIVETRAX
} else if (&t == rc_option_editor) {
vis_button = &prefs_visibility_button;
#endif
} else if (&t == recorder) {
vis_button = &recorder_visibility_button;
} else if (&t == trigger_page) {

View File

@ -99,7 +99,9 @@ ARDOUR_UI::create_editor ()
{
try {
editor = new Editor ();
editor->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
if (!ARDOUR::Profile->get_livetrax()) {
editor->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
}
}
catch (failed_constructor& err) {
@ -116,7 +118,9 @@ ARDOUR_UI::create_recorder ()
{
try {
recorder = new RecorderUI ();
recorder->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
if (!ARDOUR::Profile->get_livetrax()) {
recorder->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
}
} catch (failed_constructor& err) {
return -1;
}
@ -128,7 +132,9 @@ ARDOUR_UI::create_trigger_page ()
{
try {
trigger_page = new TriggerPage ();
trigger_page->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
if (!ARDOUR::Profile->get_livetrax()) {
trigger_page->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
}
} catch (failed_constructor& err) {
return -1;
}
@ -280,6 +286,13 @@ ARDOUR_UI::install_actions ()
ActionManager::register_action (common_actions, X_("show-ui-prefs"), _("Show more UI preferences"), sigc::mem_fun (*this, &ARDOUR_UI::show_ui_prefs));
}
if (Profile->get_livetrax()) {
/* XXX should these be toggles? */
ActionManager::register_action (common_actions, X_("livetrax-toggle-meter"), _("Hide/Show Meters"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::livetrax_toggle_visibility), LiveTraxMeterVisible));
ActionManager::register_action (common_actions, X_("livetrax-toggle-mixer"), _("Hide/Show Mixer"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::livetrax_toggle_visibility), LiveTraxMixerVisible));
ActionManager::register_action (common_actions, X_("livetrax-toggle-editor"), _("Hide/Show Editor"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::livetrax_toggle_visibility), LiveTraxEditorVisible));
}
ActionManager::register_action (common_actions, X_("toggle-meterbridge"), S_("Window|Meterbridge"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_meterbridge));
act = ActionManager::register_action (common_actions, X_("NewMIDITracer"), _("MIDI Tracer"), sigc::mem_fun(*this, &ARDOUR_UI::new_midi_tracer_window));
@ -293,6 +306,7 @@ ARDOUR_UI::install_actions ()
ActionManager::register_action (common_actions, X_("website-dev"), _("Development"), mem_fun(*this, &ARDOUR_UI::launch_website_dev));
ActionManager::register_action (common_actions, X_("forums"), _("User Forums"), mem_fun(*this, &ARDOUR_UI::launch_forums));
ActionManager::register_action (common_actions, X_("howto-report"), _("How to Report a Bug"), mem_fun(*this, &ARDOUR_UI::launch_howto_report));
ActionManager::register_action (common_actions, X_("open-media-folder"), _("Open Media Folder"), mem_fun(*this, &ARDOUR_UI::open_media_folder));
act = ActionManager::register_action (common_actions, X_("Save"), _("Save"), sigc::hide_return (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::save_state), string(""), false)));
ActionManager::session_sensitive_actions.push_back (act);
@ -539,6 +553,11 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_action (midi_actions, X_("panic"), _("Panic (Send MIDI all-notes-off)"), sigc::mem_fun(*this, &ARDOUR_UI::midi_panic));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
if (Profile->get_livetrax()) {
act = ActionManager::register_action (common_actions, X_("disable-virtual-soundcheck"), _("Disable Virtual Soundcheck"), sigc::mem_fun (*this, &ARDOUR_UI::disable_virtual_soundcheck));
act = ActionManager::register_action (common_actions, X_("enable-virtual-soundcheck"), _("Enable Virtual Soundcheck"), sigc::mem_fun (*this, &ARDOUR_UI::enable_virtual_soundcheck));
}
}
void
@ -695,29 +714,37 @@ ARDOUR_UI::install_dependent_actions ()
/* XXX */
#ifdef LIVETRAX
ActionManager::register_action (common_actions, X_("menu-show-preferences"), _("Preferences"), sigc::mem_fun (*this, &ARDOUR_UI::show_mixer_prefs));
ActionManager::register_action (common_actions, X_("show-preferences"), _("Preferences"), sigc::mem_fun (*this, &ARDOUR_UI::show_mixer_prefs));
ActionManager::register_action (common_actions, X_("hide-preferences"), _("Hide"), sigc::mem_fun (*rc_option_editor, &Gtk::Widget::hide));
#else
ActionManager::register_action (common_actions, X_("menu-show-preferences"), _("Preferences"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("show-preferences"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("hide-preferences"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("attach-preferences"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("detach-preferences"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("change-preferences-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), rc_option_editor));
ActionManager::register_action (common_actions, X_("key-change-preferences-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), rc_option_editor));
#endif
ActionManager::register_action (common_actions, X_("hide-editor"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), editor));
ActionManager::register_action (common_actions, X_("hide-mixer"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), mixer));
ActionManager::register_action (common_actions, X_("hide-preferences"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("hide-recorder"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), recorder));
ActionManager::register_action (common_actions, X_("hide-trigger"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), trigger_page));
ActionManager::register_action (common_actions, X_("attach-editor"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), editor));
ActionManager::register_action (common_actions, X_("attach-mixer"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), mixer));
ActionManager::register_action (common_actions, X_("attach-preferences"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("attach-recorder"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), recorder));
ActionManager::register_action (common_actions, X_("attach-trigger"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), trigger_page));
ActionManager::register_action (common_actions, X_("detach-editor"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), editor));
ActionManager::register_action (common_actions, X_("detach-mixer"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), mixer));
ActionManager::register_action (common_actions, X_("detach-preferences"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("detach-recorder"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), recorder));
ActionManager::register_action (common_actions, X_("detach-trigger"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), trigger_page));
ActionManager::register_action (common_actions, X_("show-editor"), _("Show Editor"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), editor));
ActionManager::register_action (common_actions, X_("show-mixer"), _("Show Mixer"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), mixer));
ActionManager::register_action (common_actions, X_("show-preferences"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor));
ActionManager::register_action (common_actions, X_("show-recorder"), _("Show Recorder"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), recorder));
ActionManager::register_action (common_actions, X_("show-trigger"), _("Show Cues"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), trigger_page));
@ -727,7 +754,6 @@ ARDOUR_UI::install_dependent_actions ()
*/
ActionManager::register_action (common_actions, X_("change-editor-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), editor));
ActionManager::register_action (common_actions, X_("change-mixer-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), mixer));
ActionManager::register_action (common_actions, X_("change-preferences-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), rc_option_editor));
ActionManager::register_action (common_actions, X_("change-recorder-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), recorder));
ActionManager::register_action (common_actions, X_("change-trigger-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), trigger_page));
@ -737,7 +763,6 @@ ARDOUR_UI::install_dependent_actions ()
*/
ActionManager::register_action (common_actions, X_("key-change-editor-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), editor));
ActionManager::register_action (common_actions, X_("key-change-mixer-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), mixer));
ActionManager::register_action (common_actions, X_("key-change-preferences-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), rc_option_editor));
ActionManager::register_action (common_actions, X_("key-change-recorder-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), recorder));
ActionManager::register_action (common_actions, X_("key-change-trigger-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), trigger_page));
@ -762,19 +787,25 @@ ARDOUR_UI::build_menu_bar ()
ev->set_name ("MainMenuBar");
ev->show ();
EventBox* ev_dsp = manage (new EventBox);
EventBox* ev_dsp;
EventBox* ev_timecode;
EventBox* ev_path = manage (new EventBox);
EventBox* ev_name = manage (new EventBox);
EventBox* ev_audio = manage (new EventBox);
EventBox* ev_format = manage (new EventBox);
EventBox* ev_timecode = manage (new EventBox);
ev_dsp->set_name ("MainMenuBar");
if (!Profile->get_livetrax()) {
ev_dsp = manage (new EventBox);
ev_timecode = manage (new EventBox);
ev_dsp->set_name ("MainMenuBar");
ev_timecode->set_name ("MainMenuBar");
}
ev_path->set_name ("MainMenuBar");
ev_name->set_name ("MainMenuBar");
ev_audio->set_name ("MainMenuBar");
ev_format->set_name ("MainMenuBar");
ev_timecode->set_name ("MainMenuBar");
Gtk::HBox* hbox = manage (new Gtk::HBox);
hbox->show ();
@ -794,18 +825,23 @@ ARDOUR_UI::build_menu_bar ()
snapshot_name_label.set_name ("Name");
format_label.set_use_markup ();
ev_dsp->add (dsp_load_label);
if (!Profile->get_livetrax()) {
ev_dsp->add (dsp_load_label);
ev_timecode->add (timecode_format_label);
ev_audio->add (sample_rate_label);
}
ev_path->add (session_path_label);
ev_name->add (snapshot_name_label);
ev_audio->add (sample_rate_label);
ev_format->add (format_label);
ev_timecode->add (timecode_format_label);
ev_dsp->show ();
if (!Profile->get_livetrax()) {
ev_dsp->show ();
ev_timecode->show ();
ev_audio->show ();
}
ev_path->show ();
ev_audio->show ();
ev_format->show ();
ev_timecode->show ();
#ifdef __APPLE__
use_menubar_as_top_menubar ();
@ -816,10 +852,14 @@ ARDOUR_UI::build_menu_bar ()
hbox->pack_end (error_alert_button, false, false, 2);
hbox->pack_end (wall_clock_label, false, false, 10);
hbox->pack_end (*ev_dsp, false, false, 6);
hbox->pack_end (disk_space_label, false, false, 6);
if (!Profile->get_livetrax()) {
hbox->pack_end (*ev_dsp, false, false, 6);
hbox->pack_end (disk_space_label, false, false, 6);
}
hbox->pack_end (*ev_audio, false, false, 6);
hbox->pack_end (*ev_timecode, false, false, 6);
if (!Profile->get_livetrax()) {
hbox->pack_end (*ev_timecode, false, false, 6);
}
hbox->pack_end (*ev_format, false, false, 6);
hbox->pack_end (peak_thread_work_label, false, false, 6);
hbox->pack_end (*ev_name, false, false, 6);
@ -834,10 +874,13 @@ ARDOUR_UI::build_menu_bar ()
_status_bar_visibility.add (&snapshot_name_label ,X_("Name"), _("Snapshot Name and Modified Indicator"), false);
_status_bar_visibility.add (&peak_thread_work_label,X_("Peakfile"), _("Active Peak-file Work"), false);
_status_bar_visibility.add (&format_label, X_("Format"), _("File Format"), false);
_status_bar_visibility.add (&timecode_format_label, X_("TCFormat"), _("Timecode Format"), false);
_status_bar_visibility.add (&sample_rate_label, X_("Audio"), _("Audio"), true);
_status_bar_visibility.add (&disk_space_label, X_("Disk"), _("Disk Space"), !Profile->get_small_screen());
_status_bar_visibility.add (&dsp_load_label, X_("DSP"), _("DSP"), true);
if (!Profile->get_livetrax()) {
_status_bar_visibility.add (&timecode_format_label, X_("TCFormat"), _("Timecode Format"), false);
_status_bar_visibility.add (&disk_space_label, X_("Disk"), _("Disk Space"), !Profile->get_small_screen());
_status_bar_visibility.add (&dsp_load_label, X_("DSP"), _("DSP"), true);
}
#ifndef __APPLE__
// OSX provides its own wallclock, thank you very much
_status_bar_visibility.add (&wall_clock_label, X_("WallClock"), _("Wall Clock"), false);
@ -845,13 +888,16 @@ ARDOUR_UI::build_menu_bar ()
ev->signal_button_press_event().connect (sigc::mem_fun (_status_bar_visibility, &VisibilityGroup::button_press_event));
ev_dsp->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::xrun_button_press));
ev_dsp->signal_button_release_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::xrun_button_release));
if (!Profile->get_livetrax()) {
ev_dsp->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::xrun_button_press));
ev_dsp->signal_button_release_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::xrun_button_release));
ev_timecode->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::timecode_button_press));
}
ev_path->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::path_button_press));
ev_name->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::path_button_press));
ev_audio->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::audio_button_press));
ev_format->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::format_button_press));
ev_timecode->signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::timecode_button_press));
ArdourWidgets::set_tooltip (session_path_label, _("Double click to open session folder."));
ArdourWidgets::set_tooltip (format_label, _("Double click to edit audio file format."));
@ -930,8 +976,10 @@ ARDOUR_UI::save_ardour_state ()
current_tab = "recorder";
} else if (current_page_number == _tabs.page_num (trigger_page->contents())) {
current_tab = "trigger";
#ifndef LIVETRAX
} else if (current_page_number == _tabs.page_num (rc_option_editor->contents())) {
current_tab = "preferences";
#endif
}
main_window_node.set_property (X_("current-tab"), current_tab);

View File

@ -143,7 +143,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
}
}
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 [title = %9] focus = %7 (%8) Key event: code = %2 [%10] state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7 mods ? %8\n",
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 [title = %9] focus = %7 (mods %8) Key event: code = %2 [%10] state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7 mods ? %8\n",
win,
ev->keyval,
Gtkmm2ext::show_gdk_event_state (ev->state),

View File

@ -26,6 +26,8 @@
is to cut down on the nasty compile times for these classes.
*/
#include "ardour/profile.h"
#include "gtkmm2ext/keyboard.h"
#include "actions.h"
@ -44,7 +46,9 @@ ARDOUR_UI::create_mixer ()
{
try {
mixer = Mixer_UI::instance ();
mixer->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
if (!ARDOUR::Profile->get_livetrax()) {
mixer->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
}
}
catch (failed_constructor& err) {

View File

@ -60,6 +60,26 @@ using namespace ARDOUR;
using namespace PBD;
using namespace ArdourWidgets;
void
ARDOUR_UI::enable_virtual_soundcheck ()
{
if (!_session) {
return;
}
_session->enable_virtual_soundcheck ();
}
void
ARDOUR_UI::disable_virtual_soundcheck ()
{
if (!_session) {
return;
}
_session->disable_virtual_soundcheck ();
}
void
ARDOUR_UI::toggle_external_sync()
{

View File

@ -117,10 +117,6 @@ ARDOUR_UI::setup_profile ()
if (gdk_screen_width() < 1200 || getenv ("ARDOUR_NARROW_SCREEN")) {
Profile->set_small_screen ();
}
if (g_getenv ("MIXBUS")) {
Profile->set_mixbus ();
}
}
int
@ -209,8 +205,8 @@ audio will be resampled, which reduces quality.\n"), desired, PROGRAM_NAME, actu
switch (dialog.run()) {
case RESPONSE_YES:
ARDOUR::AudioEngine::instance ()->stop ();
(dynamic_cast<EngineControl*> (audio_midi_setup.get (true)))->run ();
(dynamic_cast<EngineControl*> (audio_midi_setup.get (true)))->hide ();
(dynamic_cast<EngineControlDialog*> (audio_midi_setup.get (true)))->run ();
(dynamic_cast<EngineControlDialog*> (audio_midi_setup.get (true)))->hide ();
return AudioEngine::instance()->running () ? -1 : 1;
case RESPONSE_ACCEPT:
return 0;
@ -584,10 +580,10 @@ ARDOUR_UI::starting ()
* audio backend end up.
*/
EngineControl* amd;
EngineControlDialog* amd;
try {
amd = dynamic_cast<EngineControl*> (audio_midi_setup.get (true));
amd = dynamic_cast<EngineControlDialog*> (audio_midi_setup.get (true));
} catch (...) {
std::cerr << "audio-midi engine setup failed."<< std::endl;
return -1;
@ -926,10 +922,10 @@ ARDOUR_UI::load_from_application_api (const std::string& path)
/* do this again */
EngineControl* amd;
EngineControlDialog* amd;
try {
amd = dynamic_cast<EngineControl*> (audio_midi_setup.get (true));
amd = dynamic_cast<EngineControlDialog*> (audio_midi_setup.get (true));
} catch (...) {
std::cerr << "audio-midi engine setup failed."<< std::endl;
return;

View File

@ -33,10 +33,12 @@
#include "ardour/audioregion.h"
#include "ardour/session_event.h"
#include "ardour/dB.h"
#include "ardour/region_fx_plugin.h"
#include "audio_region_editor.h"
#include "audio_region_view.h"
#include "gui_thread.h"
#include "public_editor.h"
#include "pbd/i18n.h"
@ -52,11 +54,13 @@ _peak_amplitude_thread (void* arg)
return 0;
}
AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r)
: RegionEditor (s, r)
, _audio_region (r)
AudioRegionEditor::AudioRegionEditor (Session* s, AudioRegionView* arv)
: RegionEditor (s, arv)
, _arv (arv)
, _audio_region (arv->audio_region ())
, gain_adjustment(accurate_coefficient_to_dB(fabsf (_audio_region->scale_amplitude())), -40.0, +40.0, 0.1, 1.0, 0)
, _polarity_toggle (_("Invert"))
, _show_on_touch (_("Show on Touch"))
, _peak_channel (false)
{
@ -87,14 +91,27 @@ AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r
_polarity_label.set_name ("AudioRegionEditorLabel");
_polarity_label.set_text (_("Polarity:"));
_polarity_label.set_alignment (1, 0.5);
_table.attach (_polarity_label, 0, 1, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
_table.attach (_polarity_toggle, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
++_table_row;
_region_line_label.set_name ("AudioRegionEditorLabel");
_region_line_label.set_text (_("Region Line:"));
_region_line_label.set_alignment (1, 0.5);
_table.attach (_region_line_label, 0, 1, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
_table.attach (_region_line, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
_table.attach (_show_on_touch, 2, 3, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
++_table_row;
gain_changed ();
refill_region_line ();
gain_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &AudioRegionEditor::gain_adjustment_changed));
_polarity_toggle.signal_toggled().connect (sigc::mem_fun (*this, &AudioRegionEditor::gain_adjustment_changed));
_show_on_touch.signal_toggled().connect (sigc::mem_fun (*this, &AudioRegionEditor::show_on_touch_changed));
arv->region_line_changed.connect ((sigc::mem_fun (*this, &AudioRegionEditor::refill_region_line)));
_peak_amplitude.property_editable() = false;
_peak_amplitude.set_text (_("Calculating..."));
@ -105,6 +122,7 @@ AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r
snprintf (name, 64, "peak amplitude-%p", this);
pthread_create_and_store (name, &_peak_amplitude_thread_handle, _peak_amplitude_thread, this);
signal_peak_thread ();
}
AudioRegionEditor::~AudioRegionEditor ()
@ -128,6 +146,14 @@ AudioRegionEditor::region_changed (const PBD::PropertyChange& what_changed)
signal_peak_thread ();
}
}
void
AudioRegionEditor::region_fx_changed ()
{
RegionEditor::region_fx_changed ();
refill_region_line ();
}
void
AudioRegionEditor::gain_changed ()
{
@ -189,3 +215,118 @@ AudioRegionEditor::peak_amplitude_found (double p)
_peak_amplitude.set_text (s.str ());
}
void
AudioRegionEditor::show_touched_automation (std::weak_ptr<PBD::Controllable> wac)
{
if (!_arv->set_region_fx_line (wac)) {
return;
}
switch (PublicEditor::instance ().current_mouse_mode ()) {
case Editing::MouseObject:
case Editing::MouseTimeFX:
case Editing::MouseGrid:
case Editing::MouseCut:
PublicEditor::instance ().set_mouse_mode (Editing::MouseDraw, false);
break;
default:
break;
}
}
void
AudioRegionEditor::show_on_touch_changed ()
{
if (!_show_on_touch.get_active ()) {
_ctrl_touched_connection.disconnect ();
return;
}
Controllable::ControlTouched.connect (_ctrl_touched_connection, invalidator (*this), boost::bind (&AudioRegionEditor::show_touched_automation, this, _1), gui_context ());
}
void
AudioRegionEditor::refill_region_line ()
{
using namespace Gtk::Menu_Helpers;
_region_line.clear_items ();
MenuList& rm_items (_region_line.items ());
int nth = 0;
PBD::ID rfx_id (0);
uint32_t param_id = 0;
string active_text = _("Gain Envelope");
_arv->get_region_fx_line (rfx_id, param_id);
_arv->set_ignore_line_change (true);
Gtk::RadioMenuItem::Group grp;
AudioRegionView* arv = _arv;
rm_items.push_back (RadioMenuElem (grp, _("Gain Envelope")));
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&rm_items.back ());
cmi->set_active (rfx_id == 0 || param_id == UINT32_MAX);
cmi->signal_activate ().connect ([cmi, arv] () { if (cmi->get_active ()) {arv->set_region_gain_line (); }});
_audio_region->foreach_plugin ([&rm_items, arv, &nth, &grp, &active_text, rfx_id, param_id](std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> fx (wfx.lock ());
if (!fx) {
return;
}
std::shared_ptr<Plugin> plugin = fx->plugin ();
Gtk::Menu* acm = manage (new Gtk::Menu);
MenuList& acm_items (acm->items ());
for (size_t i = 0; i < plugin->parameter_count (); ++i) {
if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) {
continue;
}
const Evoral::Parameter param (PluginAutomation, 0, i);
std::string label = plugin->describe_parameter (param);
if (label == X_("latency") || label == X_("hidden")) {
continue;
}
std::shared_ptr<ARDOUR::AutomationControl> c (std::dynamic_pointer_cast<ARDOUR::AutomationControl> (fx->control (param)));
if (c && c->flags () & (Controllable::HiddenControl | Controllable::NotAutomatable)) {
continue;
}
bool active = fx->id () == rfx_id && param_id == i;
acm_items.push_back (RadioMenuElem (grp, label));
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&acm_items.back ());
cmi->set_active (active);
cmi->signal_activate ().connect ([cmi, arv, nth, i] () { if (cmi->get_active ()) {arv->set_region_fx_line (nth, i); }});
if (active) {
active_text = fx->name () + ": " + label;
}
}
if (!acm_items.empty ()) {
rm_items.push_back (MenuElem (fx->name (), *acm));
} else {
delete acm;
}
++nth;
});
if (rm_items.size () > 1) {
_show_on_touch.set_sensitive (true);
} else {
_show_on_touch.set_active (false);
_show_on_touch.set_sensitive (false);
}
_region_line.set_text (active_text);
_arv->set_ignore_line_change (false);
}
void
AudioRegionEditor::on_unmap ()
{
_show_on_touch.set_active (false);
ArdourDialog::on_unmap ();
}

View File

@ -37,6 +37,7 @@
#include <gtkmm/separator.h>
#include <gtkmm/spinbutton.h>
#include "widgets/ardour_dropdown.h"
#include "pbd/signals.h"
#include "pbd/crossthread.h"
@ -55,18 +56,25 @@ class AudioRegionView;
class AudioRegionEditor : public RegionEditor
{
public:
AudioRegionEditor (ARDOUR::Session*, std::shared_ptr<ARDOUR::AudioRegion>);
AudioRegionEditor (ARDOUR::Session*, AudioRegionView*);
~AudioRegionEditor ();
void peak_amplitude_thread ();
void on_unmap ();
private:
void region_changed (PBD::PropertyChange const &);
void region_fx_changed ();
void gain_changed ();
void gain_adjustment_changed ();
void refill_region_line ();
void show_on_touch_changed ();
void show_touched_automation (std::weak_ptr<PBD::Controllable>);
AudioRegionView* _arv;
std::shared_ptr<ARDOUR::AudioRegion> _audio_region;
Gtk::Label gain_label;
@ -79,6 +87,12 @@ private:
Gtk::Label _peak_amplitude_label;
Gtk::Entry _peak_amplitude;
Gtk::Label _region_line_label;
ArdourWidgets::ArdourDropdown _region_line;
Gtk::CheckButton _show_on_touch;
PBD::ScopedConnection _ctrl_touched_connection;
void signal_peak_thread ();
pthread_t _peak_amplitude_thread_handle;
void peak_amplitude_found (double);

View File

@ -36,6 +36,7 @@
#include "ardour/audioregion.h"
#include "ardour/audiosource.h"
#include "ardour/profile.h"
#include "ardour/region_fx_plugin.h"
#include "ardour/session.h"
#include "pbd/memento_command.h"
@ -112,8 +113,7 @@ static Cairo::RefPtr<Cairo::Pattern> create_pending_peak_pattern() {
return p;
}
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, std::shared_ptr<AudioRegion> r, double spu,
uint32_t basic_color)
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, std::shared_ptr<AudioRegion> r, double spu, uint32_t basic_color)
: RegionView (parent, tv, r, spu, basic_color)
, fade_in_handle(0)
, fade_out_handle(0)
@ -129,6 +129,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
, _amplitude_above_axis(1.0)
, trim_fade_in_drag_active(false)
, trim_fade_out_drag_active(false)
, _rfx_id (0)
, _rdx_param (UINT32_MAX)
, _ignore_line_change (false)
{
}
@ -149,6 +152,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
, _amplitude_above_axis(1.0)
, trim_fade_in_drag_active(false)
, trim_fade_out_drag_active(false)
, _rfx_id (0)
, _rdx_param (UINT32_MAX)
, _ignore_line_change (false)
{
}
@ -168,6 +174,9 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, std::shared_ptr<
, _amplitude_above_axis (other._amplitude_above_axis)
, trim_fade_in_drag_active(false)
, trim_fade_out_drag_active(false)
, _rfx_id (0)
, _rdx_param (UINT32_MAX)
, _ignore_line_change (false)
{
init (true);
}
@ -196,7 +205,7 @@ AudioRegionView::init (bool wfd)
create_waves ();
if (!_recregion) {
if (!_recregion && !Profile->get_livetrax()) {
fade_in_handle = new ArdourCanvas::Rectangle (group);
CANVAS_DEBUG_NAME (fade_in_handle, string_compose ("fade in handle for %1", region()->name()));
fade_in_handle->set_outline_color (Gtkmm2ext::rgba_to_color (0, 0, 0, 1.0));
@ -232,12 +241,7 @@ AudioRegionView::init (bool wfd)
set_fade_visibility (false);
}
const string line_name = _region->name() + ":gain";
gain_line.reset (new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope()));
update_envelope_visibility ();
gain_line->reset ();
set_region_gain_line ();
/* streamview will call set_height() */
//set_height (trackview.current_height()); // XXX not correct for Layered mode, but set_height() will fix later.
@ -277,8 +281,10 @@ AudioRegionView::init (bool wfd)
setup_waveform_visibility ();
get_canvas_frame()->set_data ("linemerger", (LineMerger*) this);
gain_line->canvas_group().raise_to_top ();
if (_fx_line) {
get_canvas_frame()->set_data ("linemerger", (LineMerger*) this);
_fx_line->canvas_group().raise_to_top ();
}
/* XXX sync mark drag? */
}
@ -606,15 +612,15 @@ AudioRegionView::set_height (gdouble height)
}
}
if (gain_line) {
if (_fx_line) {
if ((height / nchans) < NAME_HIGHLIGHT_THRESH) {
gain_line->hide ();
_fx_line->hide ();
} else {
update_envelope_visibility ();
}
gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE) - 2);
_fx_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE) - 2);
}
reset_fade_shapes ();
@ -1081,8 +1087,8 @@ AudioRegionView::set_samples_per_pixel (gdouble fpp)
}
}
if (gain_line) {
gain_line->reset ();
if (_fx_line) {
_fx_line->reset ();
}
reset_fade_shapes ();
@ -1101,12 +1107,9 @@ AudioRegionView::set_colors ()
{
RegionView::set_colors();
if (gain_line) {
gain_line->set_line_color (audio_region()->envelope_active() ?
UIConfiguration::instance().color ("gain line") :
UIConfiguration::instance().color_mod ("gain line inactive", "gain line inactive"));
}
assert (_fx_line);
set_fx_line_colors ();
set_waveform_colors ();
if (start_xfade_curve) {
@ -1148,8 +1151,8 @@ AudioRegionView::setup_waveform_visibility ()
void
AudioRegionView::temporarily_hide_envelope ()
{
if (gain_line) {
gain_line->hide ();
if (_fx_line) {
_fx_line->hide ();
}
}
@ -1160,20 +1163,122 @@ AudioRegionView::unhide_envelope ()
}
void
AudioRegionView::update_envelope_visibility ()
AudioRegionView::set_region_gain_line ()
{
if (!gain_line) {
if (Profile->get_livetrax()) {
return;
}
if (_ignore_line_change) {
return;
}
const string line_name = _region->name() + ":gain";
_fx_line.reset (new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope()));
_fx_line->set_height ((uint32_t) rint (height() - NAME_HIGHLIGHT_SIZE) - 2);
_fx_line->reset ();
_region_fx_connection.disconnect ();
bool changed = _rfx_id != PBD::ID (0) || _rdx_param != UINT32_MAX;
_rfx_id = PBD::ID (0);
_rdx_param = UINT32_MAX;
envelope_active_changed ();
if (changed) {
region_line_changed (); /* EMIT SIGNAL */
}
}
void
AudioRegionView::set_region_fx_line (std::shared_ptr<AutomationControl> ac, std::shared_ptr<RegionFxPlugin> rfx, uint32_t param_id)
{
const string line_name = _region->name () + ":" + rfx->describe_parameter (Evoral::Parameter (PluginAutomation, 0, param_id));
_fx_line.reset (new RegionFxLine (line_name, *this, *group, ac));
_fx_line->set_height ((uint32_t) rint (height() - NAME_HIGHLIGHT_SIZE) - 2);
_fx_line->reset ();
rfx->DropReferences.connect (_region_fx_connection, invalidator (*this), boost::bind (&AudioRegionView::set_region_gain_line, this), gui_context ());
bool changed = _rfx_id != rfx->id () || _rdx_param != param_id;
_rfx_id = rfx->id ();
_rdx_param = param_id;
envelope_active_changed ();
if (changed) {
region_line_changed (); /* EMIT SIGNAL */
}
}
bool
AudioRegionView::set_region_fx_line (uint32_t plugin_id, uint32_t param_id)
{
if (_ignore_line_change) {
return false;
}
std::shared_ptr<RegionFxPlugin> rfx = _region->nth_plugin (plugin_id);
if (rfx) {
std::shared_ptr<Evoral::Control> c = rfx->control (Evoral::Parameter (PluginAutomation, 0, param_id));
std::shared_ptr<AutomationControl> ac = std::dynamic_pointer_cast<AutomationControl> (c);
if (ac) {
set_region_fx_line (ac, rfx, param_id);
return true;
}
}
return false;
}
bool
AudioRegionView::set_region_fx_line (std::weak_ptr<PBD::Controllable> wac)
{
if (_ignore_line_change) {
return false;
}
std::shared_ptr<AutomationControl> ac = std::dynamic_pointer_cast<AutomationControl> (wac.lock ());
if (!ac) {
return false;
}
bool found = false;
_region->foreach_plugin ([this, ac, &found](std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> rfx (wfx.lock ());
if (!rfx || found) {
return;
}
std::shared_ptr<Plugin> plugin = rfx->plugin ();
for (size_t i = 0; i < plugin->parameter_count (); ++i) {
if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) {
continue;
}
const Evoral::Parameter param (PluginAutomation, 0, i);
if (ac == std::dynamic_pointer_cast<ARDOUR::AutomationControl> (rfx->control (param))) {
set_region_fx_line (ac, rfx, i);
found = true;
break;
}
}
});
return found;
}
bool
AudioRegionView::get_region_fx_line (PBD::ID& id, uint32_t& param_id)
{
id = _rfx_id;
param_id = _rdx_param;
return _rdx_param != UINT32_MAX && _rfx_id != 0;
}
void
AudioRegionView::update_envelope_visibility ()
{
assert (_fx_line);
if (trackview.editor().current_mouse_mode() == Editing::MouseDraw || trackview.editor().current_mouse_mode() == Editing::MouseContent ) {
gain_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::ControlPoints|AutomationLine::Line));
gain_line->canvas_group().raise_to_top ();
_fx_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::ControlPoints|AutomationLine::Line));
_fx_line->canvas_group().raise_to_top ();
} else if (UIConfiguration::instance().get_show_region_gain() || trackview.editor().current_mouse_mode() == Editing::MouseRange ) {
gain_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::Line));
gain_line->canvas_group().raise_to_top ();
_fx_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::Line));
_fx_line->canvas_group().raise_to_top ();
} else {
gain_line->set_visibility (AutomationLine::VisibleAspects(0));
_fx_line->set_visibility (AutomationLine::VisibleAspects(0));
}
}
@ -1374,7 +1479,7 @@ AudioRegionView::peaks_ready_handler (uint32_t which)
void
AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, bool with_guard_points)
{
if (!gain_line) {
if (!_fx_line) {
return;
}
@ -1386,18 +1491,17 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
samplecnt_t const sample_within_region = (samplecnt_t) floor (mx * samples_per_pixel);
if (!gain_line->control_points_adjacent (sample_within_region, before_p, after_p)) {
/* no adjacent points */
return;
double y = my;
if (_fx_line->control_points_adjacent (sample_within_region, before_p, after_p)) {
/* y is in item frame */
double const bx = _fx_line->nth (before_p)->get_x();
double const ax = _fx_line->nth (after_p)->get_x();
double const click_ratio = (ax - mx) / (ax - bx);
y = ((_fx_line->nth (before_p)->get_y() * click_ratio) + (_fx_line->nth (after_p)->get_y() * (1 - click_ratio)));
}
/* y is in item frame */
double const bx = gain_line->nth (before_p)->get_x();
double const ax = gain_line->nth (after_p)->get_x();
double const click_ratio = (ax - mx) / (ax - bx);
double y = ((gain_line->nth (before_p)->get_y() * click_ratio) + (gain_line->nth (after_p)->get_y() * (1 - click_ratio)));
/* don't create points that can't be seen */
update_envelope_visibility ();
@ -1412,55 +1516,37 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
/* compute vertical fractional position */
y = 1.0 - (y / (gain_line->height()));
y = 1.0 - (y / (_fx_line->height()));
/* map using gain line */
gain_line->view_to_model_coord_y (y);
_fx_line->view_to_model_coord_y (y);
/* XXX STATEFUL: can't convert to stateful diff until we
can represent automation data with it.
*/
XMLNode &before = audio_region()->envelope()->get_state();
MementoCommand<AudioRegion>* region_memento = 0;
if (!audio_region()->envelope_active()) {
XMLNode &region_before = audio_region()->get_state();
audio_region()->set_envelope_active(true);
XMLNode &region_after = audio_region()->get_state();
region_memento = new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after);
}
if (audio_region()->envelope()->editor_add (timepos_t (fx), y, with_guard_points)) {
XMLNode &after = audio_region()->envelope()->get_state();
XMLNode &before = _fx_line->the_list()->get_state();
if (_fx_line->the_list()->editor_add (timepos_t (fx), y, with_guard_points)) {
XMLNode &after = _fx_line->the_list()->get_state();
std::list<Selectable*> results;
trackview.editor().begin_reversible_command (_("add gain control point"));
if (region_memento) {
trackview.session()->add_command (region_memento);
}
_fx_line->enable_autoation ();
trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
trackview.session()->add_command (new MementoCommand<AutomationList>(*_fx_line->the_list(), &before, &after));
gain_line->get_selectables (region ()->position () + timecnt_t (fx), region ()->position () + timecnt_t (fx), 0.0, 1.0, results);
_fx_line->get_selectables (region ()->position () + timecnt_t (fx), region ()->position () + timecnt_t (fx), 0.0, 1.0, results);
trackview.editor ().get_selection ().set (results);
trackview.editor ().commit_reversible_command ();
trackview.session ()->set_dirty ();
} else {
delete region_memento;
delete &before;
}
}
void
AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent* /*ev*/)
{
ControlPoint *cp = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"));
audio_region()->envelope()->erase (cp->model());
}
GhostRegion*
AudioRegionView::add_ghost (TimeAxisView& tv)
{
@ -1557,10 +1643,6 @@ AudioRegionView::exited ()
trackview.editor().set_current_trimmable (std::shared_ptr<Trimmable>());
trackview.editor().set_current_movable (std::shared_ptr<Movable>());
// if (gain_line) {
// gain_line->remove_visibility (AutomationLine::ControlPoints);
// }
if (fade_in_handle) { fade_in_handle->hide(); }
if (fade_out_handle) { fade_out_handle->hide(); }
if (fade_in_trim_handle) { fade_in_trim_handle->hide(); }
@ -1572,12 +1654,8 @@ AudioRegionView::exited ()
void
AudioRegionView::envelope_active_changed ()
{
if (gain_line) {
gain_line->set_line_color (audio_region()->envelope_active() ?
UIConfiguration::instance().color ("gain line") :
UIConfiguration::instance().color_mod ("gain line inactive", "gain line inactive"));
update_envelope_visibility ();
}
set_fx_line_colors ();
update_envelope_visibility ();
}
void
@ -1595,6 +1673,20 @@ AudioRegionView::color_handler ()
}
void
AudioRegionView::set_fx_line_colors ()
{
assert (_fx_line);
if (_rdx_param != UINT32_MAX && _rfx_id != 0) {
_fx_line->set_line_color ("region automation line");
} else if (audio_region()->envelope_active()) {
_fx_line->set_line_color ("gain line");
} else {
_fx_line->set_line_color ("gain line inactive", "gain line inactive");
}
}
void
AudioRegionView::set_waveform_colors ()
{
@ -1665,7 +1757,7 @@ AudioRegionView::set_fade_visibility (bool yn)
if (end_xfade_curve) { end_xfade_curve->show (); }
if (start_xfade_rect) { start_xfade_rect->show (); }
if (end_xfade_rect) { end_xfade_rect->show (); }
} else {
} else {
if (start_xfade_curve) { start_xfade_curve->hide(); }
if (end_xfade_curve) { end_xfade_curve->hide(); }
if (fade_in_handle) { fade_in_handle->hide(); }
@ -1696,7 +1788,7 @@ void
AudioRegionView::show_region_editor ()
{
if (editor == 0) {
editor = new AudioRegionEditor (trackview.session(), audio_region());
editor = new AudioRegionEditor (trackview.session(), this);
}
editor->present ();
@ -1858,7 +1950,7 @@ AudioRegionView::parameter_changed (string const & p)
MergeableLine*
AudioRegionView::make_merger ()
{
return new MergeableLine (gain_line, std::shared_ptr<AutomationControl>(),
return new MergeableLine (_fx_line, std::shared_ptr<AutomationControl>(),
[this](timepos_t const& t) { return timepos_t (_region->position().distance (t)); },
nullptr, nullptr);
}

View File

@ -50,9 +50,9 @@ namespace ARDOUR {
};
class AudioTimeAxisView;
class AudioRegionGainLine;
class GhostRegion;
class AutomationTimeAxisView;
class RegionFxLine;
class RouteTimeAxisView;
class AudioRegionView : public RegionView, public LineMerger
@ -91,12 +91,18 @@ public:
void temporarily_hide_envelope (); ///< Dangerous!
void unhide_envelope (); ///< Dangerous!
void set_region_gain_line ();
void set_ignore_line_change (bool v) { _ignore_line_change = v; };
bool set_region_fx_line (uint32_t, uint32_t);
bool set_region_fx_line (std::weak_ptr<PBD::Controllable>);
bool get_region_fx_line (PBD::ID&, uint32_t&);
void update_envelope_visibility ();
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event, bool with_guard_points);
void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
sigc::signal<void> region_line_changed;
std::shared_ptr<AudioRegionGainLine> get_gain_line() const { return gain_line; }
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event, bool with_guard_points);
std::shared_ptr<RegionFxLine> fx_line() const { return _fx_line; }
void region_changed (const PBD::PropertyChange&);
void envelope_active_changed ();
@ -184,7 +190,7 @@ protected:
ArdourCanvas::Rectangle* end_xfade_rect;
bool _end_xfade_visible;
std::shared_ptr<AudioRegionGainLine> gain_line;
std::shared_ptr<RegionFxLine> _fx_line;
double _amplitude_above_axis;
@ -206,6 +212,7 @@ protected:
void set_colors ();
void set_waveform_colors ();
void set_fx_line_colors ();
void reset_width_dependent_items (double pixel_width);
void color_handler ();
@ -234,6 +241,14 @@ private:
bool trim_fade_in_drag_active;
bool trim_fade_out_drag_active;
void set_region_fx_line (std::shared_ptr<ARDOUR::AutomationControl>, std::shared_ptr<ARDOUR::RegionFxPlugin>, uint32_t);
PBD::ID _rfx_id;
uint32_t _rdx_param;
bool _ignore_line_change;
PBD::ScopedConnection _region_fx_connection;
};
#endif /* __gtk_ardour_audio_region_view_h__ */

View File

@ -470,8 +470,8 @@ AudioStreamView::set_selected_points (PointSelection& points)
{
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv && arv->get_gain_line ()) {
arv->get_gain_line ()->set_selected_points (points);
if (arv && arv->fx_line ()) {
arv->fx_line ()->set_selected_points (points);
}
}
}

View File

@ -87,11 +87,12 @@ using namespace Temporal;
AutomationLine::AutomationLine (const string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
std::shared_ptr<AutomationList> al,
std::shared_ptr<AutomationList> al,
const ParameterDescriptor& desc)
: trackview (tv)
, _name (name)
, _height (0)
, _line_color ("automation line")
, _view_index_offset (0)
, alist (al)
, _visible (Line)
@ -264,14 +265,23 @@ AutomationLine::set_height (guint32 h)
}
void
AutomationLine::set_line_color (uint32_t color)
AutomationLine::set_line_color (string color_name, std::string color_mod)
{
_line_color = color;
_line_color = color_name;
_line_color_mod = color_mod;
uint32_t color = UIConfiguration::instance().color (color_name);
line->set_outline_color (color);
Gtkmm2ext::SVAModifier mod = UIConfiguration::instance().modifier ("automation line fill");
Gtkmm2ext::SVAModifier mod = UIConfiguration::instance().modifier (color_mod.empty () ? "automation line fill" : color_mod);
line->set_fill_color ((color & 0xffffff00) + mod.a()*255);
line->set_fill_color ((color & 0xffffff00) + mod.a() * 255);
}
uint32_t
AutomationLine::get_line_color() const
{
return UIConfiguration::instance().color (_line_color);
}
ControlPoint*
@ -996,7 +1006,7 @@ AutomationLine::set_selected_points (PointSelection const & points)
void
AutomationLine::set_colors ()
{
set_line_color (UIConfiguration::instance().color ("automation line"));
set_line_color (_line_color, _line_color_mod);
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->set_color ();
}

View File

@ -68,7 +68,7 @@ public:
AutomationLine (const std::string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
std::shared_ptr<ARDOUR::AutomationList> al,
std::shared_ptr<ARDOUR::AutomationList> al,
const ARDOUR::ParameterDescriptor& desc);
@ -94,6 +94,7 @@ public:
virtual void start_drag_multiple (std::list<ControlPoint*>, float, XMLNode *);
virtual std::pair<float, float> drag_motion (Temporal::timecnt_t const &, float, bool, bool with_push, uint32_t& final_index);
virtual void end_drag (bool with_push, uint32_t final_index);
virtual void end_draw_merge () {}
ControlPoint* nth (uint32_t);
ControlPoint const * nth (uint32_t) const;
@ -103,8 +104,8 @@ public:
bool visible() const { return _visible != VisibleAspects(0); }
guint32 height() const { return _height; }
void set_line_color (uint32_t);
uint32_t get_line_color() const { return _line_color; }
void set_line_color (std::string color, std::string mod = "");
uint32_t get_line_color() const;
void set_visibility (VisibleAspects);
void add_visibility (VisibleAspects);
@ -173,7 +174,8 @@ protected:
std::string _name;
guint32 _height;
uint32_t _line_color;
std::string _line_color;
std::string _line_color_mod;
uint32_t _view_index_offset;
std::shared_ptr<ARDOUR::AutomationList> alist;
@ -247,6 +249,7 @@ private:
const ARDOUR::ParameterDescriptor _desc;
friend class AudioRegionGainLine;
friend class RegionFxLine;
};
#endif /* __ardour_automation_line_h__ */

View File

@ -350,7 +350,7 @@ AutomationTimeAxisView::add_contents (bool show_regions)
)
);
line->set_line_color (UIConfiguration::instance().color ("processor automation line"));
line->set_line_color ("processor automation line");
line->set_fill (true);
line->queue_reset ();
add_line (line);

View File

@ -343,20 +343,20 @@ Editor::Editor ()
, cd_mark_label (_("CD Markers"))
, section_mark_label (_("Arrangement"))
, cue_mark_label (_("Cue Markers"))
, scene_mark_label (_("Scenes"))
, videotl_label (_("Video Timeline"))
, videotl_group (0)
, _region_boundary_cache_dirty (true)
, edit_packer (4, 4, true)
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
, unused_adjustment (0.0, 0.0, 10.0, 400.0)
, controls_layout (unused_adjustment, vertical_adjustment)
, _scroll_callbacks (0)
, _visible_canvas_width (0)
, _visible_canvas_height (0)
, _full_canvas_height (0)
, edit_controls_left_menu (0)
, edit_controls_right_menu (0)
, edit_controls_left_menu (nullptr)
, edit_controls_right_menu (nullptr)
, _trigger_clip_picker (nullptr)
, visual_change_queued(false)
, _tvl_no_redisplay(false)
, _tvl_redisplay_on_resume(false)
@ -576,6 +576,13 @@ Editor::Editor ()
cue_mark_label.hide();
cue_mark_label.set_no_show_all();
scene_mark_label.set_name ("EditorRulerLabel");
scene_mark_label.set_size_request (-1, (int)timebar_height);
scene_mark_label.set_alignment (1.0, 0.5);
scene_mark_label.set_padding (5,0);
scene_mark_label.hide();
scene_mark_label.set_no_show_all();
videotl_bar_height = 4;
videotl_label.set_name ("EditorRulerLabel");
videotl_label.set_size_request (-1, (int)timebar_height * videotl_bar_height);
@ -602,7 +609,9 @@ Editor::Editor ()
CairoWidget::set_focus_handler (sigc::mem_fun (ARDOUR_UI::instance(), &ARDOUR_UI::reset_focus));
_summary = new EditorSummary (this);
if (!Profile->get_livetrax()) {
_summary = new EditorSummary (this);
}
TempoMap::MapChanged.connect (tempo_map_connection, invalidator (*this), boost::bind (&Editor::tempo_map_changed, this), gui_context());
@ -706,20 +715,27 @@ Editor::Editor ()
add_notebook_page (_("Selection"), *_properties_box);
#warning Fix Properties Sidebar Layout to fit < 720px height
#endif
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 ());
if (!Profile->get_livetrax()) {
_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 ();
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;
@ -732,93 +748,104 @@ Editor::Editor ()
settings->get_property ("notebook-shrunk", _notebook_shrunk);
}
editor_summary_pane.set_check_divider_position (true);
editor_summary_pane.add (edit_packer);
if (!Profile->get_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_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));
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_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);
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);
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_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);
_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);
edit_pane.set_check_divider_position (true);
edit_pane.add (editor_summary_pane);
_editor_list_vbox.pack_start (_the_notebook);
_editor_list_vbox.pack_start (*_properties_box, false, false, 0);
edit_pane.add (_editor_list_vbox);
edit_pane.set_child_minsize (_editor_list_vbox, 30); /* rough guess at width of notebook tabs */
editor_summary_pane.add (_summary_hbox);
edit_pane.set_check_divider_position (true);
edit_pane.add (editor_summary_pane);
_editor_list_vbox.pack_start (_the_notebook);
_editor_list_vbox.pack_start (*_properties_box, false, false, 0);
edit_pane.add (_editor_list_vbox);
edit_pane.set_child_minsize (_editor_list_vbox, 30); /* rough guess at width of notebook tabs */
edit_pane.set_drag_cursor (*_cursors->expand_left_right);
editor_summary_pane.set_drag_cursor (*_cursors->expand_up_down);
edit_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-horizontal-pane-pos", fract) || fract > 1.0) {
/* initial allocation is 90% to canvas, 10% to notebook */
fract = 0.90;
float fract;
if (!settings || !settings->get_property ("edit-horizontal-pane-pos", fract) || fract > 1.0) {
/* initial allocation is 90% to canvas, 10% to notebook */
fract = 0.90;
}
edit_pane.set_divider (0, 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);
}
edit_pane.set_divider (0, 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);
global_vpacker.set_spacing (0);
global_vpacker.set_border_width (0);
/* the next three EventBoxes provide the ability for their child widgets to have a background color. That is all. */
if (!Profile->get_livetrax()) {
/* the next three EventBoxes provide the ability for their child widgets to have a background color. That is all. */
Gtk::EventBox* ebox = manage (new Gtk::EventBox); // a themeable box
ebox->set_name("EditorWindow");
ebox->add (ebox_hpacker);
Gtk::EventBox* ebox = manage (new Gtk::EventBox); // a themeable box
ebox->set_name("EditorWindow");
ebox->add (ebox_hpacker);
Gtk::EventBox* epane_box = manage (new EventBoxExt); // a themeable box
epane_box->set_name("EditorWindow");
epane_box->add (edit_pane);
Gtk::EventBox* epane_box = manage (new EventBoxExt); // a themeable box
epane_box->set_name("EditorWindow");
epane_box->add (edit_pane);
Gtk::EventBox* epane_box2 = manage (new EventBoxExt); // a themeable box
epane_box2->set_name("EditorWindow");
epane_box2->add (global_vpacker);
Gtk::EventBox* epane_box2 = manage (new EventBoxExt); // a themeable box
epane_box2->set_name("EditorWindow");
epane_box2->add (global_vpacker);
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();
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 (*toolbar_shadow, false, false);
global_vpacker.pack_start (*ebox, false, false);
global_vpacker.pack_start (*epane_box, true, true);
global_hpacker.pack_start (*epane_box2, true, true);
global_vpacker.pack_start (*ebox, false, false);
/* need to show the "contents" widget so that notebook will show if tab is switched to
*/
if (!Profile->get_livetrax()) {
global_vpacker.pack_start (*epane_box, true, true);
global_hpacker.pack_start (*epane_box2, true, true);
}
/* need to show the "contents" widget so that notebook will show if tab is switched to
*/
global_hpacker.show ();
ebox_hpacker.show();
ebox->show();
global_hpacker.show ();
ebox_hpacker.show();
ebox->show();
} else {
global_vpacker.pack_start (edit_packer, true, true);
global_hpacker.pack_start (global_vpacker, true, true);
global_hpacker.show ();
}
/* register actions now so that set_state() can find them and set toggles/checks etc */
@ -1340,7 +1367,10 @@ void
Editor::set_session (Session *t)
{
SessionHandlePtr::set_session (t);
_trigger_clip_picker.set_session (_session);
if (_trigger_clip_picker) {
_trigger_clip_picker->set_session (_session);
}
section_marker_bar->clear (true);
@ -1353,16 +1383,19 @@ Editor::set_session (Session *t)
* before the visible state has been loaded from instant.xml */
_leftmost_sample = session_gui_extents().first.samples();
nudge_clock->set_session (_session);
_summary->set_session (_session);
if (!Profile->get_livetrax()) {
nudge_clock->set_session (_session);
_summary->set_session (_session);
}
_group_tabs->set_session (_session);
_route_groups->set_session (_session);
_regions->set_session (_session);
_sources->set_session (_session);
_snapshots->set_session (_session);
_sections->set_session (_session);
_routes->set_session (_session);
_locations->set_session (_session);
_sections->set_session (_session);
_properties_box->set_session (_session);
if (rhythm_ferret) {
@ -2503,7 +2536,9 @@ Editor::set_state (const XMLNode& node, int version)
PBD::Unwinder<bool> nsi (no_save_instant, true);
bool yn;
Tabbable::set_state (node, version);
if (!Profile->get_livetrax()) {
Tabbable::set_state (node, version);
}
samplepos_t ph_pos;
if (_session && node.get_property ("playhead", ph_pos)) {
@ -2721,7 +2756,9 @@ Editor::get_state () const
node->set_property ("id", id().to_s ());
node->add_child_nocopy (Tabbable::get_state());
if (!Profile->get_livetrax()) {
node->add_child_nocopy (Tabbable::get_state());
}
node->set_property("edit-horizontal-pane-pos", edit_pane.get_divider ());
node->set_property("notebook-shrunk", _notebook_shrunk);
@ -3292,7 +3329,7 @@ Editor::setup_toolbar ()
mode_box->set_spacing(2);
HBox* mouse_mode_box = manage (new HBox);
HBox* mouse_mode_hbox = manage (new HBox);
mouse_mode_hbox = manage (new HBox);
VBox* mouse_mode_vbox = manage (new VBox);
Alignment* mouse_mode_align = manage (new Alignment);
@ -3335,19 +3372,26 @@ Editor::setup_toolbar ()
mouse_mode_size_group->add_widget (nudge_backward_button);
mouse_mode_hbox->set_spacing (2);
mouse_mode_hbox->pack_start (smart_mode_button, false, false);
if (!Profile->get_livetrax()) {
mouse_mode_hbox->pack_start (smart_mode_button, false, false);
}
mouse_mode_hbox->pack_start (mouse_move_button, false, false);
mouse_mode_hbox->pack_start (mouse_select_button, false, false);
mouse_mode_hbox->pack_start (mouse_cut_button, false, false);
mouse_mode_hbox->pack_start (mouse_timefx_button, false, false);
mouse_mode_hbox->pack_start (mouse_grid_button, false, false);
mouse_mode_hbox->pack_start (mouse_draw_button, false, false);
mouse_mode_hbox->pack_start (mouse_content_button, false, false);
mouse_mode_vbox->pack_start (*mouse_mode_hbox);
if (!Profile->get_livetrax()) {
mouse_mode_hbox->pack_start (mouse_timefx_button, false, false);
mouse_mode_hbox->pack_start (mouse_grid_button, false, false);
mouse_mode_hbox->pack_start (mouse_draw_button, false, false);
mouse_mode_hbox->pack_start (mouse_content_button, false, false);
}
if (!Profile->get_livetrax()) {
mouse_mode_vbox->pack_start (*mouse_mode_hbox);
}
mouse_mode_align->add (*mouse_mode_vbox);
mouse_mode_align->set (0.5, 1.0, 0.0, 0.0);
@ -3363,7 +3407,9 @@ Editor::setup_toolbar ()
mode_box->pack_start (edit_point_selector, false, false);
mode_box->pack_start (*(manage (new ArdourVSpacer ())), false, false, 3);
mode_box->pack_start (*mouse_mode_box, false, false);
if (!Profile->get_livetrax()) {
mode_box->pack_start (*mouse_mode_box, false, false);
}
/* Zoom */
@ -3516,7 +3562,9 @@ Editor::setup_toolbar ()
toolbar_hbox.pack_start (grid_box, false, false);
toolbar_hbox.pack_start (_draw_box_spacer, false, false, 3);
toolbar_hbox.pack_start (draw_box, false, false);
toolbar_hbox.pack_end (_zoom_box, false, false, 2);
if (!Profile->get_livetrax()) {
toolbar_hbox.pack_end (_zoom_box, false, false, 2);
}
toolbar_hbox.pack_end (*(manage (new ArdourVSpacer ())), false, false, 3);
toolbar_hbox.pack_end (_track_box, false, false);
@ -5098,7 +5146,9 @@ Editor::on_samples_per_pixel_changed ()
}
refresh_location_display();
_summary->set_overlays_dirty ();
if (_summary) {
_summary->set_overlays_dirty ();
}
update_section_box ();
update_marker_labels ();
@ -5237,7 +5287,9 @@ Editor::visual_changer (const VisualChange& vc)
}
_region_peak_cursor->hide ();
_summary->set_overlays_dirty ();
if (_summary) {
_summary->set_overlays_dirty ();
}
}
struct EditorOrderTimeAxisSorter {
@ -5809,7 +5861,9 @@ Editor::region_view_added (RegionView * rv)
}
}
_summary->set_background_dirty ();
if (_summary) {
_summary->set_background_dirty ();
}
mark_region_boundary_cache_dirty ();
}
@ -5817,7 +5871,9 @@ Editor::region_view_added (RegionView * rv)
void
Editor::region_view_removed ()
{
_summary->set_background_dirty ();
if (_summary) {
_summary->set_background_dirty ();
}
mark_region_boundary_cache_dirty ();
}
@ -6216,7 +6272,9 @@ Editor::redisplay_track_views ()
vertical_adjustment.set_value (_full_canvas_height - _visible_canvas_height);
}
_summary->set_background_dirty();
if (_summary) {
_summary->set_background_dirty();
}
_group_tabs->set_dirty ();
return false;

View File

@ -632,6 +632,8 @@ public:
void remove_region_marker (ARDOUR::CueMarker&);
void make_region_markers_global (bool as_cd_markers);
SelectionPropertiesBox& properties_box() const { return *_properties_box; }
protected:
void map_transport_state ();
void map_position_change (samplepos_t);
@ -939,6 +941,7 @@ private:
ArdourCanvas::Container* cd_marker_group;
ArdourCanvas::Container* section_marker_group;
ArdourCanvas::Container* cue_marker_group;
ArdourCanvas::Container* scene_marker_group;
/* parent for groups which themselves contain time markers */
ArdourCanvas::Container* _time_markers_group;
@ -992,6 +995,7 @@ private:
Glib::RefPtr<Gtk::ToggleAction> ruler_section_action;
Glib::RefPtr<Gtk::ToggleAction> ruler_marker_action;
Glib::RefPtr<Gtk::ToggleAction> ruler_cue_marker_action;
Glib::RefPtr<Gtk::ToggleAction> ruler_scene_marker_action;
bool no_ruler_shown_update;
Gtk::Widget* ruler_grabbed_widget;
@ -1083,6 +1087,7 @@ private:
ArdourCanvas::Rectangle* cd_marker_bar;
ArdourCanvas::Rectangle* section_marker_bar;
ArdourCanvas::Rectangle* cue_marker_bar;
ArdourCanvas::Rectangle* scene_marker_bar;
ArdourCanvas::Line* ruler_separator;
void toggle_cue_behavior ();
@ -1099,6 +1104,7 @@ private:
Gtk::Label cd_mark_label;
Gtk::Label section_mark_label;
Gtk::Label cue_mark_label;
Gtk::Label scene_mark_label;
/* videtimline related actions */
Gtk::Label videotl_label;
@ -1167,10 +1173,6 @@ private:
Gtk::Table edit_packer;
/** the adjustment that controls the overall editor vertical scroll position */
Gtk::Adjustment vertical_adjustment;
Gtk::Adjustment horizontal_adjustment;
Gtk::Adjustment unused_adjustment; // yes, really; Gtk::Layout constructor requires refs
Gtk::Layout controls_layout;
bool control_layout_scroll (GdkEventScroll* ev);
@ -1203,7 +1205,7 @@ private:
Gtk::VBox edit_controls_vbox;
Gtk::HBox edit_controls_hbox;
TriggerClipPicker _trigger_clip_picker;
TriggerClipPicker* _trigger_clip_picker;
void control_vertical_zoom_in_all ();
void control_vertical_zoom_out_all ();
@ -1318,7 +1320,7 @@ private:
void register_actions ();
void register_region_actions ();
void register_midi_actions (Gtkmm2ext::Bindings*);
void register_midi_actions ();
void load_bindings ();
@ -1593,6 +1595,7 @@ private:
void clear_xrun_markers ();
void clear_ranges ();
void clear_cues ();
void clear_scenes ();
void clear_locations ();
void unhide_markers ();
void unhide_ranges ();
@ -1996,6 +1999,7 @@ private:
void build_edit_mode_menu ();
Gtk::VBox edit_mode_box;
void set_ripple_mode (ARDOUR::RippleMode);
void set_edit_mode (ARDOUR::EditMode);
@ -2071,7 +2075,6 @@ private:
Gtk::HBox _track_box;
Gtk::HBox _zoom_box;
void zoom_adjustment_changed();
void setup_toolbar ();

View File

@ -697,6 +697,7 @@ Editor::register_actions ()
ruler_cd_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-cd-marker-ruler"), _("CD Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_section_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-arrangement-ruler"), _("Arrangement"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-marker-ruler"), _("Location Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_scene_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-scene-marker-ruler"), _("Scene Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_cue_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-cue-marker-ruler"), _("Cue Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ActionManager::register_action (editor_menu_actions, X_("VideoMonitorMenu"), _("Video Monitor"));
@ -727,6 +728,7 @@ Editor::register_actions ()
ruler_cd_marker_action->set_active (true);
ruler_marker_action->set_active (true);
ruler_cue_marker_action->set_active (true);
ruler_scene_marker_action->set_active (false);
ruler_video_action->set_active (false);
xjadeo_proc_action->set_active (false);
@ -790,7 +792,7 @@ Editor::register_actions ()
}
void
Editor::register_midi_actions (Bindings* midi_bindings)
Editor::register_midi_actions ()
{
_midi_actions = ActionManager::create_action_group (midi_bindings, X_("Notes"));
@ -985,7 +987,9 @@ void
Editor::load_bindings ()
{
bindings = Bindings::get_bindings (X_("Editor"));
global_hpacker.set_data ("ardour-bindings", bindings);
midi_bindings = Bindings::get_bindings (X_("MIDI"));
register_midi_actions ();
/* This set of bindings may expand in the future to include things
* other than MIDI editing, but for now this is all we've got as far as
@ -993,11 +997,11 @@ Editor::load_bindings ()
* the keys may overlap.
*/
Bindings* midi_bindings = Bindings::get_bindings (X_("MIDI"));
register_midi_actions (midi_bindings);
_track_canvas_viewport->canvas()->set_data ("ardour-bindings", midi_bindings);
if (!Profile->get_livetrax()) {
global_hpacker.set_data ("ardour-bindings", bindings);
_track_canvas_viewport->canvas()->set_data ("ardour-bindings", midi_bindings);
}
}
void

View File

@ -173,6 +173,8 @@ Editor::initialize_canvas ()
CANVAS_DEBUG_NAME (section_marker_group, "Arranger marker group");
meter_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 5.0) + 1.0));
CANVAS_DEBUG_NAME (meter_group, "meter group");
scene_marker_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 5.0) + 1.0));
CANVAS_DEBUG_NAME (scene_marker_group, "scene marker_group");
float timebar_thickness = timebar_height; //was 4
float timebar_top = (timebar_height - timebar_thickness)/2;
@ -207,6 +209,9 @@ Editor::initialize_canvas ()
cue_marker_bar = new ArdourCanvas::Rectangle (cue_marker_group, ArdourCanvas::Rect (0.0, timebar_top, ArdourCanvas::COORD_MAX, timebar_btm));
CANVAS_DEBUG_NAME (cue_marker_bar, "Cue Marker Bar");
scene_marker_bar = new ArdourCanvas::Rectangle (scene_marker_group, ArdourCanvas::Rect (0.0, timebar_top, ArdourCanvas::COORD_MAX, timebar_btm));
CANVAS_DEBUG_NAME (cue_marker_bar, "Scene Marker Bar");
ruler_separator = new ArdourCanvas::Line(_time_markers_group);
CANVAS_DEBUG_NAME (ruler_separator, "separator between ruler and main canvas");
ruler_separator->set (ArdourCanvas::Duple(0.0, 0.0), ArdourCanvas::Duple(ArdourCanvas::COORD_MAX, 0.0));
@ -256,6 +261,7 @@ Editor::initialize_canvas ()
cd_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), cd_marker_bar, CdMarkerBarItem, "cd marker bar"));
section_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), section_marker_bar, SectionMarkerBarItem, "arrangement marker bar"));
cue_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), cue_marker_bar, CueMarkerBarItem, "cd marker bar"));
scene_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), scene_marker_bar, SceneMarkerBarItem, "scene marker bar"));
videotl_group->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_videotl_bar_event), videotl_group));
range_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), range_marker_bar, RangeMarkerBarItem, "range marker bar"));
transport_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), transport_marker_bar, TransportMarkerBarItem, "transport marker bar"));
@ -367,7 +373,10 @@ Editor::track_canvas_viewport_size_allocated ()
update_tempo_based_rulers ();
redisplay_grid (false);
redisplay_track_views ();
_summary->set_overlays_dirty ();
if (_summary) {
_summary->set_overlays_dirty ();
}
}
void
@ -972,7 +981,7 @@ Editor::entered_track_canvas (GdkEventCrossing* ev)
if (!was_within) {
if (internal_editing()) {
if (internal_editing() || Profile->get_livetrax()) {
/* ensure that key events go here because there are
internal editing bindings associated only with the
canvas. if the focus is elsewhere, we cannot find them.
@ -1046,7 +1055,9 @@ Editor::tie_vertical_scrolling ()
{
if (pending_visual_change.idle_handler_id < 0) {
_region_peak_cursor->hide ();
_summary->set_overlays_dirty ();
if (_summary) {
_summary->set_overlays_dirty ();
}
}
}
@ -1091,6 +1102,9 @@ Editor::color_handler()
section_marker_bar->set_fill_color (UIConfiguration::instance().color_mod ("arrangement marker bar", "marker bar"));
section_marker_bar->set_outline_color (UIConfiguration::instance().color ("marker bar separator"));
scene_marker_bar->set_fill_color (UIConfiguration::instance().color_mod ("arrangement marker bar", "marker bar"));
scene_marker_bar->set_outline_color (UIConfiguration::instance().color ("marker bar separator"));
cue_marker_bar->set_fill_color (UIConfiguration::instance().color_mod ("cd marker bar", "marker bar"));
cue_marker_bar->set_outline_color (UIConfiguration::instance().color ("marker bar separator"));
@ -1498,6 +1512,7 @@ Editor::which_canvas_cursor(ItemType type) const
case CdMarkerBarItem:
case SectionMarkerBarItem:
case CueMarkerBarItem:
case SceneMarkerBarItem:
case VideoBarItem:
case TransportMarkerBarItem:
case DropZoneItem:

View File

@ -707,11 +707,11 @@ bool
Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
{
ItemType type;
AudioRegionGainLine* gl;
if ((gl = dynamic_cast<AudioRegionGainLine*> (al)) != 0) {
RegionFxLine* rfl;
if ((rfl = dynamic_cast<RegionFxLine*> (al)) != 0) {
type = GainLineItem;
if (event->type == GDK_BUTTON_PRESS) {
clicked_regionview = &gl->region_view ();
clicked_regionview = &rfl->region_view ();
}
} else {
type = AutomationLineItem;

View File

@ -5039,7 +5039,7 @@ LineDrag::finished (GdkEvent* event, bool movement_occurred)
AudioRegionView* arv;
if ((arv = dynamic_cast<AudioRegionView*> (_editor->clicked_regionview)) != 0) {
arv->add_gain_point_event (&arv->get_gain_line ()->grab_item (), event, false);
arv->add_gain_point_event (&arv->fx_line ()->grab_item (), event, false);
}
}
}
@ -6367,7 +6367,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list<RegionView*> cons
for (list<RegionView*>::const_iterator i = v.begin (); i != v.end (); ++i) {
if (AudioRegionView* audio_view = dynamic_cast<AudioRegionView*> (*i)) {
lines.push_back (audio_view->get_gain_line ());
lines.push_back (audio_view->fx_line ());
} else if (AutomationRegionView* automation_view = dynamic_cast<AutomationRegionView*> (*i)) {
lines.push_back (automation_view->line ());
_integral = true;
@ -6394,8 +6394,8 @@ AutomationRangeDrag::setup (list<std::shared_ptr<AutomationLine>> const& lines)
/* need a special detection for automation lanes (not region gain line) */
// TODO: if we implement automation regions, this check can probably be removed
AudioRegionGainLine* argl = dynamic_cast<AudioRegionGainLine*> ((*i).get ());
if (!argl) {
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> ((*i).get ());
if (!fxl) {
/* in automation lanes, the EFFECTIVE range should be considered 0->max_position (even if there is no line) */
r.first = Temporal::timepos_t ((*i)->the_list ()->time_domain ());
r.second = Temporal::timepos_t::max ((*i)->the_list ()->time_domain ());
@ -7267,7 +7267,7 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::motion (GdkEvent* ev, bool firs
dragging_line = new ArdourCanvas::PolyLine (parent ? parent : item());
dragging_line->set_ignore_events (true);
dragging_line->set_outline_width (2.0);
dragging_line->set_outline_color (UIConfiguration::instance().color ("automation line"));
dragging_line->set_outline_color (UIConfiguration::instance().color ("automation line")); // XXX -> get color from AutomationLine
dragging_line->raise_to_top ();
/* for freehand drawing, we only support left->right direction, for now. */

View File

@ -27,11 +27,13 @@ enum ItemType {
WaveItem,
PlayheadCursorItem,
MarkerItem,
SceneMarkerItem,
MarkerBarItem,
RangeMarkerBarItem,
CdMarkerBarItem,
SectionMarkerBarItem,
CueMarkerBarItem,
SceneMarkerBarItem,
VideoBarItem,
TransportMarkerBarItem,
SelectionItem,

View File

@ -145,6 +145,8 @@ Editor::add_new_location_internal (Location* location)
color = X_("location loop");
} else if (location->is_auto_punch()) {
color = X_("location punch");
} else if (location->is_scene()) {
color = X_("location scene");
} else {
color = X_("location range");
}
@ -161,6 +163,9 @@ Editor::add_new_location_internal (Location* location)
} else if (location->is_section()) {
lam->start = new ArdourMarker (*this, *section_marker_group, color, location->name(), marker_type (location), location->start());
group = section_marker_group;
} else if (location->is_scene()) {
lam->start = new ArdourMarker (*this, *scene_marker_group, color, location->name(), marker_type (location), location->start());
group = scene_marker_group;
} else {
lam->start = new ArdourMarker (*this, *marker_group, color, location->name(), marker_type (location), location->start());
group = marker_group;
@ -514,6 +519,8 @@ void Editor::ensure_marker_updated (LocationMarkers* lam, Location* location)
{
if (location->is_cd_marker()) {
reparent_location_markers (lam, cd_marker_group);
} else if (location->is_scene()) {
reparent_location_markers (lam, scene_marker_group);
} else if (location->is_section()) {
reparent_location_markers (lam, section_marker_group);
} else if (location->is_cue_marker()) {

View File

@ -247,7 +247,11 @@ Editor::snap_mode_button_clicked (GdkEventButton* ev)
RCOptionEditor* rc_option_editor = ARDOUR_UI::instance()->get_rc_option_editor();
if (rc_option_editor) {
#ifdef LIVETRAX
rc_option_editor->present ();
#else
ARDOUR_UI::instance()->show_tabbable (rc_option_editor);
#endif
rc_option_editor->set_current_page (_("Editor/Snap"));
}
@ -775,6 +779,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
}
}
return true;
case SceneMarkerItem:
_drags->set (new MarkerDrag (this, item), event);
return true;
case TempoMarkerItem:
if (ArdourKeyboard::indicates_constraint (event->button.state)) {
@ -1731,6 +1738,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
marker_context_menu (&event->button, item);
break;
case SceneMarkerItem:
marker_context_menu (&event->button, item);
break;
case TempoMarkerItem:
case MeterMarkerItem:
case BBTMarkerItem:
@ -2340,7 +2351,7 @@ Editor::can_remove_control_point (ArdourCanvas::Item* item)
}
AutomationLine& line = control_point->line ();
if (dynamic_cast<AudioRegionGainLine*> (&line)) {
if (dynamic_cast<RegionFxLine*> (&line)) {
/* we shouldn't remove the first or last gain point in region gain lines */
if (line.is_last_point(*control_point) || line.is_first_point(*control_point)) {
return false;

View File

@ -2683,6 +2683,22 @@ Editor::clear_cues ()
}
}
void
Editor::clear_scenes ()
{
begin_reversible_command (_("clear locations"));
XMLNode &before = _session->locations()->get_state();
if (_session->locations()->clear_scene_markers (0, max_samplepos)) {
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
commit_reversible_command ();
} else {
abort_reversible_command ();
}
}
void
Editor::clear_locations ()
{
@ -4833,7 +4849,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
bool erase = true;
if (dynamic_cast<AudioRegionGainLine*> (&line)) {
if (dynamic_cast<RegionFxLine*> (&line)) {
/* removing of first and last gain point in region gain lines is prohibited*/
if (line.is_last_point (*(*sel_point)) || line.is_first_point (*(*sel_point))) {
erase = false;

View File

@ -180,6 +180,7 @@ Editor::initialize_rulers ()
lab_children.push_back (Element(cd_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(cue_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(scene_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(section_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(videotl_label, PACK_SHRINK, PACK_START));
@ -257,6 +258,10 @@ Editor::popup_ruler_menu (timepos_t const & where, ItemType t)
}
break;
case SceneMarkerBarItem:
ruler_items.push_back (MenuElem (_("Delete all Scenes"), sigc::mem_fun (*this, &Editor::clear_scenes)));
break;
case TempoBarItem:
case TempoCurveItem:
ruler_items.push_back (MenuElem (_("Add New Tempo"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_add_new_tempo_event), where)));
@ -485,7 +490,7 @@ Editor::update_ruler_visibility ()
videotl_label.hide();
#endif
if (ruler_minsec_action->get_active()) {
if (!Profile->get_livetrax() && ruler_minsec_action->get_active()) {
old_unit_pos = minsec_ruler->position().y;
if (tbpos != old_unit_pos) {
minsec_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -501,7 +506,7 @@ Editor::update_ruler_visibility ()
minsec_label.hide();
}
if (ruler_timecode_action->get_active()) {
if (Profile->get_livetrax() || ruler_timecode_action->get_active()) {
old_unit_pos = timecode_ruler->position().y;
if (tbpos != old_unit_pos) {
timecode_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -517,7 +522,7 @@ Editor::update_ruler_visibility ()
timecode_label.hide();
}
if (ruler_samples_action->get_active()) {
if (!Profile->get_livetrax() && ruler_samples_action->get_active()) {
old_unit_pos = samples_ruler->position().y;
if (tbpos != old_unit_pos) {
samples_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -533,7 +538,7 @@ Editor::update_ruler_visibility ()
samples_label.hide();
}
if (ruler_bbt_action->get_active()) {
if (!Profile->get_livetrax() && ruler_bbt_action->get_active()) {
old_unit_pos = bbt_ruler->position().y;
if (tbpos != old_unit_pos) {
bbt_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -549,7 +554,7 @@ Editor::update_ruler_visibility ()
bbt_label.hide();
}
if (ruler_tempo_action->get_active()) {
if (!Profile->get_livetrax() && ruler_tempo_action->get_active()) {
old_unit_pos = tempo_group->position().y;
if (tbpos != old_unit_pos) {
tempo_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -564,7 +569,7 @@ Editor::update_ruler_visibility ()
tempo_label.hide();
}
if (ruler_meter_action->get_active()) {
if (!Profile->get_livetrax() && ruler_meter_action->get_active()) {
old_unit_pos = meter_group->position().y;
if (tbpos != old_unit_pos) {
meter_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -579,7 +584,7 @@ Editor::update_ruler_visibility ()
meter_label.hide();
}
if (ruler_range_action->get_active()) {
if (!Profile->get_livetrax() && ruler_range_action->get_active()) {
old_unit_pos = range_marker_group->position().y;
if (tbpos != old_unit_pos) {
range_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -597,7 +602,7 @@ Editor::update_ruler_visibility ()
range_mark_label.hide();
}
if (ruler_loop_punch_action->get_active()) {
if (!Profile->get_livetrax() && ruler_loop_punch_action->get_active()) {
old_unit_pos = transport_marker_group->position().y;
if (tbpos != old_unit_pos) {
transport_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -615,7 +620,7 @@ Editor::update_ruler_visibility ()
transport_mark_label.hide();
}
if (ruler_cd_marker_action->get_active()) {
if (!Profile->get_livetrax() && ruler_cd_marker_action->get_active()) {
old_unit_pos = cd_marker_group->position().y;
if (tbpos != old_unit_pos) {
cd_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -637,7 +642,7 @@ Editor::update_ruler_visibility ()
update_marker_display();
}
if (ruler_marker_action->get_active()) {
if (Profile->get_livetrax() || ruler_marker_action->get_active()) {
old_unit_pos = marker_group->position().y;
if (tbpos != old_unit_pos) {
marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -655,7 +660,7 @@ Editor::update_ruler_visibility ()
mark_label.hide();
}
if (ruler_cue_marker_action->get_active()) {
if (!Profile->get_livetrax() && ruler_cue_marker_action->get_active()) {
old_unit_pos = cue_marker_group->position().y;
if (tbpos != old_unit_pos) {
cue_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -673,7 +678,26 @@ Editor::update_ruler_visibility ()
cue_mark_label.hide();
}
if (ruler_section_action->get_active()) {
if (Profile->get_livetrax() || ruler_scene_marker_action->get_active()) {
old_unit_pos = scene_marker_group->position().y;
if (tbpos != old_unit_pos) {
scene_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
scene_marker_group->show();
scene_mark_label.show();
scene_marker_bar->set_outline(false);
tbpos += timebar_height;
tbgpos += timebar_height;
visible_timebars++;
update_marker_display();
} else {
scene_marker_group->hide ();
scene_mark_label.hide ();
}
if (!Profile->get_livetrax() && ruler_section_action->get_active()) {
old_unit_pos = section_marker_group->position().y;
if (tbpos != old_unit_pos) {
section_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
@ -693,7 +717,7 @@ Editor::update_ruler_visibility ()
update_marker_display();
}
if (ruler_video_action->get_active()) {
if (!Profile->get_livetrax() && ruler_video_action->get_active()) {
old_unit_pos = videotl_group->position().y;
if (tbpos != old_unit_pos) {
videotl_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));

View File

@ -80,9 +80,68 @@ static const unsigned int latency_tab = 1; /* zero-based, page zero is the main
static const char* results_markup = X_("<span weight=\"bold\" size=\"larger\">%1</span>");
EngineControl::EngineControl ()
EngineControlDialog::EngineControlDialog ()
: ArdourDialog (_("Audio/MIDI Setup"))
, engine_status ("")
{
engine_control.set_parent (*this);
if (UIConfiguration::instance().get_allow_to_resize_engine_dialog ()) {
set_resizable (false);
}
set_name (X_("AudioMIDISetup"));
/* packup the notebook */
get_vbox ()->set_border_width (12);
get_vbox ()->pack_start (engine_control.contents());
}
void
EngineControlDialog::on_response (int r)
{
/* Do not run ArdourDialog::on_response() which will hide us. Leave
* that to whoever invoked us, if they wish to hide us after "start".
*
* StartupFSM does hide us after response(); Window > Audio/MIDI Setup
* does not.
*/
if (r == RESPONSE_OK) {
pop_splash ();
}
Gtk::Dialog::on_response (r);
}
void
EngineControlDialog::on_show ()
{
ArdourDialog::on_show ();
engine_control.on_show ();
}
void
EngineControlDialog::on_map ()
{
if (!ARDOUR_UI::instance ()->the_session () && !PublicEditor::_instance) {
set_type_hint (Gdk::WINDOW_TYPE_HINT_NORMAL);
} else if (UIConfiguration::instance ().get_all_floating_windows_are_dialogs ()) {
set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG);
} else {
set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY);
}
ArdourDialog::on_map ();
}
bool
EngineControlDialog::on_delete_event (GdkEventAny* ev)
{
engine_control.on_delete_event (ev);
return ArdourDialog::on_delete_event (ev);
}
EngineControl::EngineControl ()
: engine_status ("")
, settings_table (4, 4)
, latency_expander (_("Advanced Settings"))
, monitor_expander (_("Hardware Monitoring"))
@ -126,6 +185,7 @@ EngineControl::EngineControl ()
, queue_device_changed (false)
, _have_control (true)
, block_signals (0)
, parent (nullptr)
{
using namespace Notebook_Helpers;
vector<string> backend_names;
@ -133,11 +193,6 @@ EngineControl::EngineControl ()
AttachOptions xopt = AttachOptions (FILL | EXPAND);
int row;
if (UIConfiguration::instance().get_allow_to_resize_engine_dialog ()) {
set_resizable (false);
}
set_name (X_("AudioMIDISetup"));
/* the backend combo is the one thing that is ALWAYS visible */
vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance ()->available_backends ();
@ -277,11 +332,6 @@ EngineControl::EngineControl ()
notebook.set_name ("SettingsNotebook");
/* packup the notebook */
get_vbox ()->set_border_width (12);
get_vbox ()->pack_start (notebook);
/* Setup buttons and signals */
lm_button_audio.signal_clicked.connect (sigc::mem_fun (*this, &EngineControl::calibrate_audio_latency));
@ -454,7 +504,6 @@ EngineControl::SignalBlocker::~SignalBlocker ()
void
EngineControl::on_show ()
{
ArdourDialog::on_show ();
if (!ARDOUR::AudioEngine::instance ()->current_backend () || !ARDOUR::AudioEngine::instance ()->running ()) {
// re-check _have_control (jackd running) see #6041
backend_changed ();
@ -463,19 +512,6 @@ EngineControl::on_show ()
start_stop_button.grab_focus ();
}
void
EngineControl::on_map ()
{
if (!ARDOUR_UI::instance ()->the_session () && !PublicEditor::_instance) {
set_type_hint (Gdk::WINDOW_TYPE_HINT_NORMAL);
} else if (UIConfiguration::instance ().get_all_floating_windows_are_dialogs ()) {
set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG);
} else {
set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY);
}
ArdourDialog::on_map ();
}
void
EngineControl::config_parameter_changed (std::string const& p)
{
@ -500,15 +536,17 @@ EngineControl::config_parameter_changed (std::string const& p)
bool
EngineControl::start_engine ()
{
assert (parent);
int rv = push_state_to_backend (true);
if (rv < 0) {
/* error message from backend */
ArdourMessageDialog msg (*this, ARDOUR::AudioEngine::instance ()->get_last_backend_error ());
ArdourMessageDialog msg (*parent, ARDOUR::AudioEngine::instance ()->get_last_backend_error ());
msg.run ();
} else if (rv > 0) {
/* error from push_state_to_backend() */
// TODO: get error message from push_state_to_backend
ArdourMessageDialog msg (*this, _("Could not configure Audio/MIDI engine with given settings."));
ArdourMessageDialog msg (*parent, _("Could not configure Audio/MIDI engine with given settings."));
msg.run ();
}
return rv == 0;
@ -1083,8 +1121,8 @@ EngineControl::backend_changed ()
maybe_display_saved_state ();
}
if (!UIConfiguration::instance().get_allow_to_resize_engine_dialog ()) {
resize (1, 1); // shrink window
if (parent && !UIConfiguration::instance().get_allow_to_resize_engine_dialog ()) {
parent->resize (1, 1); // shrink window
}
}
@ -2680,7 +2718,7 @@ EngineControl::get_output_device_name () const
void
EngineControl::control_app_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -2693,25 +2731,10 @@ EngineControl::control_app_button_clicked ()
backend->launch_control_app ();
}
void
EngineControl::on_response (int r)
{
/* Do not run ArdourDialog::on_response() which will hide us. Leave
* that to whoever invoked us, if they wish to hide us after "start".
*
* StartupFSM does hide us after response(); Window > Audio/MIDI Setup
* does not.
*/
if (r == RESPONSE_OK) {
pop_splash ();
}
Gtk::Dialog::on_response (r);
}
void
EngineControl::start_stop_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -2732,13 +2755,15 @@ EngineControl::start_stop_button_clicked ()
rv = start_engine () ? RESPONSE_OK : RESPONSE_ACCEPT;
}
response (rv);
if (parent) {
parent->response (rv);
}
}
void
EngineControl::update_devices_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -2760,7 +2785,7 @@ EngineControl::update_devices_button_clicked ()
void
EngineControl::try_autostart_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -2771,7 +2796,7 @@ EngineControl::try_autostart_button_clicked ()
void
EngineControl::use_buffered_io_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -2952,6 +2977,10 @@ unparent_widget (Gtk::Widget& w)
void
EngineControl::populate_action_area (int page_num)
{
if (!parent) {
return;
}
/* re-populate action area */
unparent_widget (start_stop_button);
unparent_widget (connect_disconnect_button);
@ -2962,17 +2991,19 @@ EngineControl::populate_action_area (int page_num)
if (page_num == 0) {
if (_have_control) {
get_action_area ()->add (start_stop_button);
parent->add_widget_action (start_stop_button);
} else {
get_action_area ()->add (connect_disconnect_button);
parent->add_widget_action (connect_disconnect_button);
}
} else if (page_num == latency_tab) {
get_action_area ()->add (lm_measure_button);
get_action_area ()->add (lm_use_button);
get_action_area ()->add (lm_back_button);
get_action_area ()->show_all ();
parent->add_widget_action (lm_measure_button);
parent->add_widget_action (lm_use_button);
parent->add_widget_action (lm_back_button);
lm_measure_button.show();
lm_use_button.show ();
lm_back_button.show ();
} else if (page_num == midi_tab) {
get_action_area ()->add (midi_back_button);
parent->add_widget_action (midi_back_button);
midi_back_button.show ();
}
}
@ -3148,7 +3179,7 @@ EngineControl::end_latency_detection ()
void
EngineControl::latency_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -3162,7 +3193,7 @@ EngineControl::latency_button_clicked ()
void
EngineControl::latency_back_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -3181,7 +3212,7 @@ EngineControl::latency_back_button_clicked ()
void
EngineControl::use_latency_button_clicked ()
{
if (!_sensitive) {
if (!parent || parent->ui_sensitive()) {
return;
}
@ -3227,7 +3258,9 @@ EngineControl::use_latency_button_clicked ()
* from a running instance.
*/
notebook.set_current_page (0);
response (RESPONSE_OK);
if (parent) {
parent->response (RESPONSE_OK);
}
return;
}
@ -3236,17 +3269,6 @@ EngineControl::use_latency_button_clicked ()
}
}
bool
EngineControl::on_delete_event (GdkEventAny* ev)
{
if (lm_running || notebook.get_current_page () == 2) {
/* currently measuring latency - be sure to clean up */
end_latency_detection ();
}
return ArdourDialog::on_delete_event (ev);
}
void
EngineControl::engine_running ()
{
@ -3319,13 +3341,13 @@ EngineControl::connect_disconnect_click ()
stop_engine ();
} else {
if (!ARDOUR_UI::instance ()->the_session ()) {
pop_splash ();
hide ();
parent->pop_splash ();
parent->hide ();
ARDOUR::GUIIdle ();
}
start_engine ();
if (!ARDOUR_UI::instance ()->the_session ()) {
ArdourDialog::response (RESPONSE_OK);
parent->response (RESPONSE_OK);
}
}
}
@ -3355,3 +3377,19 @@ EngineControl::configure_midi_devices ()
{
notebook.set_current_page (midi_tab);
}
void
EngineControl::set_parent (ArdourDialog& d)
{
parent = &d;
}
bool
EngineControl::on_delete_event (GdkEventAny*)
{
if (lm_running || notebook.get_current_page () == 2) {
/* currently measuring latency - be sure to clean up */
end_latency_detection ();
}
return false;
}

View File

@ -45,7 +45,7 @@
#include "ardour_dialog.h"
class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList
class EngineControl : public PBD::ScopedConnectionList, virtual public sigc::trackable
{
public:
EngineControl ();
@ -58,6 +58,12 @@ public:
void set_desired_sample_rate (uint32_t);
Gtk::Widget& contents() { return notebook; }
void on_show ();
bool on_delete_event (GdkEventAny*);
void set_parent (ArdourDialog&);
private:
Gtk::Notebook notebook;
@ -347,8 +353,6 @@ private:
sigc::connection latency_timeout;
sigc::connection lm_back_button_signal;
void on_show ();
void on_map ();
void on_monitor_expand ();
void on_latency_expand ();
void config_parameter_changed (std::string const&);
@ -382,8 +386,6 @@ private:
/* main dialog events */
void on_switch_page (GtkNotebookPage*, guint page_num);
bool on_delete_event (GdkEventAny*);
void on_response (int);
void connect_disconnect_click ();
void calibrate_audio_latency ();
@ -396,6 +398,27 @@ private:
PBD::ScopedConnection running_connection;
PBD::ScopedConnectionList stopped_connection;
PBD::ScopedConnection devicelist_connection;
ArdourDialog* parent;
};
class EngineControlDialog : public ArdourDialog
{
public:
EngineControlDialog ();
XMLNode& get_state () const { return engine_control.get_state (); }
bool set_state (XMLNode const & node) { return engine_control.set_state (node); }
void set_desired_sample_rate (uint32_t hz) { engine_control.set_desired_sample_rate (hz); }
private:
EngineControl engine_control;
void on_show ();
void on_map ();
void on_response (int);
bool on_delete_event (GdkEventAny*);
};
#endif /* __gtk2_ardour_engine_dialog_h__ */

View File

@ -152,11 +152,13 @@ setup_gtk_ardour_enums ()
REGISTER_ENUM (StreamItem);
REGISTER_ENUM (PlayheadCursorItem);
REGISTER_ENUM (MarkerItem);
REGISTER_ENUM (SceneMarkerItem);
REGISTER_ENUM (MarkerBarItem);
REGISTER_ENUM (RangeMarkerBarItem);
REGISTER_ENUM (CdMarkerBarItem);
REGISTER_ENUM (SectionMarkerBarItem);
REGISTER_ENUM (CueMarkerBarItem);
REGISTER_ENUM (SceneMarkerBarItem);
REGISTER_ENUM (VideoBarItem);
REGISTER_ENUM (TransportMarkerBarItem);
REGISTER_ENUM (SelectionItem);

View File

@ -1015,7 +1015,10 @@ GenericPluginUI::build_control_ui (const Evoral::Parameter& param,
}
if (!_pi || mcontrol->flags () & Controllable::NotAutomatable) {
if (!_pi) {
control_ui->automate_button.set_no_show_all ();
control_ui->automate_button.hide ();
} else if (mcontrol->flags () & Controllable::NotAutomatable) {
control_ui->automate_button.set_sensitive (false);
set_tooltip(control_ui->automate_button, _("This control cannot be automated"));
} else {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -19,7 +19,9 @@
#include "pbd/convert.h"
#include "pbd/enumwriter.h"
#include "ardour/profile.h"
#include "ardour/plugin_manager.h"
#include "gtkmm2ext/gui_thread.h"
#include "instrument_selector.h"
@ -47,12 +49,20 @@ InstrumentSelector::drop_plugin_ptr()
{
unset_model ();
clear ();
_instrument_list->clear ();
if (_instrument_list) {
_instrument_list->clear ();
}
}
void
InstrumentSelector::refill()
{
/* XXX conditional can be removed once livetrax has its own simple add
tracks dialog.
*/
if (Profile->get_livetrax()) {
return;
}
TreeModel::iterator iter = get_active();
std::string selected;
if (iter) {

View File

@ -42,6 +42,7 @@
#include "mixer_ui.h"
#include "plugin_selector.h"
#include "plugin_ui.h"
#include "plugin_window_proxy.h"
#include "ui_config.h"
#include "pbd/i18n.h"
@ -299,7 +300,7 @@ IOPluginWindow::IOPlugUI::IOPlugUI (std::shared_ptr<ARDOUR::IOPlug> iop)
_window_proxy = dynamic_cast<PluginWindowProxy*> (iop->window_proxy ());
assert (_window_proxy);
} else {
_window_proxy = new PluginWindowProxy (string_compose ("IOP-%1", _iop->id ()), _iop);
_window_proxy = new PluginWindowProxy (string_compose ("IOP-%1", _iop->id ()), "I/O", _iop);
const XMLNode* ui_xml = _iop->session ().extra_xml (X_("UI"));
if (ui_xml) {
@ -373,113 +374,6 @@ IOPluginWindow::IOPlugUI::button_resized (Gtk::Allocation& alloc)
_btn_ioplug.set_layout_ellipsize_width (alloc.get_width () * PANGO_SCALE);
}
/* ****************************************************************************/
IOPluginWindow::PluginWindowProxy::PluginWindowProxy (std::string const& name, std::weak_ptr<PlugInsertBase> plugin)
: WM::ProxyBase (name, std::string ())
, _pib (plugin)
, _is_custom (true)
, _want_custom (true)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return;
}
p->DropReferences.connect (_going_away_connection, MISSING_INVALIDATOR, boost::bind (&IOPluginWindow::PluginWindowProxy::plugin_going_away, this), gui_context ());
}
IOPluginWindow::PluginWindowProxy::~PluginWindowProxy ()
{
_window = 0;
}
Gtk::Window*
IOPluginWindow::PluginWindowProxy::get (bool create)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return 0;
}
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (!_window) {
if (!create) {
return 0;
}
_is_custom = _want_custom;
_window = new PluginUIWindow (p, false, _is_custom);
if (_window) {
std::shared_ptr<ARDOUR::IOPlug> iop = std::dynamic_pointer_cast<ARDOUR::IOPlug> (p);
assert (iop);
_window->set_title (iop->name ());
setup ();
_window->show_all ();
}
}
return _window;
}
void
IOPluginWindow::PluginWindowProxy::show_the_right_window ()
{
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (_window) {
_window->unset_transient_for ();
}
toggle ();
}
int
IOPluginWindow::PluginWindowProxy::set_state (const XMLNode& node, int)
{
XMLNodeList children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
while (i != children.end ()) {
std::string name;
if ((*i)->name () == X_("Window") && (*i)->get_property (X_("name"), name) && name == _name) {
break;
}
++i;
}
if (i != children.end ()) {
(*i)->get_property (X_("custom-ui"), _want_custom);
}
return ProxyBase::set_state (node, 0);
}
XMLNode&
IOPluginWindow::PluginWindowProxy::get_state () const
{
XMLNode* node;
node = &ProxyBase::get_state ();
node->set_property (X_("custom-ui"), _is_custom);
return *node;
}
void
IOPluginWindow::PluginWindowProxy::plugin_going_away ()
{
delete _window;
_window = 0;
WM::Manager::instance ().remove (this);
_going_away_connection.disconnect ();
delete this;
}
/* ****************************************************************************/
IOPluginWindow::IOButton::IOButton (std::shared_ptr<ARDOUR::IO> io, bool pre)
: _io (io)
, _pre (pre)

View File

@ -35,11 +35,11 @@ namespace ARDOUR
{
class IO;
class IOPlug;
class PlugInsertBase;
class Port;
}
class IOSelectorWindow;
class PluginWindowProxy;
class IOPluginWindow : public ArdourWindow
{
@ -48,39 +48,6 @@ public:
void set_session (ARDOUR::Session*);
class PluginWindowProxy : public WM::ProxyBase
{
public:
PluginWindowProxy (std::string const&, std::weak_ptr<ARDOUR::PlugInsertBase>);
~PluginWindowProxy ();
Gtk::Window* get (bool create = false);
void show_the_right_window ();
ARDOUR::SessionHandlePtr* session_handle ()
{
return 0;
}
void set_custom_ui_mode (bool use_custom)
{
_want_custom = use_custom;
}
int set_state (const XMLNode&, int);
XMLNode& get_state () const;
private:
void plugin_going_away ();
std::weak_ptr<ARDOUR::PlugInsertBase> _pib;
bool _is_custom;
bool _want_custom;
PBD::ScopedConnection _going_away_connection;
};
protected:
void on_show ();
void on_hide ();
@ -147,7 +114,7 @@ private:
IOButton _btn_output;
ArdourWidgets::ArdourButton _btn_ioplug;
PluginWindowProxy* _window_proxy;
std::shared_ptr<ARDOUR::IOPlug> _iop;
std::shared_ptr<ARDOUR::IOPlug> _iop;
PBD::ScopedConnection _going_away_connection;
};

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2024 Paul Davis <paul@linuxaudiosystems.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 <gtkmm/stock.h>
#include "livetrax_add_track_dialog.h"
#include "pbd/i18n.h"
using namespace Gtk;
LiveTraxAddTrackDialog::LiveTraxAddTrackDialog ()
: ArdourDialog (_("Add Tracks"))
, track_count (1.0, 1.0, 1024.0, 1.0, 10.)
, track_count_spinner (track_count)
, mono_button (channel_button_group, _("Mono"))
, stereo_button (channel_button_group, _("Stereo"))
{
get_vbox()->pack_start (track_count_spinner);
get_vbox()->pack_start (mono_button);
get_vbox()->pack_start (stereo_button);
mono_button.set_active();
add_button (Stock::CANCEL, RESPONSE_CANCEL);
add_button (Stock::OK, RESPONSE_OK);
show_all ();
}
LiveTraxAddTrackDialog::~LiveTraxAddTrackDialog()
{
}
int
LiveTraxAddTrackDialog::num_tracks() const
{
return track_count.get_value();
}
bool
LiveTraxAddTrackDialog::stereo() const
{
return stereo_button.get_active();
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2024 Paul Davis <paul@linuxaudiosystems.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.
*/
#ifndef __gtk_ardour_livetrax_add_track_dialog_h__
#define __gtk_ardour_livetrax_add_track_dialog_h__
#include <gtkmm/dialog.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/button.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/adjustment.h>
#include "ardour_dialog.h"
class LiveTraxAddTrackDialog : public ArdourDialog
{
public:
LiveTraxAddTrackDialog ();
~LiveTraxAddTrackDialog ();
int num_tracks() const;
bool stereo () const;
private:
Gtk::Adjustment track_count;
Gtk::SpinButton track_count_spinner;
Gtk::RadioButtonGroup channel_button_group;
Gtk::RadioButton mono_button;
Gtk::RadioButton stereo_button;
};
#endif // __gtk_ardour_livetrax_add_track_dialog_h__ */

View File

@ -0,0 +1,116 @@
#include "ardour/logmeter.h"
#include "ardour/audioengine.h"
#include "widgets/fastmeter.h"
#include "livetrax_meters.h"
#include "ui_config.h"
using namespace ARDOUR;
using namespace ArdourWidgets;
#define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ()))
LiveTraxMeters::LiveTraxMeters (size_t initial_cnt)
{
set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_NEVER);
resize (initial_cnt);
meter_box.set_spacing (PX_SCALE (10));
add (meter_box);
fast_screen_update_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &LiveTraxMeters::update_meters), 40, GDK_PRIORITY_REDRAW + 10);
}
LiveTraxMeters::~LiveTraxMeters ()
{
fast_screen_update_connection.disconnect ();
}
void
LiveTraxMeters::resize (size_t sz)
{
size_t old = meters.size();
while (old > sz) {
/* Widgets are all managed so this should delete them as they
are removed.
*/
meter_box.remove (*widgets[old - 1]);
meters.pop_back ();
old--;
}
if (old == sz) {
return;
}
uint32_t c[10];
uint32_t b[4];
float stp[4];
c[0] = UIConfiguration::instance().color ("meter color0");
c[1] = UIConfiguration::instance().color ("meter color1");
c[2] = UIConfiguration::instance().color ("meter color2");
c[3] = UIConfiguration::instance().color ("meter color3");
c[4] = UIConfiguration::instance().color ("meter color4");
c[5] = UIConfiguration::instance().color ("meter color5");
c[6] = UIConfiguration::instance().color ("meter color6");
c[7] = UIConfiguration::instance().color ("meter color7");
c[8] = UIConfiguration::instance().color ("meter color8");
c[9] = UIConfiguration::instance().color ("meter color9");
b[0] = UIConfiguration::instance().color ("meter background bottom");
b[1] = UIConfiguration::instance().color ("meter background top");
b[2] = 0x991122ff; // red highlight gradient Bot
b[3] = 0x551111ff; // red highlight gradient Top
stp[0] = 115.0 * log_meter0dB (-15);
stp[1] = 115.0 * log_meter0dB (-9);
stp[2] = 115.0 * log_meter0dB (-3);
stp[3] = 115.0;
// XXX config changed -> update meter style (and size)
for (size_t i = old; i < sz; ++i) {
meters.push_back (manage (new FastMeter (10 /* (uint32_t)floor (UIConfiguration::instance ().get_meter_hold ()) */,
8, FastMeter::Vertical, PX_SCALE (64),
c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9],
b[0], b[1], b[2], b[3],
stp[0], stp[1], stp[2], stp[3],
(UIConfiguration::instance ().get_meter_style_led () ? 3 : 1))));
Gtk::VBox* vb = manage (new Gtk::VBox);
char buf[16];
snprintf (buf, sizeof (buf), "%zu", i+1);
Gtk::Label* l = manage (new Gtk::Label (buf));
vb->pack_start (*l, false, false);
vb->pack_start (*meters.back(), true, true);
widgets.push_back (vb);
meter_box.pack_start (*vb, false, false, 0);
}
meter_box.show_all ();
}
bool
LiveTraxMeters::update_meters ()
{
PortManager::AudioInputPorts const aip (AudioEngine::instance ()->audio_input_ports ());
size_t n = 0;
for (auto const & p : aip) {
if (n >= meters.size()) {
break;
}
meters[n]->set (p.second.meter->level, p.second.meter->peak);
++n;
}
return true;
}

View File

@ -0,0 +1,35 @@
#ifndef __ardour_gtk_livetrax_meters_h__
#define __ardour_gtk_livetrax_meters_h__
#include <unistd.h>
#include <gtkmm/box.h>
#include <gtkmm/scrolledwindow.h>
namespace Gtk {
class Label;
}
namespace ArdourWidgets {
class FastMeter;
}
class LiveTraxMeters : public Gtk::ScrolledWindow
{
public:
LiveTraxMeters (size_t initial_cnt);
~LiveTraxMeters ();
void resize (size_t);
private:
Gtk::HBox meter_box;
Gtk::HBox global_hbox;
std::vector<Gtk::Widget*> widgets;
std::vector<ArdourWidgets::FastMeter*> meters;
sigc::connection fast_screen_update_connection;
bool update_meters ();
};
#endif /* __ardour_gtk_livetrax_meters_h__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2012-2017 Robin Gareus <robin@gareus.org>
* Copyright (C) 2012-2018 Paul Davis <paul@linuxaudiosystems.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.
*/
#ifndef __gtk_ardour_rc_option_editor_h__
#define __gtk_ardour_rc_option_editor_h__
#include "widgets/tabbable.h"
#include "option_editor.h"
#include "visibility_group.h"
#include "transport_masters_dialog.h"
/** @file rc_option_editor.h
* @brief Editing of options which are obtained from and written back to one of the .rc files.
*
* This is subclassed from OptionEditor. Simple options (e.g. boolean and simple choices)
* are expressed using subclasses of Option. More complex UI elements are represented
* using individual classes subclassed from OptionEditorBox.
*/
/** Editor for options which are obtained from and written back to one of the .rc files. */
class RCOptionEditor : public OptionEditorWindow
{
public:
RCOptionEditor ();
void set_session (ARDOUR::Session*);
XMLNode& get_state () const;
bool on_key_release_event (GdkEventKey*);
private:
void parameter_changed (std::string const &);
void ltc_generator_volume_changed ();
ARDOUR::RCConfiguration* _rc_config;
BoolOption* _solo_control_is_listen_control;
ComboOption<ARDOUR::ListenPosition>* _listen_position;
VisibilityGroup _mixer_strip_visibility;
BoolOption* _sync_framerate;
HSliderOption* _ltc_volume_slider;
Gtk::Adjustment* _ltc_volume_adjustment;
BoolOption* _ltc_send_continuously;
BoolOption* _plugin_prefer_inline;
BoolOption* _cairo_image_surface;
TransportMastersWidget _transport_masters_widget;
Gtk::Button audiomidi_tab_button;
Gtk::Button midi_tab_button;
Gtk::Button session_tab_button;
Gtk::Button preferences_tab_button;
Gtk::Button sync_tab_button;
PBD::ScopedConnection parameter_change_connection;
PBD::ScopedConnection engine_started_connection;
void show_audio_setup ();
void show_transport_masters ();
void reset_clip_library_dir ();
EntryOption* mrl_option;
EntryOption* mru_option;
std::string get_default_lower_midi_note ();
bool set_default_lower_midi_note (std::string);
std::string get_default_upper_midi_note ();
bool set_default_upper_midi_note (std::string);
};
#endif /* __gtk_ardour_rc_option_editor_h__ */

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2024 Paul Davis <paul@linuxaudiosystems.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 <iostream>
#include "livetrax_tc_widget.h"
#include "ui_config.h"
LiveTraxTCWidget::LiveTraxTCWidget()
{
Gtkmm2ext::Color c;
c = UIConfiguration::instance().color ("widget:blue");
Gtkmm2ext::color_to_rgba (c, bg_r, bg_g, bg_b, bg_a);
c = UIConfiguration::instance().color ("neutral:foreground");
Gtkmm2ext::color_to_rgba (c, txt_r, txt_g, txt_b, txt_a);
c = UIConfiguration::instance().color ("theme:bg1");
Gtkmm2ext::color_to_rgba (c, fg_r, fg_g, fg_b, fg_a);
}
bool
LiveTraxTCWidget::on_button_release_event (GdkEventButton* ev)
{
std::cerr << "here\n";
return true;
}
void
LiveTraxTCWidget::render (Cairo::RefPtr<Cairo::Context> const & context, cairo_rectangle_t*)
{
/* draw the background */
context->set_source_rgba (bg_r, bg_g, bg_b, 1.);
context->rectangle (0, 0, get_width(), get_height());
context->fill ();
Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create (context);
layout->set_text ("TC\nSource");
layout->set_font_description (UIConfiguration::instance().get_NormalBoldFont());
context->move_to (get_width() / 2.0 + 10., 10.);
context->set_source_rgba (txt_r, txt_g, txt_b, 1.);
layout->show_in_cairo_context (context);
double rect_width = (get_width() / 2.);
double rect_height = (get_height() - 3.) / 2.;
context->set_source_rgba (fg_r, fg_g, fg_b, 1.);
context->rectangle (1., 1., rect_width, rect_height);
context->fill ();
context->set_source_rgba (fg_r, fg_g, fg_b, 1.);
context->rectangle (1., 2 + rect_height, rect_width, rect_height);
context->fill ();
layout->set_text ("LTC");
layout->set_font_description (UIConfiguration::instance().get_NormalFont());
context->move_to (4., 3.); // XXXX need to adjust by + text height/2
context->set_source_rgba (txt_r, txt_g, txt_b, 1.);
layout->show_in_cairo_context (context);
layout->set_text ("25 FPS");
layout->set_font_description (UIConfiguration::instance().get_NormalFont());
context->move_to (4., 3. + rect_height); // XXXX need to adjust by + text height/2
context->set_source_rgba (txt_r, txt_g, txt_b, 1.);
layout->show_in_cairo_context (context);
}
void
LiveTraxTCWidget::parameter_changed (std::string const & param)
{
}
void
LiveTraxTCWidget::on_size_request (Gtk::Requisition* r)
{
r->width = 150;
r->height = -1;
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2024 Paul Davis <paul@linuxaudiosystems.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.
*/
#ifndef __gtk2_ardour_livetrax_tc_widget_h__
#define __gtk2_ardour_livetrax_tc_widget_h__
#include "gtkmm2ext/cairo_widget.h"
class LiveTraxTCWidget : public CairoWidget
{
public:
LiveTraxTCWidget ();
bool on_button_release_event (GdkEventButton*);
void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
void parameter_changed (std::string const &);
void on_size_request (Gtk::Requisition*);
private:
double bg_r, bg_g, bg_b, bg_a;
double fg_r, fg_g, fg_b, fg_a;
double txt_r, txt_g, txt_b, txt_a;
};
#endif /* __gtk2_ardour_livetrax_tc_widget_h__ */

View File

@ -42,6 +42,7 @@
#include "ardour_http.h"
#include "ardour_ui.h"
#include "audio_region_view.h"
#include "public_editor.h"
#include "region_selection.h"
#include "luadialog.h"
@ -826,6 +827,14 @@ LuaInstance::register_classes (lua_State* L, bool sandbox)
.endClass ()
.deriveClass <RegionView, TimeAxisViewItem> ("RegionView")
.addCast<AudioRegionView> ("to_audioregionview")
.addFunction ("show_region_editor", &RegionView::show_region_editor)
.addFunction ("hide_region_editor", &RegionView::hide_region_editor)
.endClass ()
.deriveClass <AudioRegionView, RegionView> ("RegionView")
.addFunction ("set_region_gain_line", &AudioRegionView::set_region_gain_line)
.addFunction ("set_region_fx_line", (bool (AudioRegionView::*)(uint32_t, uint32_t))&AudioRegionView::set_region_fx_line)
.endClass ()
.deriveClass <RouteUI, Selectable> ("RouteUI")

View File

@ -51,6 +51,7 @@
#include "ardour/revision.h"
#include "ardour/ardour.h"
#include "ardour/audioengine.h"
#include "ardour/profile.h"
#include "ardour/session_utils.h"
#include "ardour/filesystem_paths.h"

View File

@ -103,6 +103,8 @@ MergeableLine::merge_drawn_line (Editor& e, Session& s, Evoral::ControlList::Ord
e.begin_reversible_command (_("draw automation"));
s.add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
_line->end_draw_merge ();
_line->get_selectables (earliest, latest, 0.0, 1.0, results);
e.get_selection ().set (results);

View File

@ -2548,13 +2548,13 @@ MidiRegionView::update_drag_selection(timepos_t const & start, timepos_t const &
/* Add control points to selection. */
const ATracks& atracks = midi_view()->automation_tracks();
Selectables selectables;
editor.get_selection().clear_points();
timepos_t st (start);
timepos_t et (end);
for (ATracks::const_iterator a = atracks.begin(); a != atracks.end(); ++a) {
Selectables selectables;
a->second->get_selectables (st, et, gy0, gy1, selectables);
for (Selectables::const_iterator s = selectables.begin(); s != selectables.end(); ++s) {
ControlPoint* cp = dynamic_cast<ControlPoint*>(*s);

View File

@ -154,7 +154,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, std::shared_ptr<Route> rt,
, gpm (sess, 250)
, panners (sess)
, trigger_display (-1., 8*16.)
, button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL))
, button_size_group (Gtk::SizeGroup::create (ARDOUR::Profile->get_livetrax() ? Gtk::SIZE_GROUP_BOTH : Gtk::SIZE_GROUP_HORIZONTAL))
, rec_mon_table (2, 2)
, solo_iso_table (1, 2)
, mute_solo_table (1, 2)
@ -237,10 +237,16 @@ MixerStrip::init ()
rec_mon_table.set_homogeneous (true);
rec_mon_table.set_row_spacings (2);
rec_mon_table.set_col_spacings (2);
if (ARDOUR::Profile->get_mixbus()) {
rec_mon_table.resize (1, 3);
if (ARDOUR::Profile->get_livetrax()) {
rec_mon_table.resize (1, 2);
rec_mon_table.attach (*monitor_input_button, 1, 2, 0, 1);
rec_mon_table.attach (*monitor_disk_button, 2, 3, 0, 1);
} else {
if (ARDOUR::Profile->get_mixbus()) {
rec_mon_table.resize (1, 3);
rec_mon_table.attach (*monitor_input_button, 1, 2, 0, 1);
rec_mon_table.attach (*monitor_disk_button, 2, 3, 0, 1);
}
}
rec_mon_table.show ();
@ -324,23 +330,31 @@ MixerStrip::init ()
set_tooltip (&number_label, _("Double-click to edit the route color.\nRight-click to show the route operations context menu."));
global_vpacker.set_spacing (2);
global_vpacker.pack_start (width_hide_box, Gtk::PACK_SHRINK);
global_vpacker.pack_start (name_button, Gtk::PACK_SHRINK);
global_vpacker.pack_start (input_button_box, Gtk::PACK_SHRINK);
global_vpacker.pack_start (invert_button_box, Gtk::PACK_SHRINK);
global_vpacker.pack_start (trigger_display, Gtk::PACK_SHRINK);
global_vpacker.pack_start (_tmaster_widget, Gtk::PACK_SHRINK);
global_vpacker.pack_start (processor_box, true, true);
if (!Profile->get_livetrax()) {
global_vpacker.pack_start (width_hide_box, Gtk::PACK_SHRINK);
global_vpacker.pack_start (name_button, Gtk::PACK_SHRINK);
global_vpacker.pack_start (input_button_box, Gtk::PACK_SHRINK);
global_vpacker.pack_start (invert_button_box, Gtk::PACK_SHRINK);
global_vpacker.pack_start (trigger_display, Gtk::PACK_SHRINK);
global_vpacker.pack_start (_tmaster_widget, Gtk::PACK_SHRINK);
global_vpacker.pack_start (processor_box, true, true);
}
global_vpacker.pack_start (panners, Gtk::PACK_SHRINK);
global_vpacker.pack_start (rec_mon_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (master_volume_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (solo_iso_table, Gtk::PACK_SHRINK);
if (!Profile->get_livetrax()) {
global_vpacker.pack_start (master_volume_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (solo_iso_table, Gtk::PACK_SHRINK);
}
global_vpacker.pack_start (mute_solo_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (gpm, Gtk::PACK_SHRINK);
global_vpacker.pack_start (control_slave_ui, Gtk::PACK_SHRINK);
global_vpacker.pack_start (bottom_button_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (output_button, Gtk::PACK_SHRINK);
global_vpacker.pack_start (_comment_button, Gtk::PACK_SHRINK);
if (!Profile->get_livetrax()) {
global_vpacker.pack_start (control_slave_ui, Gtk::PACK_SHRINK);
global_vpacker.pack_start (bottom_button_table, Gtk::PACK_SHRINK);
global_vpacker.pack_start (output_button, Gtk::PACK_SHRINK);
global_vpacker.pack_start (_comment_button, Gtk::PACK_SHRINK);
} else {
global_vpacker.pack_start (name_button, true, true);
}
#ifndef MIXBUS
//add a spacer underneath the master bus;
@ -439,7 +453,7 @@ MixerStrip::~MixerStrip ()
void
MixerStrip::vca_assign (std::shared_ptr<ARDOUR::VCA> vca)
{
std::shared_ptr<Slavable> sl = std::dynamic_pointer_cast<Slavable> ( route() );
std::shared_ptr<Slavable> sl = std::dynamic_pointer_cast<Slavable> (route());
if (sl)
sl->assign(vca);
}
@ -447,14 +461,19 @@ MixerStrip::vca_assign (std::shared_ptr<ARDOUR::VCA> vca)
void
MixerStrip::vca_unassign (std::shared_ptr<ARDOUR::VCA> vca)
{
std::shared_ptr<Slavable> sl = std::dynamic_pointer_cast<Slavable> ( route() );
if (sl)
std::shared_ptr<Slavable> sl = std::dynamic_pointer_cast<Slavable> (route());
if (sl) {
sl->unassign(vca);
}
}
bool
MixerStrip::mixer_strip_enter_event (GdkEventCrossing* /*ev*/)
MixerStrip::mixer_strip_enter_event (GdkEventCrossing* ev)
{
if (ev->detail != GDK_NOTIFY_INFERIOR) {
_mixer.steal_focus ();
}
_entered_mixer_strip = this;
return false;
@ -464,7 +483,7 @@ bool
MixerStrip::mixer_strip_leave_event (GdkEventCrossing *ev)
{
//if we have moved outside our strip, but not into a child view, then deselect ourselves
if ( !(ev->detail == GDK_NOTIFY_INFERIOR) ) {
if (ev->detail != GDK_NOTIFY_INFERIOR) {
_entered_mixer_strip= 0;
//clear keyboard focus in the gain display. this is cheesy but fixes a longstanding "bug" where the user starts typing in the gain entry, and leaves it active, thereby prohibiting other keybindings from working
@ -702,15 +721,19 @@ MixerStrip::set_route (std::shared_ptr<Route> rt)
if (is_track ()) {
rec_mon_table.attach (*rec_enable_button, 0, 1, 0, ARDOUR::Profile->get_mixbus() ? 1 : 2);
rec_mon_table.attach (*rec_enable_button, 0, 1, 0, (ARDOUR::Profile->get_mixbus()|ARDOUR::Profile->get_livetrax()) ? 1 : 2);
rec_enable_button->show();
if (ARDOUR::Profile->get_mixbus()) {
if (ARDOUR::Profile->get_livetrax()) {
rec_mon_table.attach (*monitor_input_button, 1, 2, 0, 1);
rec_mon_table.attach (*monitor_disk_button, 2, 3, 0, 1);
} else {
rec_mon_table.attach (*monitor_input_button, 1, 2, 0, 1);
rec_mon_table.attach (*monitor_disk_button, 1, 2, 1, 2);
if (ARDOUR::Profile->get_mixbus()) {
rec_mon_table.attach (*monitor_input_button, 1, 2, 0, 1);
rec_mon_table.attach (*monitor_disk_button, 2, 3, 0, 1);
} else {
rec_mon_table.attach (*monitor_input_button, 1, 2, 0, 1);
rec_mon_table.attach (*monitor_disk_button, 1, 2, 1, 2);
}
}
} else {
@ -1068,7 +1091,13 @@ MixerStrip::route_color_changed ()
{
using namespace ARDOUR_UI_UTILS;
name_button.modify_bg (STATE_NORMAL, color());
number_label.set_fixed_colors (gdk_color_to_rgba (color()), gdk_color_to_rgba (color()));
Gtkmm2ext::Color c (gdk_color_to_rgba (color()));
if (Profile->get_livetrax()) {
name_button.set_fixed_colors (c, c);
}
number_label.set_fixed_colors (c, c);
reset_strip_style ();
}
@ -1677,7 +1706,7 @@ MixerStrip::revert_to_default_display ()
gain_meter().set_controls (_route, _route->shared_peak_meter(), _route->amp(), _route->gain_control());
gain_meter().setup_meters ();
panner_ui().set_panner (_route->main_outs()->panner_shell(), _route->main_outs()->panner());
panner_ui().set_panner (_route->panner_shell(), _route->panner());
update_panner_choices();
panner_ui().setup_pan ();
panner_ui().set_send_drawing_mode (false);

View File

@ -56,6 +56,7 @@
#include "ardour/monitor_control.h"
#include "ardour/panner_shell.h"
#include "ardour/plugin_manager.h"
#include "ardour/profile.h"
#include "ardour/route_group.h"
#include "ardour/selection.h"
#include "ardour/session.h"
@ -131,7 +132,7 @@ Mixer_UI::Mixer_UI ()
, no_track_list_redisplay (false)
, in_group_row_change (false)
, track_menu (0)
, _plugin_selector (0)
, _plugin_selector (nullptr)
, _surround_strip (0)
, foldback_strip (0)
, _show_foldback_strip (true)
@ -164,6 +165,8 @@ Mixer_UI::Mixer_UI ()
scroller_base.set_name ("MixerWindow");
scroller_base.signal_button_press_event().connect (sigc::mem_fun(*this, &Mixer_UI::strip_scroller_button_event));
scroller_base.signal_button_release_event().connect (sigc::mem_fun(*this, &Mixer_UI::strip_scroller_button_event));
scroller_base.signal_enter_notify_event ().connect (sigc::mem_fun (*this, &Mixer_UI::scroller_enter), false);
/* set up drag-n-drop */
vector<TargetEntry> target_table;
@ -330,57 +333,62 @@ Mixer_UI::Mixer_UI ()
}
_mixer_scene_vbox.pack_start(_mixer_scene_table, false, false);
rhs_pane1.add (favorite_plugins_frame);
rhs_pane1.add (track_display_frame);
if (!Profile->get_livetrax()) {
rhs_pane1.add (favorite_plugins_frame);
rhs_pane1.add (track_display_frame);
rhs_pane2.add (rhs_pane1);
rhs_pane2.add (group_display_frame);
rhs_pane2.add (rhs_pane1);
rhs_pane2.add (group_display_frame);
list_vpacker.pack_start (rhs_pane2, true, true);
list_vpacker.pack_start (rhs_pane2, true, true);
//add a spacer; this fills the area that is normally taken by the pane resizers
_mixer_scene_spacer.set_size_request (-1, 6);
list_vpacker.pack_start (_mixer_scene_spacer, false, false);
_mixer_scene_frame.add(_mixer_scene_vbox);
list_vpacker.pack_start (_mixer_scene_frame, false, false);
//add a spacer; this fills the area that is normally taken by the pane resizers
_mixer_scene_spacer.set_size_request (-1, 6);
list_vpacker.pack_start (_mixer_scene_spacer, false, false);
vca_label_bar.set_size_request (-1, 16 + 1); /* must match height in GroupTabs::set_size_request() + 1 border px*/
vca_vpacker.pack_start (vca_label_bar, false, false);
_mixer_scene_frame.add(_mixer_scene_vbox);
list_vpacker.pack_start (_mixer_scene_frame, false, false);
vca_scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
vca_scroller_base.set_name (X_("MixerWindow"));
vca_scroller_base.signal_button_press_event().connect (sigc::mem_fun(*this, &Mixer_UI::strip_scroller_button_event));
vca_scroller_base.signal_button_release_event().connect (sigc::mem_fun(*this, &Mixer_UI::strip_scroller_button_event));
vca_label_bar.set_size_request (-1, 16 + 1); /* must match height in GroupTabs::set_size_request() + 1 border px*/
vca_vpacker.pack_start (vca_label_bar, false, false);
vca_hpacker.signal_scroll_event().connect (sigc::mem_fun (*this, &Mixer_UI::on_vca_scroll_event), false);
vca_scroller.add (vca_hpacker);
vca_scroller.set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_AUTOMATIC);
vca_scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
vca_scroller_base.set_name (X_("MixerWindow"));
vca_scroller_base.signal_button_press_event().connect (sigc::mem_fun(*this, &Mixer_UI::strip_scroller_button_event));
vca_scroller_base.signal_button_release_event().connect (sigc::mem_fun(*this, &Mixer_UI::strip_scroller_button_event));
vca_vpacker.pack_start (vca_scroller, true, true);
vca_hpacker.signal_scroll_event().connect (sigc::mem_fun (*this, &Mixer_UI::on_vca_scroll_event), false);
vca_scroller.add (vca_hpacker);
vca_scroller.set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_AUTOMATIC);
inner_pane.add (scroller);
inner_pane.add (vca_vpacker);
vca_vpacker.pack_start (vca_scroller, true, true);
global_hpacker.pack_start (inner_pane, true, true);
global_hpacker.pack_start (out_packer, false, false);
inner_pane.add (scroller);
inner_pane.add (vca_vpacker);
list_hpane.set_check_divider_position (true);
list_hpane.add (list_vpacker);
list_hpane.add (global_hpacker);
list_hpane.set_child_minsize (list_vpacker, 30);
global_hpacker.pack_start (inner_pane, true, true);
global_hpacker.pack_start (out_packer, false, false);
rhs_pane1.set_divider (0, .6);
rhs_pane2.set_divider (0, .7);
list_hpane.set_divider (0, .2);
inner_pane.set_divider (0, .8);
list_hpane.set_check_divider_position (true);
list_hpane.add (list_vpacker);
list_hpane.add (global_hpacker);
list_hpane.set_child_minsize (list_vpacker, 30);
rhs_pane1.set_drag_cursor (*PublicEditor::instance().cursors()->expand_up_down);
rhs_pane2.set_drag_cursor (*PublicEditor::instance().cursors()->expand_up_down);
list_hpane.set_drag_cursor (*PublicEditor::instance().cursors()->expand_left_right);
inner_pane.set_drag_cursor (*PublicEditor::instance().cursors()->expand_left_right);
rhs_pane1.set_divider (0, .6);
rhs_pane2.set_divider (0, .7);
list_hpane.set_divider (0, .2);
inner_pane.set_divider (0, .8);
_content.pack_start (list_hpane, true, true);
rhs_pane1.set_drag_cursor (*PublicEditor::instance().cursors()->expand_up_down);
rhs_pane2.set_drag_cursor (*PublicEditor::instance().cursors()->expand_up_down);
list_hpane.set_drag_cursor (*PublicEditor::instance().cursors()->expand_left_right);
inner_pane.set_drag_cursor (*PublicEditor::instance().cursors()->expand_left_right);
_content.pack_start (list_hpane, true, true);
} else {
_content.pack_start (scroller, true, true);
}
update_title ();
@ -429,7 +437,9 @@ Mixer_UI::Mixer_UI ()
ARDOUR_UI::instance()->Escape.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::escape, this), gui_context());
#ifndef DEFER_PLUGIN_SELECTOR_LOAD
_plugin_selector = new PluginSelector (PluginManager::instance ());
if (!Profile->get_livetrax()) {
_plugin_selector = new PluginSelector (PluginManager::instance ());
}
#else
#error implement deferred Plugin-Favorite list
#endif
@ -515,8 +525,17 @@ Mixer_UI::show_window ()
ms->parameter_changed (X_("mixer-element-visibility"));
}
/* force focus into main area */
scroller_base.grab_focus ();
if (!Profile->get_livetrax()) {
/* force focus into main area */
scroller_base.grab_focus ();
}
}
bool
Mixer_UI::scroller_enter (GdkEventCrossing* ev)
{
steal_focus ();
return false;
}
void
@ -1285,7 +1304,9 @@ Mixer_UI::set_session (Session* sess)
return;
}
refill_favorite_plugins();
if (!Profile->get_livetrax()) {
refill_favorite_plugins();
}
XMLNode* node = ARDOUR_UI::instance()->mixer_settings();
set_state (*node, 0);
@ -2293,7 +2314,7 @@ Mixer_UI::toggle_mixer_list ()
void
Mixer_UI::showhide_mixer_list (bool yn)
{
if (yn) {
if (!Profile->get_livetrax() && yn) {
list_vpacker.show ();
} else {
list_vpacker.hide ();
@ -2539,7 +2560,9 @@ Mixer_UI::set_state (const XMLNode& node, int version)
{
bool yn;
Tabbable::set_state (node, version);
if (!Profile->get_livetrax()) {
Tabbable::set_state (node, version);
}
if (node.get_property ("narrow-strips", yn)) {
if (yn) {
@ -2683,7 +2706,9 @@ Mixer_UI::get_state () const
{
XMLNode* node = new XMLNode (X_("Mixer"));
node->add_child_nocopy (Tabbable::get_state());
if (!Profile->get_livetrax()) {
node->add_child_nocopy (Tabbable::get_state());
}
node->set_property (X_("mixer-rhs-pane1-pos"), rhs_pane1.get_divider());
node->set_property (X_("mixer-rhs_pane2-pos"), rhs_pane2.get_divider());
@ -2915,6 +2940,11 @@ Mixer_UI::set_route_group_activation (RouteGroup* g, bool a)
PluginSelector*
Mixer_UI::plugin_selector()
{
if (Profile->get_livetrax()) {
/* no plugins, no plugin selector */
return nullptr;
}
#ifdef DEFER_PLUGIN_SELECTOR_LOAD
if (!_plugin_selector)
_plugin_selector = new PluginSelector (PluginManager::instance());
@ -3167,6 +3197,10 @@ Mixer_UI::save_favorite_ui_state (const TreeModel::iterator& iter, const TreeMod
void
Mixer_UI::plugin_list_mode_changed ()
{
if (Profile->get_livetrax()) {
return;
}
if (plugin_list_mode () == PLM_Favorite) {
PBD::Unwinder<bool> uw (ignore_plugin_refill, true);
favorite_plugins_search_hbox.show ();
@ -3180,6 +3214,10 @@ Mixer_UI::plugin_list_mode_changed ()
void
Mixer_UI::plugin_search_entry_changed ()
{
if (Profile->get_livetrax()) {
return;
}
if (plugin_list_mode () == PLM_Favorite) {
refill_favorite_plugins ();
}
@ -3194,6 +3232,10 @@ Mixer_UI::plugin_search_clear_button_clicked ()
void
Mixer_UI::refiller (PluginInfoList& result, const PluginInfoList& plugs)
{
if (Profile->get_livetrax()) {
return;
}
PluginManager& manager (PluginManager::instance());
PluginListMode plm = plugin_list_mode ();
@ -3240,6 +3282,10 @@ Mixer_UI::refiller (PluginInfoList& result, const PluginInfoList& plugs)
void
Mixer_UI::refill_favorite_plugins ()
{
if (Profile->get_livetrax()) {
return;
}
if (ignore_plugin_refill) {
return;
}
@ -4430,3 +4476,11 @@ Mixer_UI::sync_surround_action ()
Glib::RefPtr<Action> surround_export = ActionManager::get_action (X_("Main"), X_("SurroundExport"));
surround_export->set_sensitive (have_sm && _session->vapor_export_barrier ());
}
void
Mixer_UI::steal_focus ()
{
if (Profile->get_livetrax()) {
scroller_base.grab_focus ();
}
}

View File

@ -169,6 +169,8 @@ public:
void toggle_monitor_action (ARDOUR::MonitorChoice monitor_choice, bool group_override = false, bool all = false);
void steal_focus ();
protected:
void set_axis_targets_for_operation ();
PBD::ControllableSet selected_gaincontrols ();
@ -234,6 +236,7 @@ private:
void scroller_drag_data_received (const Glib::RefPtr<Gdk::DragContext>&, int, int, const Gtk::SelectionData&, guint, guint);
bool strip_scroller_button_event (GdkEventButton*);
bool scroller_enter (GdkEventCrossing*);
void scroll_left ();
void scroll_right ();
void vca_scroll_left ();

View File

@ -35,6 +35,7 @@
#include "gtkmm2ext/colors.h"
#include "ardour/dB.h"
#include "ardour/profile.h"
#include "ardour/rc_configuration.h"
#include "ardour/session.h"
#include "ardour/types.h"
@ -1107,20 +1108,20 @@ OptionEditor::add_path_to_treeview (std::string const & pn, Gtk::Widget& widget)
}
/** Add a component to a given page.
* @param pn Page name (will be created if it doesn't already exist)
* @param page_name Page name (will be created if it doesn't already exist)
* @param o Component.
*/
void
OptionEditor::add_option (std::string const & pn, OptionEditorComponent* o)
OptionEditor::add_option (std::string const & page_name, OptionEditorComponent* o)
{
if (_pages.find (pn) == _pages.end()) {
OptionEditorPage* oep = new OptionEditorPage (_notebook, pn);
_pages[pn] = oep;
if (_pages.find (page_name) == _pages.end()) {
OptionEditorPage* oep = new OptionEditorPage (_notebook, page_name);
_pages[page_name] = oep;
add_path_to_treeview (pn, oep->box);
add_path_to_treeview (page_name, oep->box);
}
OptionEditorPage* p = _pages[pn];
OptionEditorPage* p = _pages[page_name];
p->components.push_back (o);
o->add_to_page (p);
@ -1216,7 +1217,12 @@ OptionEditorWindow::OptionEditorWindow (PBD::Configuration* c, string const& str
hpacker.set_border_width (4);
Frame* f = manage (new Frame ());
f->add (treeview());
if (Profile->get_livetrax()) {
f->add (button_box());
} else {
f->add (treeview());
}
f->set_shadow_type (Gtk::SHADOW_OUT);
f->set_border_width (0);
vpacker.pack_start (*f, true, true);

View File

@ -726,6 +726,7 @@ protected:
PBD::Configuration* _config;
Gtk::Notebook& notebook() { return _notebook; }
Gtk::TreeView& treeview() { return option_treeview; }
Gtk::VBox& button_box() { return _button_box; }
class OptionColumns : public Gtk::TreeModel::ColumnRecord
{
@ -775,6 +776,7 @@ private:
PBD::ScopedConnection config_connection;
Gtk::Notebook _notebook;
Gtk::TreeView option_treeview;
Gtk::VBox _button_box;
std::map<std::string, OptionEditorPage*> _pages;
void add_path_to_treeview (std::string const &, Gtk::Widget&);

View File

@ -33,8 +33,10 @@
#include "ardour/pannable.h"
#include "ardour/panner.h"
#include "ardour/panner_shell.h"
#include "ardour/profile.h"
#include "ardour/session.h"
#include "widgets/ardour_knob.h"
#include "widgets/tooltips.h"
#include "gain_meter.h"
@ -55,24 +57,27 @@ using namespace Gtkmm2ext;
using namespace Gtk;
PannerUI::PannerUI (Session* s)
: _current_nouts (-1)
: in_pan_update (false)
, _current_nouts (-1)
, _current_nins (-1)
, _current_uri ("")
, _send_mode (false)
, twod_panner (nullptr)
, big_window (nullptr)
, _stereo_panner (nullptr)
, _mono_panner (nullptr)
, _knob_panner (nullptr)
, _ignore_width_change (false)
, _ignore_position_change (false)
, pan_astate_menu (nullptr)
, pan_astyle_menu (nullptr)
, pan_automation_state_button ("")
, _panner_list()
, pan_menu (nullptr)
, bypass_menu_item (nullptr)
, send_link_menu_item (nullptr)
{
set_session (s);
pan_menu = 0;
pan_astate_menu = 0;
pan_astyle_menu = 0;
in_pan_update = false;
_stereo_panner = 0;
_mono_panner = 0;
_ignore_width_change = false;
_ignore_position_change = false;
pan_automation_state_button.set_name ("MixerAutomationPlaybackButton");
ArdourWidgets::set_tooltip (pan_automation_state_button, _("Pan automation mode"));
@ -86,10 +91,7 @@ PannerUI::PannerUI (Session* s)
pan_vbox.set_spacing (2);
pack_start (pan_vbox, true, true);
twod_panner = 0;
big_window = 0;
set_width(Narrow);
set_width (Narrow);
}
void
@ -121,6 +123,9 @@ PannerUI::set_panner (std::shared_ptr<PannerShell> ps, std::shared_ptr<Panner> p
delete _mono_panner;
_mono_panner = 0;
delete _knob_panner;
_knob_panner = 0;
if (!_panner) {
return;
}
@ -202,6 +207,7 @@ PannerUI::~PannerUI ()
delete pan_astate_menu;
delete _stereo_panner;
delete _mono_panner;
delete _knob_panner;
}
void
@ -219,11 +225,9 @@ PannerUI::setup_pan ()
assert (_panshell);
if (nouts == _current_nouts
&& nins == _current_nins
&& _current_uri == _panshell->panner_gui_uri()
)
{
if (nouts == _current_nouts &&
nins == _current_nins &&
_current_uri == _panshell->panner_gui_uri()) {
return;
}
@ -239,6 +243,8 @@ PannerUI::setup_pan ()
_stereo_panner = 0;
delete _mono_panner;
_mono_panner = 0;
delete _knob_panner;
_knob_panner = 0;
if (!_panner) {
delete big_window;
@ -283,20 +289,35 @@ PannerUI::setup_pan ()
std::shared_ptr<Pannable> pannable = _panner->pannable();
std::shared_ptr<AutomationControl> ac = pannable->pan_azimuth_control;
_mono_panner = new MonoPanner (_panshell);
if (ARDOUR::Profile->get_livetrax()) {
_mono_panner->StartGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch),
std::weak_ptr<AutomationControl> (ac)));
_mono_panner->StopGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch),
std::weak_ptr<AutomationControl>(ac)));
_knob_panner = new ArdourWidgets::ArdourKnob (ArdourWidgets::ArdourKnob::default_elements,
ArdourWidgets::ArdourCtrlBase::Flags (ArdourWidgets::ArdourCtrlBase::Detent|ArdourWidgets::ArdourCtrlBase::ArcToZero));
_mono_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event));
_knob_panner->set_controllable (ac);
update_pan_sensitive ();
_knob_panner->show ();
_knob_panner->set_size_request (-1, 5 * ceilf(7.f * scale));
_knob_panner->set_name ("monitor section knob");
pan_vbox.pack_start (*_knob_panner, false, false);
_mono_panner->set_size_request (-1, 5 * ceilf(7.f * scale));
_mono_panner->set_send_drawing_mode (_send_mode);
} else {
update_pan_sensitive ();
pan_vbox.pack_start (*_mono_panner, false, false);
_mono_panner = new MonoPanner (_panshell);
_mono_panner->StartGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch),
std::weak_ptr<AutomationControl> (ac)));
_mono_panner->StopGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch),
std::weak_ptr<AutomationControl>(ac)));
_mono_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event));
_mono_panner->set_size_request (-1, 5 * ceilf(7.f * scale));
_mono_panner->set_send_drawing_mode (_send_mode);
update_pan_sensitive ();
pan_vbox.pack_start (*_mono_panner, false, false);
}
}
else if (_current_uri == "http://ardour.org/plugin/panner_vbap#ui")
{

View File

@ -54,6 +54,10 @@ namespace Gtk {
class Menuitem;
}
namespace ArdourWidgets {
class ArdourKnob;
}
class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr
{
public:
@ -106,6 +110,7 @@ private:
StereoPanner* _stereo_panner;
MonoPanner* _mono_panner;
ArdourWidgets::ArdourKnob* _knob_panner;
bool _ignore_width_change;
bool _ignore_position_change;

View File

@ -0,0 +1,154 @@
/*
* Copyright (C) 2022 Robin Gareus <robin@gareus.org>
*
* 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 "ardour/plug_insert_base.h"
#include "ardour/plugin_manager.h"
#include "gui_thread.h"
#include "plugin_ui.h"
#include "plugin_window_proxy.h"
#include "pbd/i18n.h"
using namespace ARDOUR;
using namespace Gtk;
using namespace Gtkmm2ext;
PluginWindowProxy::PluginWindowProxy (std::string const& name, std::string const& title, std::weak_ptr<PlugInsertBase> plugin)
: WM::ProxyBase (name, std::string ())
, _pib (plugin)
, _title (title)
, _is_custom (true)
, _want_custom (true)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return;
}
p->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&PluginWindowProxy::plugin_going_away, this), gui_context ());
}
PluginWindowProxy::~PluginWindowProxy ()
{
_window = 0;
}
Gtk::Window*
PluginWindowProxy::get (bool create)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return 0;
}
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (!_window) {
if (!create) {
return 0;
}
_is_custom = _want_custom;
_window = new PluginUIWindow (p, false, _is_custom);
if (_window) {
_window->set_title (generate_processor_title (p));
setup ();
_window->show_all ();
}
}
return _window;
}
void
PluginWindowProxy::show_the_right_window ()
{
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (_window) {
_window->unset_transient_for ();
}
toggle ();
}
int
PluginWindowProxy::set_state (const XMLNode& node, int)
{
XMLNodeList children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
while (i != children.end ()) {
std::string name;
if ((*i)->name () == X_("Window") && (*i)->get_property (X_("name"), name) && name == _name) {
break;
}
++i;
}
if (i != children.end ()) {
(*i)->get_property (X_("custom-ui"), _want_custom);
}
return ProxyBase::set_state (node, 0);
}
XMLNode&
PluginWindowProxy::get_state () const
{
XMLNode* node;
node = &ProxyBase::get_state ();
node->set_property (X_("custom-ui"), _is_custom);
return *node;
}
void
PluginWindowProxy::plugin_going_away ()
{
delete _window;
_window = 0;
WM::Manager::instance ().remove (this);
drop_connections ();
delete this;
}
std::string
PluginWindowProxy::generate_processor_title (std::shared_ptr<PlugInsertBase> p)
{
std::string maker = p->plugin()->maker() ? p->plugin()->maker() : "";
std::string::size_type email_pos;
if ((email_pos = maker.find_first_of ('<')) != std::string::npos) {
maker = maker.substr (0, email_pos - 1);
}
if (maker.length() > 32) {
maker = maker.substr (0, 32);
maker += " ...";
}
std::string type = PluginManager::plugin_type_name (p->type ());
auto so = std::dynamic_pointer_cast<SessionObject> (p);
assert (so);
return string_compose(_("%1: %2 (by %3) [%4]"), _title, so->name(), maker, type);
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2022,2024 Robin Gareus <robin@gareus.org>
*
* 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.
*/
#ifndef _gtkardour_plugin_window_proxy_h_
#define _gtkardour_plugin_window_proxy_h_
#include "ardour_window.h"
#include "window_manager.h"
#include "pbd/signals.h"
namespace Gtk
{
class Window;
}
namespace ARDOUR
{
class PlugInsertBase;
}
class PluginWindowProxy : public WM::ProxyBase, public PBD::ScopedConnectionList
{
public:
PluginWindowProxy (std::string const&, std::string const&, std::weak_ptr<ARDOUR::PlugInsertBase>);
~PluginWindowProxy ();
Gtk::Window* get (bool create = false);
void show_the_right_window ();
ARDOUR::SessionHandlePtr* session_handle ()
{
return 0;
}
void set_custom_ui_mode (bool use_custom)
{
_want_custom = use_custom;
}
int set_state (const XMLNode&, int);
XMLNode& get_state () const;
std::string generate_processor_title (std::shared_ptr<ARDOUR::PlugInsertBase>);
private:
void plugin_going_away ();
std::weak_ptr<ARDOUR::PlugInsertBase> _pib;
std::string _title;
bool _is_custom;
bool _want_custom;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -462,7 +462,9 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp
if (type == DataType::AUDIO || type == DataType::NIL) {
if (!inputs) {
program->add_bundle (session->the_auditioner()->output()->bundle());
if (session->the_auditioner()) {
program->add_bundle (session->the_auditioner()->output()->bundle());
}
if (session->click_io()) {
program->add_bundle (session->click_io()->bundle());
}

View File

@ -35,6 +35,8 @@ ARDOUR::DataType PublicEditor::pbdid_dragged_dt = ARDOUR::DataType::NIL;
PublicEditor::PublicEditor (Gtk::Widget& content)
: Tabbable (content, _("Editor"), X_("editor"))
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
{
_suspend_route_redisplay_counter.store (0);
}

View File

@ -105,6 +105,7 @@ class TempoMarker;
class TimeAxisView;
class VerboseCursor;
struct SelectionRect;
class SelectionPropertiesBox;
class DisplaySuspender;
@ -599,6 +600,14 @@ public:
PBD::Signal0<void> MouseModeChanged;
Gtkmm2ext::Bindings* bindings;
Gtkmm2ext::Bindings* midi_bindings;
virtual SelectionPropertiesBox& properties_box() const = 0;
Gtk::HBox* mouse_mode_hbox;
Gtk::HBox _zoom_box;
/** the adjustment that controls the overall editor vertical scroll position */
Gtk::Adjustment vertical_adjustment;
Gtk::Adjustment horizontal_adjustment;
protected:
friend class DisplaySuspender;

File diff suppressed because it is too large Load Diff

View File

@ -1,94 +1,6 @@
/*
* Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2012-2017 Robin Gareus <robin@gareus.org>
* Copyright (C) 2012-2018 Paul Davis <paul@linuxaudiosystems.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.
*/
#ifndef __gtk_ardour_rc_option_editor_h__
#define __gtk_ardour_rc_option_editor_h__
#include "widgets/tabbable.h"
#include "option_editor.h"
#include "visibility_group.h"
#include "transport_masters_dialog.h"
/** @file rc_option_editor.h
* @brief Editing of options which are obtained from and written back to one of the .rc files.
*
* This is subclassed from OptionEditor. Simple options (e.g. boolean and simple choices)
* are expressed using subclasses of Option. More complex UI elements are represented
* using individual classes subclassed from OptionEditorBox.
*/
/** Editor for options which are obtained from and written back to one of the .rc files. */
class RCOptionEditor : public OptionEditorContainer, public ARDOUR::SessionHandlePtr, public ArdourWidgets::Tabbable
{
public:
RCOptionEditor ();
void set_session (ARDOUR::Session*);
Gtk::Window* use_own_window (bool and_fill_it);
XMLNode& get_state () const;
bool on_key_release_event (GdkEventKey*);
private:
void parameter_changed (std::string const &);
void ltc_generator_volume_changed ();
ARDOUR::RCConfiguration* _rc_config;
BoolOption* _solo_control_is_listen_control;
ComboOption<ARDOUR::ListenPosition>* _listen_position;
VisibilityGroup _mixer_strip_visibility;
BoolOption* _sync_framerate;
HSliderOption* _ltc_volume_slider;
Gtk::Adjustment* _ltc_volume_adjustment;
BoolOption* _ltc_send_continuously;
BoolOption* _plugin_prefer_inline;
BoolOption* _cairo_image_surface;
TransportMastersWidget _transport_masters_widget;
PBD::ScopedConnection parameter_change_connection;
PBD::ScopedConnection engine_started_connection;
void show_audio_setup ();
void show_transport_masters ();
void reset_clip_library_dir ();
EntryOption* mrl_option;
EntryOption* mru_option;
std::string get_default_lower_midi_note ();
bool set_default_lower_midi_note (std::string);
std::string get_default_upper_midi_note ();
bool set_default_upper_midi_note (std::string);
/* plugin actions */
void plugin_scan_refresh ();
void plugin_reset_stats ();
void clear_vst2_cache ();
void clear_vst2_blacklist ();
void clear_vst3_cache ();
void clear_vst3_blacklist ();
void clear_au_cache ();
void clear_au_blacklist ();
void edit_vst_path (std::string const&, std::string const&, sigc::slot<std::string>, sigc::slot<bool, std::string>);
};
#endif /* __gtk_ardour_rc_option_editor_h__ */
#ifdef LIVETRAX
#include "livetrax_rc_option_editor.h"
#else
#include "ardour_rc_option_editor.h"
#endif

View File

@ -28,18 +28,31 @@
#include "pbd/memento_command.h"
#include "pbd/stateful_diff_command.h"
#include "pbd/unwind.h"
#include "gtkmm2ext/dndtreeview.h"
#include "widgets/tooltips.h"
#include "ardour/plugin_manager.h"
#include "ardour/region.h"
#include "ardour/region_fx_plugin.h"
#include "ardour/session.h"
#include "ardour/source.h"
#include "ardour_message.h"
#include "ardour_ui.h"
#include "clock_group.h"
#include "main_clock.h"
#include "context_menu_helper.h"
#include "gui_thread.h"
#include "keyboard.h"
#include "main_clock.h"
#include "mixer_ui.h"
#include "new_plugin_preset_dialog.h"
#include "region_editor.h"
#include "region_view.h"
#include "plugin_selector.h"
#include "plugin_window_proxy.h"
#include "public_editor.h"
#include "pbd/i18n.h"
@ -49,11 +62,11 @@ using namespace PBD;
using namespace std;
using namespace Gtkmm2ext;
RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
RegionEditor::RegionEditor (Session* s, RegionView* rv)
: ArdourDialog (_("Region"))
, _table (9, 2)
, _table (9, 3)
, _table_row (0)
, _region (r)
, _region (rv->region ())
, name_label (_("Name:"))
, audition_button (_("Audition"))
, _clock_group (new ClockGroup)
@ -64,11 +77,12 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
, sync_offset_absolute_clock (X_("regionsyncoffsetabsolute"), true, "", true, false)
/* XXX cannot file start yet */
, start_clock (X_("regionstart"), true, "", false, false)
, _region_fx_box (_region)
, _sources (1)
{
set_session (s);
switch (r->time_domain()) {
switch (_region->time_domain()) {
case Temporal::AudioTime:
/* XXX check length of region and choose samples or minsec */
_clock_group->set_clock_mode (AudioClock::MinSec);
@ -113,6 +127,8 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
start_label.set_name ("RegionEditorLabel");
start_label.set_text (_("File start:"));
_sources_label.set_name ("RegionEditorLabel");
region_fx_label.set_text (_("Region Effects"));
region_fx_label.set_name ("RegionEditorLabel");
if (_region->sources().size() > 1) {
_sources_label.set_text (_("Sources:"));
@ -170,6 +186,9 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
_table.attach (_sources, 1, 2, _table_row, _table_row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
++_table_row;
_table.attach (region_fx_label, 2, 3, 0, 1, Gtk::FILL, Gtk::FILL);
_table.attach (_region_fx_box, 2, 3, 1, _table_row + 2, Gtk::FILL, Gtk::FILL);
get_vbox()->pack_start (_table, true, true);
add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_ACCEPT);
@ -190,6 +209,9 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
assert (t);
t->property_ellipsize() = Pango::ELLIPSIZE_END;
region_fx_label.set_no_show_all ();
_region_fx_box.set_no_show_all ();
show_all();
name_changed ();
@ -203,9 +225,16 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
bounds_changed (change);
_region->PropertyChanged.connect (state_connection, invalidator (*this), boost::bind (&RegionEditor::region_changed, this, _1), gui_context());
_region->RegionFxChanged.connect (region_connection, invalidator (*this), boost::bind (&RegionEditor::region_fx_changed, this), gui_context ());
spin_arrow_grab = false;
/* for now only audio region effects are supported */
if (std::dynamic_pointer_cast<AudioRegion> (_region)) {
region_fx_label.show ();
_region_fx_box.show ();
}
connect_editor_events ();
}
@ -238,6 +267,12 @@ RegionEditor::region_changed (const PBD::PropertyChange& what_changed)
}
}
void
RegionEditor::region_fx_changed ()
{
_region_fx_box.redisplay_plugins ();
}
gint
RegionEditor::bpressed (GdkEventButton* ev, Gtk::SpinButton* /*but*/, void (RegionEditor::*/*pmf*/)())
{
@ -469,3 +504,541 @@ RegionEditor::handle_response (int)
{
hide ();
}
/* ****************************************************************************/
static std::list<Gtk::TargetEntry>
drop_targets ()
{
std::list<Gtk::TargetEntry> tmp;
tmp.push_back (Gtk::TargetEntry ("x-ardour/region-fx", Gtk::TARGET_SAME_APP)); // re-order
tmp.push_back (Gtk::TargetEntry ("x-ardour/plugin.info", Gtk::TARGET_SAME_APP)); // from plugin-manager
tmp.push_back (Gtk::TargetEntry ("x-ardour/plugin.favorite", Gtk::TARGET_SAME_APP)); // from sidebar
return tmp;
}
static std::list<Gtk::TargetEntry>
drag_targets ()
{
std::list<Gtk::TargetEntry> tmp;
tmp.push_back (Gtk::TargetEntry ("x-ardour/region-fx", Gtk::TARGET_SAME_APP)); // re-order
tmp.push_back (Gtk::TargetEntry ("x-ardour/plugin.preset", Gtk::TARGET_SAME_APP)); // to sidebar (optional preset)
return tmp;
}
RegionEditor::RegionFxBox::RegionFxBox (std::shared_ptr<ARDOUR::Region> r)
: _region (r)
, _display (drop_targets ())
, _no_redisplay (false)
, _placement (-1)
{
_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
_scroller.set_name ("ProcessorScroller");
_scroller.add (_display);
pack_start (_scroller, true, true);
_display.set_can_focus ();
_display.set_name ("ProcessorList");
_display.set_data ("regionfxbox", this);
_display.set_size_request (104, -1); // TODO UI scale
_display.set_spacing (0);
_display.ButtonPress.connect (sigc::mem_fun (*this, &RegionFxBox::fxe_button_press_event));
_display.ButtonRelease.connect (sigc::mem_fun (*this, &RegionFxBox::fxe_button_release_event));
_display.Reordered.connect (sigc::mem_fun (*this, &RegionFxBox::reordered));
_display.DropFromAnotherBox.connect (sigc::mem_fun (*this, &RegionFxBox::object_drop));
_display.DropFromExternal.connect (sigc::mem_fun (*this, &RegionFxBox::plugin_drop));
_display.signal_key_press_event ().connect (sigc::mem_fun (*this, &RegionFxBox::on_key_press), false);
_scroller.show ();
_display.show ();
redisplay_plugins ();
}
bool
RegionEditor::RegionFxBox::use_plugins (SelectedPlugins const& plugins)
{
int errors = 0;
{
PBD::Unwinder<bool> uw (_no_redisplay, true);
for (auto const& p : plugins) {
std::shared_ptr<RegionFxPlugin> pos;
if (_placement >= 0) {
pos = _region->nth_plugin (_placement++);
}
if (!_region->add_plugin (std::shared_ptr<RegionFxPlugin> (new RegionFxPlugin (_region->session (), _region->time_domain (), p)), pos)) {
++errors;
}
}
}
redisplay_plugins ();
if (errors) {
notify_plugin_load_fail (errors);
}
return false;
}
void
RegionEditor::RegionFxBox::redisplay_plugins ()
{
if (_no_redisplay) {
return;
}
_display.clear ();
_region->foreach_plugin (sigc::mem_fun (*this, &RegionFxBox::add_fx_to_display));
}
void
RegionEditor::RegionFxBox::add_fx_to_display (std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> fx (wfx.lock ());
if (!fx) {
return;
}
RegionFxEntry* e = new RegionFxEntry (fx);
_display.add_child (e, drag_targets ());
}
bool
RegionEditor::RegionFxBox::fxe_button_press_event (GdkEventButton* ev, RegionFxEntry* child)
{
if (child) {
std::weak_ptr<RegionFxPlugin> wfx (std::weak_ptr<RegionFxPlugin> (child->region_fx_plugin ()));
if (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS)) {
if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
show_plugin_gui (wfx, false);
} else {
show_plugin_gui (wfx, true);
}
return true;
}
if (Keyboard::is_context_menu_event (ev)) {
using namespace Gtk::Menu_Helpers;
PluginSelector* ps = Mixer_UI::instance ()->plugin_selector ();
ps->set_interested_object (*this);
Gtk::Menu* m = ARDOUR_UI_UTILS::shared_popup_menu ();
MenuList& items = m->items ();
items.push_back (MenuElem (_("New Plugin")));
Gtk::MenuItem& npm = items.back ();
npm.set_submenu (*ps->plugin_menu ());
std::shared_ptr<Plugin> plugin = child->region_fx_plugin ()->plugin ();
items.push_back (SeparatorElem ());
items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, true)));
items.back ().set_sensitive (plugin->has_editor ());
items.push_back (MenuElem (_("Edit with generic controls..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, false)));
Gtk::Menu* automation_menu = manage (new Gtk::Menu);
MenuList& ac_items (automation_menu->items ());
for (size_t i = 0; i < plugin->parameter_count (); ++i) {
if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) {
continue;
}
const Evoral::Parameter param (PluginAutomation, 0, i);
std::string label = plugin->describe_parameter (param);
if (label == X_("latency") || label == X_("hidden")) {
continue;
}
std::shared_ptr<ARDOUR::AutomationControl> c (std::dynamic_pointer_cast<ARDOUR::AutomationControl> (child->region_fx_plugin ()->control (param)));
if (c && c->flags () & (Controllable::HiddenControl | Controllable::NotAutomatable)) {
continue;
}
std::weak_ptr<ARDOUR::AutomationControl> wac (c);
bool play = c->automation_state () == Play;
ac_items.push_back (CheckMenuElem (label));
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&ac_items.back ());
cmi->set_active (play);
cmi->signal_activate ().connect ([wac, play] () {
std::shared_ptr<ARDOUR::AutomationControl> ac = wac.lock ();
if (ac) {
ac->set_automation_state (play ? ARDOUR::Off : Play);
}
});
}
if (!ac_items.empty ()) {
items.push_back (SeparatorElem ());
items.push_back (MenuElem ("Automation Enable", *automation_menu));
} else {
delete automation_menu;
}
items.push_back (SeparatorElem ());
items.push_back (MenuElem (_("Delete"), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::queue_delete_region_fx), wfx)));
m->signal_unmap ().connect ([this, &npm] () { npm.remove_submenu (); _display.remove_placeholder (); });
m->popup (ev->button, ev->time);
int x, y;
_display.get_pointer (x, y);
_placement = _display.add_placeholder (y);
return true;
}
return false;
}
if (Keyboard::is_context_menu_event (ev)) {
_placement = -1;
using namespace Gtk::Menu_Helpers;
PluginSelector* ps = Mixer_UI::instance ()->plugin_selector ();
ps->set_interested_object (*this);
Gtk::Menu* m = ARDOUR_UI_UTILS::shared_popup_menu ();
MenuList& items = m->items ();
items.push_back (MenuElem (_("New Plugin")));
Gtk::MenuItem& npm = items.back ();
npm.set_submenu (*ps->plugin_menu ());
m->signal_unmap ().connect ([&npm] () { npm.remove_submenu (); });
m->popup (ev->button, ev->time);
return true;
} else if (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) {
_placement = -1;
PluginSelector* ps = Mixer_UI::instance ()->plugin_selector ();
ps->set_interested_object (*this);
ps->show_manager ();
return true;
}
return false;
}
bool
RegionEditor::RegionFxBox::fxe_button_release_event (GdkEventButton* ev, RegionFxEntry* child)
{
if (child && Keyboard::is_delete_event (ev)) {
queue_delete_region_fx (std::weak_ptr<RegionFxPlugin> (child->region_fx_plugin ()));
}
return false;
}
bool
RegionEditor::RegionFxBox::on_key_press (GdkEventKey* ev)
{
switch (ev->keyval) {
case GDK_KEY_Delete:
break;
case GDK_KEY_BackSpace:
break;
default:
return false;
}
for (auto const& i : _display.selection (true)) {
queue_delete_region_fx (std::weak_ptr<RegionFxPlugin> (i->region_fx_plugin ()));
}
return true;
}
void
RegionEditor::RegionFxBox::reordered ()
{
Region::RegionFxList fxl;
for (auto const& i : _display.children ()) {
fxl.push_back (i->region_fx_plugin ());
}
_region->reorder_plugins (fxl);
}
void
RegionEditor::RegionFxBox::queue_delete_region_fx (std::weak_ptr<ARDOUR::RegionFxPlugin> wfx)
{
Glib::signal_idle ().connect (sigc::bind (sigc::mem_fun (*this, &RegionFxBox::idle_delete_region_fx), wfx));
}
bool
RegionEditor::RegionFxBox::idle_delete_region_fx (std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> fx (wfx.lock ());
if (!fx) {
return false;
}
_region->remove_plugin (fx);
return false;
}
void
RegionEditor::RegionFxBox::notify_plugin_load_fail (uint32_t cnt)
{
assert (cnt > 0);
ArdourMessageDialog (_("Failed to load Region Effect Plugin"), false, Gtk::MESSAGE_ERROR).run ();
}
std::shared_ptr<RegionFxPlugin>
RegionEditor::RegionFxBox::find_drop_position (RegionFxEntry* pos)
{
std::shared_ptr<RegionFxPlugin> rv;
if (pos) {
rv = pos->region_fx_plugin ();
if (!rv) {
rv = _display.children ().front ()->region_fx_plugin ();
}
}
return rv;
}
void
RegionEditor::RegionFxBox::plugin_drop (Gtk::SelectionData const& data, RegionFxEntry* pos, Glib::RefPtr<Gdk::DragContext> const& context)
{
uint32_t errors = 0;
std::shared_ptr<RegionFxPlugin> at = find_drop_position (pos);
if (data.get_target () == "x-ardour/plugin.info") {
const void* d = data.get_data ();
const Gtkmm2ext::DnDTreeView<ARDOUR::PluginInfoPtr>* tv = reinterpret_cast<const Gtkmm2ext::DnDTreeView<ARDOUR::PluginInfoPtr>*> (d);
PluginInfoList nfos;
Gtk::TreeView* source;
tv->get_object_drag_data (nfos, &source);
for (auto const& i : nfos) {
PluginPtr p = (i)->load (_region->session ());
if (!_region->add_plugin (std::shared_ptr<RegionFxPlugin> (new RegionFxPlugin (_region->session (), _region->time_domain (), p)), at)) {
++errors;
}
}
} else if (data.get_target () == "x-ardour/plugin.favorite") {
const void* d = data.get_data ();
const Gtkmm2ext::DnDTreeView<ARDOUR::PluginPresetPtr>* tv = reinterpret_cast<const Gtkmm2ext::DnDTreeView<ARDOUR::PluginPresetPtr>*> (d);
PluginPresetList nfos;
Gtk::TreeView* source;
tv->get_object_drag_data (nfos, &source);
for (auto const& i : nfos) {
PluginPresetPtr ppp (i);
PluginInfoPtr pip = ppp->_pip;
PluginPtr p = pip->load (_region->session ());
if (!p) {
continue;
}
if (ppp->_preset.valid) {
p->load_preset (ppp->_preset);
}
if (!_region->add_plugin (std::shared_ptr<RegionFxPlugin> (new RegionFxPlugin (_region->session (), _region->time_domain (), p)), at)) {
++errors;
}
}
}
if (errors) {
notify_plugin_load_fail (errors);
}
}
void
RegionEditor::RegionFxBox::delete_dragged_plugins (Region::RegionFxList const& fxl)
{
{
PBD::Unwinder<bool> uw (_no_redisplay, true);
for (auto const& fx : fxl) {
_region->remove_plugin (fx);
}
}
redisplay_plugins ();
}
void
RegionEditor::RegionFxBox::object_drop (Gtkmm2ext::DnDVBox<RegionFxEntry>* source, RegionFxEntry* pos, Glib::RefPtr<Gdk::DragContext> const& context)
{
if (Gdk::ACTION_LINK == context->get_selected_action ()) {
std::list<RegionFxEntry*> children = source->selection ();
assert (children.size () == 1);
RegionFxEntry* other = *children.begin ();
assert (other->can_copy_state (pos));
std::shared_ptr<ARDOUR::RegionFxPlugin> othr = other->region_fx_plugin ();
std::shared_ptr<ARDOUR::RegionFxPlugin> self = pos->region_fx_plugin ();
PBD::ID id = self->id ();
XMLNode& state = othr->get_state ();
state.remove_property ("count");
/* Controllable and automation IDs should not be copied */
PBD::Stateful::ForceIDRegeneration force_ids;
self->set_state (state, Stateful::current_state_version);
self->update_id (id);
return;
}
std::shared_ptr<RegionFxPlugin> at = find_drop_position (pos);
uint32_t errors = 0;
Region::RegionFxList fxl;
for (auto const& i : source->selection (true)) {
fxl.push_back (i->region_fx_plugin ());
}
for (auto const& i : fxl) {
XMLNode& state = i->get_state ();
state.remove_property ("count");
PBD::Stateful::ForceIDRegeneration force_ids;
std::shared_ptr<RegionFxPlugin> rfx (new RegionFxPlugin (_region->session (), _region->time_domain ()));
rfx->set_state (state, Stateful::current_state_version);
if (!_region->add_plugin (rfx, at)) {
++errors;
}
delete &state;
}
if ((context->get_suggested_action () == Gdk::ACTION_MOVE) && source) {
RegionFxBox* other = reinterpret_cast<RegionFxBox*> (source->get_data ("regionfxbox"));
if (other) {
other->delete_dragged_plugins (fxl);
}
}
if (errors) {
notify_plugin_load_fail (errors);
}
}
void
RegionEditor::RegionFxBox::show_plugin_gui (std::weak_ptr<RegionFxPlugin> wfx, bool custom_ui)
{
std::shared_ptr<RegionFxPlugin> rfx (wfx.lock ());
if (!rfx) {
return;
}
PluginWindowProxy* pwp;
if (rfx->window_proxy ()) {
pwp = dynamic_cast<PluginWindowProxy*> (rfx->window_proxy ());
} else {
pwp = new PluginWindowProxy (string_compose ("RFX-%1", rfx->id ()), _region->name (), rfx);
const XMLNode* ui_xml = rfx->session ().extra_xml (X_("UI"));
if (ui_xml) {
pwp->set_state (*ui_xml, 0);
}
rfx->set_window_proxy (pwp);
WM::Manager::instance ().register_window (pwp);
RegionView* rv = PublicEditor::instance ().regionview_from_region (_region);
rv->RegionViewGoingAway.connect_same_thread (*pwp, [pwp] (RegionView*) { pwp->hide (); });
}
pwp->set_custom_ui_mode (custom_ui);
pwp->show_the_right_window ();
Gtk::Window* tlw = PublicEditor::instance ().current_toplevel ();
if (tlw) {
pwp->set_transient_for (*tlw);
}
}
/* ****************************************************************************/
RegionEditor::RegionFxEntry::RegionFxEntry (std::shared_ptr<RegionFxPlugin> rfx)
: _fx_btn (ArdourWidgets::ArdourButton::default_elements)
, _rfx (rfx)
{
_box.pack_start (_fx_btn, true, true);
_plugin_preset_pointer = PluginPresetPtr (new PluginPreset (rfx->plugin ()->get_info ()));
_fx_btn.set_fallthrough_to_parent (true);
_fx_btn.set_text (name ());
_fx_btn.set_active (true);
_fx_btn.set_name ("processor postfader");
if (rfx->plugin ()->has_editor ()) {
set_tooltip (_fx_btn, string_compose (_("<b>%1</b>\nDouble-click to show GUI.\n%2+double-click to show generic GUI."), name (), Keyboard::secondary_modifier_name ()));
} else {
set_tooltip (_fx_btn, string_compose (_("<b>%1</b>\nDouble-click to show generic GUI."), name ()));
}
_box.show ();
_fx_btn.show ();
}
std::string
RegionEditor::RegionFxEntry::name () const
{
return _rfx->name ();
}
bool
RegionEditor::RegionFxEntry::can_copy_state (Gtkmm2ext::DnDVBoxChild* o) const
{
RegionFxEntry* other = dynamic_cast<RegionFxEntry*> (o);
if (!other) {
return false;
}
std::shared_ptr<ARDOUR::RegionFxPlugin> othr = other->region_fx_plugin ();
std::shared_ptr<ARDOUR::RegionFxPlugin> self = region_fx_plugin ();
if (self->type () != othr->type ()) {
return false;
}
std::shared_ptr<Plugin> my_p = self->plugin ();
std::shared_ptr<Plugin> ot_p = othr->plugin ();
return my_p->unique_id () == ot_p->unique_id ();
}
void
RegionEditor::RegionFxEntry::set_visual_state (Gtkmm2ext::VisualState s, bool yn)
{
if (yn) {
_fx_btn.set_visual_state (Gtkmm2ext::VisualState (_fx_btn.visual_state () | s));
} else {
_fx_btn.set_visual_state (Gtkmm2ext::VisualState (_fx_btn.visual_state () & ~s));
}
}
bool
RegionEditor::RegionFxEntry::drag_data_get (Glib::RefPtr<Gdk::DragContext> const, Gtk::SelectionData& data)
{
/* compare to ProcessorEntry::drag_data_get */
if (data.get_target () != "x-ardour/plugin.preset") {
return false;
}
std::shared_ptr<Plugin> plugin = _rfx->plugin ();
assert (plugin);
PluginManager& manager (PluginManager::instance ());
bool fav = manager.get_status (_plugin_preset_pointer->_pip) == PluginManager::Favorite;
NewPluginPresetDialog d (plugin, string_compose (_("New Favorite Preset for \"%1\""), _plugin_preset_pointer->_pip->name), !fav);
_plugin_preset_pointer->_preset.valid = false;
switch (d.run ()) {
default:
case Gtk::RESPONSE_CANCEL:
data.set (data.get_target (), 8, NULL, 0);
return true;
break;
case Gtk::RESPONSE_NO:
break;
case Gtk::RESPONSE_ACCEPT:
if (d.name ().empty ()) {
break;
}
if (d.replace ()) {
plugin->remove_preset (d.name ());
}
Plugin::PresetRecord const r = plugin->save_preset (d.name ());
if (!r.uri.empty ()) {
_plugin_preset_pointer->_preset.uri = r.uri;
_plugin_preset_pointer->_preset.label = r.label;
_plugin_preset_pointer->_preset.user = r.user;
_plugin_preset_pointer->_preset.valid = r.valid;
}
}
data.set (data.get_target (), 8, (const guchar*)&_plugin_preset_pointer, sizeof (PluginPresetPtr));
return true;
}

View File

@ -27,6 +27,7 @@
#include <gtkmm/label.h>
#include <gtkmm/entry.h>
#include <gtkmm/box.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/togglebutton.h>
#include <gtkmm/button.h>
#include <gtkmm/arrow.h>
@ -36,34 +37,100 @@
#include <gtkmm/separator.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/listviewtext.h>
#include <gtkmm/scrolledwindow.h>
#include "gtkmm2ext/dndtreeview.h"
#include "gtkmm2ext/dndvbox.h"
#include "pbd/signals.h"
#include "audio_clock.h"
#include "ardour_dialog.h"
#include "plugin_interest.h"
#include "region_editor.h"
namespace ARDOUR {
class Region;
class Session;
class RegionFxPlugin;
}
class RegionView;
class ClockGroup;
class RegionEditor : public ArdourDialog
{
public:
RegionEditor (ARDOUR::Session*, std::shared_ptr<ARDOUR::Region>);
RegionEditor (ARDOUR::Session*, RegionView*);
virtual ~RegionEditor ();
protected:
virtual void region_changed (const PBD::PropertyChange&);
virtual void region_fx_changed ();
Gtk::Table _table;
int _table_row;
private:
class RegionFxEntry : public Gtkmm2ext::DnDVBoxChild, public sigc::trackable
{
public:
RegionFxEntry (std::shared_ptr<ARDOUR::RegionFxPlugin>);
Gtk::EventBox& action_widget () { return _fx_btn; }
Gtk::Widget& widget () { return _box; }
std::string drag_text () const { return name (); }
bool is_selectable() const { return true; }
bool can_copy_state (Gtkmm2ext::DnDVBoxChild*) const;
void set_visual_state (Gtkmm2ext::VisualState, bool);
bool drag_data_get (Glib::RefPtr<Gdk::DragContext> const, Gtk::SelectionData &);
std::shared_ptr<ARDOUR::RegionFxPlugin> region_fx_plugin () const { return _rfx; }
private:
std::string name () const;
Gtk::VBox _box;
ArdourWidgets::ArdourButton _fx_btn;
std::shared_ptr<ARDOUR::RegionFxPlugin> _rfx;
ARDOUR::PluginPresetPtr _plugin_preset_pointer;
};
class RegionFxBox : public Gtk::VBox, public PluginInterestedObject //, public ARDOUR::SessionHandlePtr
{
public:
RegionFxBox (std::shared_ptr<ARDOUR::Region>);
void redisplay_plugins ();
private:
void add_fx_to_display (std::weak_ptr<ARDOUR::RegionFxPlugin>);
void show_plugin_gui (std::weak_ptr<ARDOUR::RegionFxPlugin>, bool custom_ui = true);
void queue_delete_region_fx (std::weak_ptr<ARDOUR::RegionFxPlugin>);
bool idle_delete_region_fx (std::weak_ptr<ARDOUR::RegionFxPlugin>);
void notify_plugin_load_fail (uint32_t cnt = 1);
bool on_key_press (GdkEventKey*);
/* PluginInterestedObject */
bool use_plugins (SelectedPlugins const&);
/* DNDVbox signal handlers */
bool fxe_button_press_event (GdkEventButton*, RegionFxEntry*);
bool fxe_button_release_event (GdkEventButton*, RegionFxEntry*);
void reordered ();
void plugin_drop (Gtk::SelectionData const&, RegionFxEntry*, Glib::RefPtr<Gdk::DragContext> const&);
void object_drop (Gtkmm2ext::DnDVBox<RegionFxEntry>*, RegionFxEntry*, Glib::RefPtr<Gdk::DragContext> const&);
void delete_dragged_plugins (std::list<std::shared_ptr<ARDOUR::RegionFxPlugin>> const&);
std::shared_ptr<ARDOUR::RegionFxPlugin> find_drop_position (RegionFxEntry*);
std::shared_ptr<ARDOUR::Region> _region;
Gtkmm2ext::DnDVBox<RegionFxEntry> _display;
Gtk::ScrolledWindow _scroller;
Gtk::EventBox _base;
bool _no_redisplay;
int _placement;
};
std::shared_ptr<ARDOUR::Region> _region;
void connect_editor_events ();
@ -78,6 +145,7 @@ private:
Gtk::Label sync_relative_label;
Gtk::Label sync_absolute_label;
Gtk::Label start_label;
Gtk::Label region_fx_label;
ClockGroup* _clock_group;
@ -88,8 +156,11 @@ private:
AudioClock sync_offset_absolute_clock; ///< sync offset relative to the start of the timeline
AudioClock start_clock;
RegionFxBox _region_fx_box;
PBD::ScopedConnection state_connection;
PBD::ScopedConnection audition_connection;
PBD::ScopedConnection region_connection;
void bounds_changed (const PBD::PropertyChange&);
void name_changed ();

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
*
* 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 "ardour/automation_control.h"
#include "audio_region_view.h"
#include "gui_thread.h"
#include "region_fx_line.h"
#include "pbd/i18n.h"
using namespace ARDOUR;
RegionFxLine::RegionFxLine (std::string const& name, RegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<AutomationList> l, ParameterDescriptor const& d)
: AutomationLine (name, r.get_time_axis_view(), parent, l, d)
, _rv (r)
{
init ();
}
RegionFxLine::RegionFxLine (std::string const& name, RegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<ARDOUR::AutomationControl> ac)
: AutomationLine (name, r.get_time_axis_view(), parent, ac->alist (), ac->desc ())
, _rv (r)
, _ac (ac)
{
init ();
}
void
RegionFxLine::init ()
{
_rv.region()->PropertyChanged.connect (_region_changed_connection, invalidator (*this), boost::bind (&RegionFxLine::region_changed, this, _1), gui_context());
group->raise_to_top ();
group->set_y_position (2);
}
Temporal::timepos_t
RegionFxLine::get_origin() const
{
return _rv.region()->position();
}
void
RegionFxLine::enable_autoation ()
{
std::shared_ptr<AutomationControl> ac = _ac.lock ();
if (ac) {
ac->set_automation_state (Play);
}
}
void
RegionFxLine::end_drag (bool with_push, uint32_t final_index)
{
enable_autoation ();
AutomationLine::end_drag (with_push, final_index);
}
void
RegionFxLine::end_draw_merge ()
{
enable_autoation ();
AutomationLine::end_draw_merge ();
}
void
RegionFxLine::region_changed (PBD::PropertyChange const& what_changed)
{
PBD::PropertyChange interesting_stuff;
interesting_stuff.add (ARDOUR::Properties::start);
interesting_stuff.add (ARDOUR::Properties::length);
if (what_changed.contains (interesting_stuff)) {
reset ();
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
*
* 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.
*/
#ifndef __ardour_gtk_region_fx_line_h__
#define __ardour_gtk_region_fx_line_h__
#include "automation_line.h"
class RegionView;
class RegionFxLine : public AutomationLine
{
public:
RegionFxLine (std::string const&, RegionView&, ArdourCanvas::Container&, std::shared_ptr<ARDOUR::AutomationList>, ARDOUR::ParameterDescriptor const&);
RegionFxLine (std::string const&, RegionView&, ArdourCanvas::Container&, std::shared_ptr<ARDOUR::AutomationControl>);
Temporal::timepos_t get_origin() const;
RegionView& region_view () { return _rv; }
void end_drag (bool with_push, uint32_t final_index);
void end_draw_merge ();
virtual void enable_autoation ();
private:
void init ();
void region_changed (PBD::PropertyChange const&);
RegionView& _rv;
std::weak_ptr<ARDOUR::AutomationControl> _ac;
PBD::ScopedConnection _region_changed_connection;
};
#endif

View File

@ -35,45 +35,52 @@
#include "time_axis_view.h"
#include "editor.h"
#include "gui_thread.h"
#include "pbd/i18n.h"
using namespace std;
using namespace ARDOUR;
using namespace PBD;
AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<AutomationList> l)
: AutomationLine (name, r.get_time_axis_view(), parent, l, l->parameter())
, rv (r)
: RegionFxLine (name, r, parent, l, l->parameter ())
, arv (r)
{
// If this isn't true something is horribly wrong, and we'll get catastrophic gain values
assert(l->parameter().type() == EnvelopeAutomation);
r.region()->PropertyChanged.connect (_region_changed_connection, invalidator (*this), boost::bind (&AudioRegionGainLine::region_changed, this, _1), gui_context());
group->raise_to_top ();
group->set_y_position (2);
terminal_points_can_slide = false;
}
timepos_t
AudioRegionGainLine::get_origin() const
{
return rv.region()->position();
}
void
AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fraction)
{
AutomationLine::start_drag_single (cp, x, fraction);
RegionFxLine::start_drag_single (cp, x, fraction);
// XXX Stateful need to capture automation curve data
if (!rv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), &rv.audio_region()->get_state(), 0));
rv.audio_region()->set_envelope_active(false);
if (!arv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &arv.audio_region()->get_state(), 0));
arv.audio_region()->set_envelope_active(false);
}
}
void
AudioRegionGainLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
{
RegionFxLine::start_drag_line (i1, i2, fraction);
if (!arv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &arv.audio_region()->get_state(), 0));
arv.audio_region()->set_envelope_active(false);
}
}
void
AudioRegionGainLine::start_drag_multiple (list<ControlPoint*> cp, float fraction, XMLNode* state)
{
RegionFxLine::start_drag_multiple (cp, fraction, state);
if (!arv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &arv.audio_region()->get_state(), 0));
arv.audio_region()->set_envelope_active(false);
}
}
@ -84,10 +91,10 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
trackview.editor().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
if (!rv.audio_region()->envelope_active()) {
rv.audio_region()->clear_changes ();
rv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new StatefulDiffCommand (rv.audio_region()));
if (!arv.audio_region()->envelope_active()) {
arv.audio_region()->clear_changes ();
arv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new PBD::StatefulDiffCommand (arv.audio_region()));
}
trackview.editor ().get_selection ().clear_points ();
@ -101,23 +108,27 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
void
AudioRegionGainLine::end_drag (bool with_push, uint32_t final_index)
{
if (!rv.audio_region()->envelope_active()) {
rv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), 0, &rv.audio_region()->get_state()));
if (!arv.audio_region()->envelope_active()) {
arv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), 0, &arv.audio_region()->get_state()));
}
AutomationLine::end_drag (with_push, final_index);
RegionFxLine::end_drag (with_push, final_index);
}
void
AudioRegionGainLine::region_changed (const PropertyChange& what_changed)
AudioRegionGainLine::end_draw_merge ()
{
PropertyChange interesting_stuff;
enable_autoation ();
RegionFxLine::end_draw_merge ();
}
interesting_stuff.add (ARDOUR::Properties::start);
interesting_stuff.add (ARDOUR::Properties::length);
if (what_changed.contains (interesting_stuff)) {
reset ();
void
AudioRegionGainLine::enable_autoation ()
{
if (!arv.audio_region()->envelope_active()) {
XMLNode& before = arv.audio_region()->get_state();
arv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &before, &arv.audio_region()->get_state()));
}
}

View File

@ -27,8 +27,7 @@
#include "ardour/ardour.h"
#include "automation_line.h"
#include "region_fx_line.h"
namespace ARDOUR {
class Session;
@ -37,23 +36,21 @@ namespace ARDOUR {
class TimeAxisView;
class AudioRegionView;
class AudioRegionGainLine : public AutomationLine
class AudioRegionGainLine : public RegionFxLine
{
public:
AudioRegionGainLine (const std::string & name, AudioRegionView&, ArdourCanvas::Container& parent, std::shared_ptr<ARDOUR::AutomationList>);
Temporal::timepos_t get_origin() const;
void start_drag_single (ControlPoint*, double, float);
void start_drag_line (uint32_t, uint32_t, float);
void start_drag_multiple (std::list<ControlPoint*>, float, XMLNode*);
void end_drag (bool with_push, uint32_t final_index);
void end_draw_merge ();
void enable_autoation ();
void remove_point (ControlPoint&);
AudioRegionView& region_view () { return rv; }
private:
PBD::ScopedConnection _region_changed_connection;
void region_changed (const PBD::PropertyChange& what_changed);
AudioRegionView& rv;
AudioRegionView& arv;
};
#endif /* __ardour_gtk_region_gain_line_h__ */

View File

@ -237,6 +237,7 @@ RegionView::init (bool wfd)
//set_height (trackview.current_height());
_region->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RegionView::region_changed, this, _1), gui_context());
_region->RegionFxChanged.connect (*this, invalidator (*this), boost::bind (&RegionView::region_renamed, this), gui_context());
/* derived class calls set_colors () including RegionView::set_colors() in ::init() */
//set_colors ();
@ -749,7 +750,7 @@ void
RegionView::show_region_editor ()
{
if (!editor) {
editor = new RegionEditor (trackview.session(), region());
editor = new RegionEditor (trackview.session(), this);
}
editor->present ();
@ -791,6 +792,9 @@ RegionView::make_name () const
if (_region->muted()) {
str = std::string(u8"\U0001F507") + str; // SPEAKER WITH CANCELLATION STROKE
}
if (_region->has_region_fx()) {
str = str + " (Fx)";
}
return str;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -182,85 +182,121 @@ RouteTimeAxisView::set_route (std::shared_ptr<Route> rt)
playlist_button.signal_button_press_event().connect (sigc::mem_fun(*this, &RouteTimeAxisView::playlist_click), false);
automation_button.signal_button_press_event().connect (sigc::mem_fun(*this, &RouteTimeAxisView::automation_click), false);
if (is_track()) {
if (Profile->get_livetrax()) {
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*rec_enable_button, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*rec_enable_button, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
monitor_input_button->show ();
if (is_midi_track()) {
set_tooltip(*rec_enable_button, _("Record (Right-click for Step Edit)"));
gm.set_fader_name ("MidiTrackFader");
} else {
set_tooltip(*rec_enable_button, _("Record"));
gm.set_fader_name ("AudioTrackFader");
}
controls_table.attach (number_label, 0, 1, 0, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (*rec_enable_button, 3, 4, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (*monitor_input_button, 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (*mute_button, 3, 4, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (*solo_button, 4, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
/* set playlist button tip to the current playlist, and make it update when it changes */
update_playlist_tip ();
track()->PlaylistChanged.connect (*this, invalidator (*this), ui_bind(&RouteTimeAxisView::update_playlist_tip, this), gui_context());
controls_button_size_group->add_widget(*mute_button);
controls_button_size_group->add_widget(*solo_button);
controls_button_size_group->add_widget(*monitor_input_button);
controls_button_size_group->add_widget(*rec_enable_button);
} else {
gm.set_fader_name ("AudioBusFader");
Gtk::Fixed *blank = manage(new Gtk::Fixed());
controls_button_size_group->add_widget(*blank);
if (ARDOUR::Profile->get_mixbus() ) {
controls_table.attach (*blank, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*blank, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
blank->show();
}
top_hbox.pack_end(gm.get_level_meter(), false, false, 2);
if (!ARDOUR::Profile->get_mixbus()) {
controls_meters_size_group->add_widget (gm.get_level_meter());
}
if (_route->is_master()) {
route_group_button.set_sensitive(false);
}
top_hbox.pack_end(gm.get_level_meter(), false, false, 2);
_route->meter_change.connect (*this, invalidator (*this), bind (&RouteTimeAxisView::meter_changed, this), gui_context());
_route->input()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->track_number_changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::label_view, this), gui_context());
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*mute_button, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*mute_button, 3, 4, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
// mute button is always present, it is used to
// force the 'blank' placeholders to the proper size
controls_button_size_group->add_widget(*mute_button);
if (!_route->is_master()) {
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*solo_button, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
if (is_track()) {
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*rec_enable_button, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*rec_enable_button, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
if (is_midi_track()) {
set_tooltip(*rec_enable_button, _("Record (Right-click for Step Edit)"));
gm.set_fader_name ("MidiTrackFader");
} else {
set_tooltip(*rec_enable_button, _("Record"));
gm.set_fader_name ("AudioTrackFader");
}
/* set playlist button tip to the current playlist, and make it update when it changes */
update_playlist_tip ();
track()->PlaylistChanged.connect (*this, invalidator (*this), ui_bind(&RouteTimeAxisView::update_playlist_tip, this), gui_context());
} else {
controls_table.attach (*solo_button, 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
gm.set_fader_name ("AudioBusFader");
Gtk::Fixed *blank = manage(new Gtk::Fixed());
controls_button_size_group->add_widget(*blank);
if (ARDOUR::Profile->get_mixbus() ) {
controls_table.attach (*blank, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*blank, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
blank->show();
}
} else {
Gtk::Fixed *blank = manage(new Gtk::Fixed());
controls_button_size_group->add_widget(*blank);
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*blank, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*blank, 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
blank->show();
}
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (route_group_button, 2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (gm.get_gain_slider(), 3, 5, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 1, 0);
} else {
controls_table.attach (route_group_button, 4, 5, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (gm.get_gain_slider(), 0, 2, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 1, 0);
top_hbox.pack_end(gm.get_level_meter(), false, false, 2);
if (!ARDOUR::Profile->get_mixbus()) {
controls_meters_size_group->add_widget (gm.get_level_meter());
}
if (_route->is_master()) {
route_group_button.set_sensitive(false);
}
_route->meter_change.connect (*this, invalidator (*this), bind (&RouteTimeAxisView::meter_changed, this), gui_context());
_route->input()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->track_number_changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::label_view, this), gui_context());
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*mute_button, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*mute_button, 3, 4, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
// mute button is always present, it is used to
// force the 'blank' placeholders to the proper size
controls_button_size_group->add_widget(*mute_button);
if (!_route->is_master()) {
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*solo_button, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*solo_button, 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
} else {
Gtk::Fixed *blank = manage(new Gtk::Fixed());
controls_button_size_group->add_widget(*blank);
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (*blank, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
} else {
controls_table.attach (*blank, 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
}
blank->show();
}
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (route_group_button, 2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (gm.get_gain_slider(), 3, 5, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 1, 0);
} else {
controls_table.attach (route_group_button, 4, 5, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
controls_table.attach (gm.get_gain_slider(), 0, 2, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 1, 0);
}
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (automation_button, 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
} else {
controls_table.attach (automation_button, 3, 4, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
}
if (is_track() && track()->mode() == ARDOUR::Normal) {
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (playlist_button, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
} else {
controls_table.attach (playlist_button, 2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
}
}
}
set_tooltip(*solo_button,_("Solo"));
@ -284,20 +320,6 @@ RouteTimeAxisView::set_route (std::shared_ptr<Route> rt)
route_active_changed();
label_view ();
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (automation_button, 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
} else {
controls_table.attach (automation_button, 3, 4, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
}
if (is_track() && track()->mode() == ARDOUR::Normal) {
if (ARDOUR::Profile->get_mixbus()) {
controls_table.attach (playlist_button, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
} else {
controls_table.attach (playlist_button, 2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
}
}
_y_position = -1;
_route->processors_changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::processors_changed, this, _1), gui_context());
@ -447,7 +469,7 @@ void
RouteTimeAxisView::update_track_number_visibility ()
{
DisplaySuspender ds;
bool show_label = _session->config.get_track_name_number();
bool show_label = (Profile->get_livetrax() || _session->config.get_track_name_number());
if (_route && _route->is_master()) {
show_label = false;

View File

@ -484,11 +484,13 @@ RouteUI::mute_press (GdkEventButton* ev)
if (Keyboard::is_context_menu_event (ev)) {
if (mute_menu == 0){
build_mute_menu();
}
if (!Profile->get_livetrax()) {
if (mute_menu == 0){
build_mute_menu();
}
mute_menu->popup (ev->button, ev->time);
mute_menu->popup (ev->button, ev->time);
}
return true;
@ -650,11 +652,13 @@ RouteUI::solo_press(GdkEventButton* ev)
if (Keyboard::is_context_menu_event (ev)) {
if (solo_menu == 0) {
build_solo_menu ();
}
if (!Profile->get_livetrax()) {
if (solo_menu == 0) {
build_solo_menu ();
}
solo_menu->popup (ev->button, ev->time);
solo_menu->popup (ev->button, ev->time);
}
} else {
@ -1025,7 +1029,7 @@ RouteUI::step_edit_changed (bool yn)
bool
RouteUI::rec_enable_release (GdkEventButton* ev)
{
if (Keyboard::is_context_menu_event (ev)) {
if (!Profile->get_livetrax() && Keyboard::is_context_menu_event (ev)) {
build_record_menu ();
if (_record_menu) {
_record_menu->popup (ev->button, ev->time);
@ -2880,4 +2884,3 @@ RouteUI::clear_time_domain (bool apply_to_selection)
}
}

View File

@ -1176,11 +1176,11 @@ Selection::get_state () const
continue;
}
AudioRegionGainLine* argl = dynamic_cast<AudioRegionGainLine*> (&(*i)->line());
if (argl) {
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> (&(*i)->line());
if (fxl) {
XMLNode* r = node->add_child (X_("ControlPoint"));
r->set_property (X_("type"), "region");
r->set_property (X_("region-id"), argl->region_view ().region ()->id ());
r->set_property (X_("region-id"), fxl->region_view ().region ()->id ());
r->set_property (X_("view-index"), (*i)->view_index());
}
@ -1324,35 +1324,6 @@ Selection::set_state (XMLNode const & node, int)
if (!cps.empty()) {
add (cps);
}
} else if (prop_type->value () == "region") {
PBD::ID region_id;
uint32_t view_index;
if (!(*i)->get_property (X_("region-id"), region_id) ||
!(*i)->get_property (X_("view-index"), view_index)) {
continue;
}
RegionSelection rs;
editor->get_regionviews_by_id (region_id, rs);
if (!rs.empty ()) {
vector <ControlPoint *> cps;
for (RegionSelection::iterator rsi = rs.begin(); rsi != rs.end(); ++rsi) {
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*rsi);
if (arv) {
std::shared_ptr<AudioRegionGainLine> gl = arv->get_gain_line ();
ControlPoint* cp = gl->nth(view_index);
if (cp) {
cps.push_back (cp);
cp->show();
}
}
}
if (!cps.empty()) {
add (cps);
}
}
}
} else if ((*i)->name() == X_("TimelineRange")) {

View File

@ -175,7 +175,7 @@ SelectionPropertiesBox::selection_changed ()
_header_label.hide();
if (!selection.time.empty()) {
if (Profile->get_livetrax() || !selection.time.empty()) {
_time_info_box->show();
_header_label.set_text(_("Range Properties (Press ESC to Deselect All)"));
_header_label.show();

View File

@ -47,7 +47,7 @@
#include "ardour_dialog.h"
class EngineControl;
class EngineControlDialog;
class SessionDialog : public ArdourDialog
{

View File

@ -497,6 +497,7 @@ SessionOptionEditor::parameter_changed (std::string const & p)
_sf->add (FormatInt24, _("24-bit integer"));
_sf->add (FormatInt16, _("16-bit integer"));
}
if (need_refill) {
parameter_changed ("native-file-data-format");
}

View File

@ -286,8 +286,10 @@ SoundFileBox::set_session(Session* s)
auditioner_connections.drop_connections();
} else {
auditioner_connections.drop_connections();
_session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
_session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
if (_session->the_auditioner()) {
_session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
_session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
}
}
}
@ -310,15 +312,19 @@ SoundFileBox::audition_progress(ARDOUR::samplecnt_t pos, ARDOUR::samplecnt_t len
}
bool
SoundFileBox::seek_button_press(GdkEventButton*) {
SoundFileBox::seek_button_press (GdkEventButton*)
{
_seeking = true;
return false; // pass on to slider
}
bool
SoundFileBox::seek_button_release(GdkEventButton*) {
SoundFileBox::seek_button_release (GdkEventButton*)
{
_seeking = false;
_session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
if (_session->the_auditioner()) {
_session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
}
seek_slider.set_sensitive (false);
return false; // pass on to slider
}
@ -991,18 +997,20 @@ SoundFileBrowser::add_gain_meter ()
{
delete gm;
gm = new GainMeter (_session, 250);
std::shared_ptr<Route> r = _session->the_auditioner ();
gm->set_controls (r, r->shared_peak_meter(), r->amp(), r->gain_control());
gm->set_fader_name (X_("GainFader"));
if (r) {
gm = new GainMeter (_session, 250);
meter_packer.set_border_width (12);
meter_packer.pack_start (*gm, false, true);
hpacker.pack_end (meter_packer, false, false);
meter_packer.show_all ();
start_metering ();
gm->set_controls (r, r->shared_peak_meter(), r->amp(), r->gain_control());
gm->set_fader_name (X_("GainFader"));
meter_packer.set_border_width (12);
meter_packer.pack_start (*gm, false, true);
hpacker.pack_end (meter_packer, false, false);
meter_packer.show_all ();
start_metering ();
}
}
void
@ -2126,7 +2134,9 @@ SoundFileOmega::where_combo_changed()
void
SoundFileOmega::instrument_combo_changed()
{
_session->the_auditioner()->set_audition_synth_info( instrument_combo.selected_instrument() );
if (_session->the_auditioner()) {
_session->the_auditioner()->set_audition_synth_info( instrument_combo.selected_instrument() );
}
}
MidiTrackNameSource

View File

@ -68,7 +68,7 @@ using namespace PBD;
using std::string;
using std::vector;
StartupFSM::StartupFSM (EngineControl& amd)
StartupFSM::StartupFSM (EngineControlDialog& amd)
: session_domain (Config->get_preferred_time_domain())
, session_existing_sample_rate (0)
, session_engine_hints ("EngineHints")

View File

@ -27,7 +27,7 @@
class ArdourDialog;
class NewUserWizard;
class EngineControl;
class EngineControlDialog;
class SessionDialog;
class PluginScanDialog;
@ -59,7 +59,7 @@ class StartupFSM : public sigc::trackable
WaitingForPlugins
};
StartupFSM (EngineControl&);
StartupFSM (EngineControlDialog&);
~StartupFSM ();
void start ();
@ -121,7 +121,7 @@ class StartupFSM : public sigc::trackable
* created and destroyed within the scope of startup.
*/
EngineControl& audiomidi_dialog;
EngineControlDialog& audiomidi_dialog;
NewUserWizard* new_user_dialog;
SessionDialog* session_dialog;
ArdourDialog* pre_release_dialog;

View File

@ -622,7 +622,7 @@ StreamView::get_selectables (timepos_t const & start, timepos_t const & end, dou
|| (!within && (*i)->region()->coverage (start, end) != Temporal::OverlapNone)) {
if (_trackview.editor().internal_editing()) {
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*i);
if (arv && arv->get_gain_line ()) {
if (arv && arv->fx_line ()) {
/* Note: AutomationLine::get_selectables() uses trackview.current_height (),
* disregarding Stacked layer display height
*/
@ -630,7 +630,7 @@ StreamView::get_selectables (timepos_t const & start, timepos_t const & end, dou
double const y = (*i)->get_canvas_group ()->position().y;
double t = 1.0 - std::min (1.0, std::max (0., (top - _trackview.y_position () - y) / c));
double b = 1.0 - std::min (1.0, std::max (0., (bottom - _trackview.y_position () - y) / c));
arv->get_gain_line()->get_selectables (start, end, b, t, results);
arv->fx_line()->get_selectables (start, end, b, t, results);
}
} else {
results.push_back (*i);

View File

@ -365,6 +365,7 @@
<ColorAlias name="recording rect" alias="alert:ruddy"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:foregroundest"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -356,6 +356,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -357,6 +357,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -357,6 +357,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -357,6 +357,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

Some files were not shown because too many files have changed in this diff Show More