Compare commits

...

22 Commits

Author SHA1 Message Date
Paul Davis 9f90870306 reduce (but not eliminate) AutomationLine (+ derivatives) dependence on TimeAxisView
AutomationLines now use a TimeThing for time conversions, and has their own Session ref handle
2021-12-09 10:19:23 -07:00
Paul Davis 0dda441598 automation region view: eliminate use of trackview member to access PublicEditor 2021-12-08 16:31:28 -07:00
Paul Davis 3798a2a045 change where a ghost region gets its height set 2021-12-08 16:14:10 -07:00
Paul Davis ecaa0ec422 time axis view item: more complete/correct (?) fix for selection frame size 2021-12-08 14:58:59 -07:00
Paul Davis 87e89750f8 automation region view: do not set height of the line outside of ::set_height() 2021-12-08 14:49:54 -07:00
Paul Davis 44699e605c time_axis_view_item: do not set frame handle heights outside of ::set_height() 2021-12-08 14:49:09 -07:00
Paul Davis 9e89294e11 time axis view item: fix selection frame size 2021-12-08 14:29:26 -07:00
Paul Davis 5bd3d25f8e time axis view item: don't set name text size/position outside of ::set_height() 2021-12-08 14:29:11 -07:00
Paul Davis 8c75ea936a no need to set initial height in a TimeAxisViewItem, since ::set_height() will take care of it 2021-12-08 13:46:57 -07:00
Paul Davis 36f3d5aad4 remove another long-commented line 2021-12-08 13:46:33 -07:00
Paul Davis 816b6a00bc fix ghost region height for MIDI regions 2021-12-08 13:46:21 -07:00
Paul Davis be111abb34 minor fixups for ghost region height management 2021-12-08 13:19:20 -07:00
Paul Davis ee22381f32 remove long-commented line 2021-12-08 13:13:08 -07:00
Paul Davis de65798619 ghostregions: use their own height, not trackview.current_height() 2021-12-08 09:28:26 -07:00
Paul Davis 71181bbb02 use TimeThing within MidiRegionView for time conversion 2021-12-07 22:08:35 -07:00
Paul Davis 0b2ab07c61 use TimeThing when constructing RegionViews/TimeAxisViewItem 2021-12-07 21:51:29 -07:00
Paul Davis 0537243540 PublicEditor inherits from TimeThing 2021-12-07 21:27:35 -07:00
Paul Davis 40c60ecb42 remove unused file 2021-12-07 21:23:29 -07:00
Paul Davis 992b517933 clip editor: add bg color 2021-12-06 17:03:32 -07:00
Paul Davis 00f1dc8725 audio clip editor: trivial packing onto trigger page 2021-12-06 15:33:32 -07:00
Paul Davis e1a5c5ccca audio clip editor: some color 2021-12-06 15:29:15 -07:00
Paul Davis 94517a9de5 audio clip editor: starting to add display material 2021-12-06 15:13:16 -07:00
33 changed files with 372 additions and 299 deletions

View File

@ -16,15 +16,95 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "ardour/audioregion.h"
#include "waveview/wave_view.h"
#include "audio_clip_editor.h"
#include "ui_config.h"
#include "pbd/i18n.h"
using namespace ARDOUR;
using namespace ArdourWaveView;
using namespace ArdourCanvas;
AudioClipEditor::AudioClipEditor ()
{
set_background_color (UIConfiguration::instance().color (X_("theme:bg")));
}
AudioClipEditor::~AudioClipEditor ()
{
drop_waves ();
}
void
AudioClipEditor::drop_waves ()
{
for (auto & wave : waves) {
delete wave;
}
waves.clear ();
}
void
AudioClipEditor::set_region (boost::shared_ptr<AudioRegion> r)
{
drop_waves ();
uint32_t n_chans = r->n_channels ();
for (uint32_t n = 0; n < n_chans; ++n) {
WaveView* wv = new WaveView (this, r);
wv->set_channel (n);
waves.push_back (wv);
}
int h = get_allocation().get_height ();
if (h) {
set_wave_heights (h);
}
}
void
AudioClipEditor::size_allocate (Gtk::Allocation const & alloc)
{
GtkCanvas::size_allocate (alloc);
set_wave_heights (alloc.get_height());
}
void
AudioClipEditor::set_wave_heights (int h)
{
uint32_t n = 0;
Distance ht = h / waves.size();
for (auto & wave : waves) {
wave->set_height (ht);
wave->set_y_position (n * ht);
wave->set_samples_per_pixel (8192);
wave->set_show_zero_line (false);
wave->set_clip_level (1.0);
}
}
void
AudioClipEditor::set_waveform_colors ()
{
Gtkmm2ext::Color clip = UIConfiguration::instance().color ("clipped waveform");
Gtkmm2ext::Color zero = UIConfiguration::instance().color ("zero line");
Gtkmm2ext::Color fill = UIConfiguration::instance().color ("waveform fill");
Gtkmm2ext::Color outline = UIConfiguration::instance().color ("waveform outline");
for (auto & wave : waves) {
wave->set_fill_color (fill);
wave->set_outline_color (outline);
wave->set_clip_color (clip);
wave->set_zero_color (zero);
}
}

View File

@ -19,13 +19,33 @@
#ifndef __gtk2_ardour_audio_clip_editor_h__
#define __gtk2_ardour_audio_clip_editor_h__
#include <vector>
#include "canvas/canvas.h"
namespace ARDOUR {
class AudioRegion;
}
namespace ArdourWaveView {
class WaveView;
}
class AudioClipEditor : public ArdourCanvas::GtkCanvas
{
public:
AudioClipEditor ();
~AudioClipEditor ();
void set_region (boost::shared_ptr<ARDOUR::AudioRegion>);
private:
std::vector<ArdourWaveView::WaveView *> waves;
void drop_waves ();
void size_allocate (Gtk::Allocation const &);
void set_wave_heights (int);
void set_waveform_colors ();
};

View File

@ -69,6 +69,7 @@
#include "audio_time_axis.h"
#include "rgb_macros.h"
#include "gui_thread.h"
#include "time_thing.h"
#include "ui_config.h"
#include "pbd/i18n.h"
@ -111,9 +112,9 @@ static Cairo::RefPtr<Cairo::Pattern> create_pending_peak_pattern() {
return p;
}
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, TimeThing const & tt, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
uint32_t basic_color)
: RegionView (parent, tv, r, spu, basic_color)
: RegionView (parent, tt, tv, r, spu, basic_color)
, sync_mark(0)
, fade_in_handle(0)
, fade_out_handle(0)
@ -132,9 +133,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
{
}
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, TimeThing const & tt, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
uint32_t basic_color, bool recording, TimeAxisViewItem::Visibility visibility)
: RegionView (parent, tv, r, spu, basic_color, recording, visibility)
: RegionView (parent, tt, tv, r, spu, basic_color, recording, visibility)
, sync_mark(0)
, fade_in_handle(0)
, fade_out_handle(0)
@ -235,13 +236,12 @@ AudioRegionView::init (bool wfd)
const string line_name = _region->name() + ":gain";
gain_line.reset (new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope()));
gain_line.reset (new AudioRegionGainLine (line_name, *this, PublicEditor::instance(), get_time_axis_view(), *group, audio_region()->envelope()));
update_envelope_visibility ();
gain_line->reset ();
/* streamview will call set_height() */
//set_height (trackview.current_height()); // XXX not correct for Layered mode, but set_height() will fix later.
region_muted ();
region_sync_changed ();
@ -1470,7 +1470,6 @@ AudioRegionView::add_ghost (TimeAxisView& tv)
ghost->waves.push_back(wave);
}
ghost->set_height ();
ghost->set_duration (_region->length_samples() / samples_per_pixel);
ghost->set_colors();
ghosts.push_back (ghost);

View File

@ -58,12 +58,14 @@ class AudioRegionView : public RegionView
{
public:
AudioRegionView (ArdourCanvas::Container *,
TimeThing const &,
RouteTimeAxisView&,
boost::shared_ptr<ARDOUR::AudioRegion>,
double initial_samples_per_pixel,
uint32_t base_color);
AudioRegionView (ArdourCanvas::Container *,
TimeThing const &,
RouteTimeAxisView&,
boost::shared_ptr<ARDOUR::AudioRegion>,
double samples_per_pixel,

View File

@ -100,14 +100,14 @@ AudioStreamView::create_region_view (boost::shared_ptr<Region> r, bool wait_for_
case NonLayered:
case Normal:
if (recording) {
region_view = new AudioRegionView (_canvas_group, _trackview, region,
region_view = new AudioRegionView (_canvas_group, PublicEditor::instance(), _trackview, region,
_samples_per_pixel, region_color, recording, TimeAxisViewItem::Visibility(
TimeAxisViewItem::ShowFrame |
TimeAxisViewItem::HideFrameRight |
TimeAxisViewItem::HideFrameLeft |
TimeAxisViewItem::HideFrameTB));
} else {
region_view = new AudioRegionView (_canvas_group, _trackview, region,
region_view = new AudioRegionView (_canvas_group, PublicEditor::instance(), _trackview, region,
_samples_per_pixel, region_color);
}
break;

View File

@ -81,15 +81,16 @@ using namespace Temporal;
#define SAMPLES_TO_TIME(x) (get_origin().distance (x))
/** @param converter A TimeConverter whose origin_b is the start time of the AutomationList in session samples.
* This will not be deleted by AutomationLine.
*/
AutomationLine::AutomationLine (const string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
boost::shared_ptr<AutomationList> al,
const ParameterDescriptor& desc)
: trackview (tv)
AutomationLine::AutomationLine (const string& name,
TimeThing const & tt,
Session& s,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
boost::shared_ptr<AutomationList> al,
const ParameterDescriptor& desc)
: SessionHandleRef (s)
, _trackview (tv)
, time_thing (tt)
, _name (name)
, alist (al)
, _parent_group (parent)
@ -118,7 +119,7 @@ AutomationLine::AutomationLine (const string& name,
line->Event.connect (sigc::mem_fun (*this, &AutomationLine::event_handler));
trackview.session()->register_with_memento_command_factory(alist->id(), this);
_session.register_with_memento_command_factory(alist->id(), this);
interpolation_changed (alist->interpolation ());
@ -300,8 +301,8 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
y = min (1.0, y);
y = _height - (y * _height);
trackview.editor().begin_reversible_command (_("automation event move"));
trackview.editor().session()->add_command (
PublicEditor::instance().begin_reversible_command (_("automation event move"));
_session.add_command (
new MementoCommand<AutomationList> (memento_command_binder(), &get_state(), 0));
cp.move_to (cp.get_x(), y, ControlPoint::Full);
@ -318,11 +319,11 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
update_pending = false;
trackview.editor().session()->add_command (
_session.add_command (
new MementoCommand<AutomationList> (memento_command_binder(), 0, &alist->get_state()));
trackview.editor().commit_reversible_command ();
trackview.editor().session()->set_dirty ();
PublicEditor::instance().commit_reversible_command ();
_session.set_dirty ();
}
void
@ -420,7 +421,7 @@ AutomationLine::string_to_fraction (string const & s) const
void
AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction)
{
trackview.editor().session()->add_command (
_session.add_command (
new MementoCommand<AutomationList> (memento_command_binder(), &get_state(), 0));
_drag_points.clear ();
@ -445,7 +446,7 @@ AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction)
void
AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
{
trackview.editor().session()->add_command (
_session.add_command (
new MementoCommand<AutomationList> (memento_command_binder (), &get_state(), 0));
_drag_points.clear ();
@ -464,7 +465,7 @@ AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
void
AutomationLine::start_drag_multiple (list<ControlPoint*> cp, float fraction, XMLNode* state)
{
trackview.editor().session()->add_command (
_session.add_command (
new MementoCommand<AutomationList> (memento_command_binder(), state, 0));
_drag_points = cp;
@ -487,7 +488,7 @@ AutomationLine::ContiguousControlPoints::ContiguousControlPoints (AutomationLine
}
void
AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e)
AutomationLine::ContiguousControlPoints::compute_x_bounds (TimeThing const & tt)
{
uint32_t sz = size();
@ -501,10 +502,10 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e)
if (front()->view_index() > 0) {
before_x = line.nth (front()->view_index() - 1)->get_x();
const samplepos_t pos = e.pixel_to_sample(before_x);
const samplepos_t pos = tt.pixel_to_sample(before_x);
const TempoMetric& metric = map->metric_at (pos);
const samplecnt_t len = ceil (metric.samples_per_bar (pos) / (Temporal::ticks_per_beat * metric.meter().divisions_per_bar()));
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
const double one_tick_in_pixels = tt.sample_to_pixel_unrounded (len);
before_x += one_tick_in_pixels;
}
@ -516,10 +517,10 @@ AutomationLine::ContiguousControlPoints::compute_x_bounds (PublicEditor& e)
if (back()->view_index() < (line.npoints() - 1)) {
after_x = line.nth (back()->view_index() + 1)->get_x();
const samplepos_t pos = e.pixel_to_sample(after_x);
const samplepos_t pos = tt.pixel_to_sample(after_x);
const TempoMetric& metric = map->metric_at (pos);
const samplecnt_t len = ceil (metric.samples_per_bar (pos) / (Temporal::ticks_per_beat * metric.meter().divisions_per_bar()));
const double one_tick_in_pixels = e.sample_to_pixel_unrounded (len);
const double one_tick_in_pixels = tt.sample_to_pixel_unrounded (len);
after_x -= one_tick_in_pixels;
}
@ -632,7 +633,7 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool
}
for (vector<CCP>::iterator ccp = contiguous_points.begin(); ccp != contiguous_points.end(); ++ccp) {
(*ccp)->compute_x_bounds (trackview.editor());
(*ccp)->compute_x_bounds (PublicEditor::instance());
}
_drag_had_movement = true;
}
@ -759,10 +760,10 @@ AutomationLine::end_drag (bool with_push, uint32_t final_index)
line->set_steps (line_points, is_stepped());
}
trackview.editor().session()->add_command (
_session.add_command (
new MementoCommand<AutomationList>(memento_command_binder (), 0, &alist->get_state()));
trackview.editor().session()->set_dirty ();
_session.set_dirty ();
did_push = false;
contiguous_points.clear ();
@ -799,7 +800,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp)
* taking _offset into account.
*/
const double model_x = trackview.editor().time_to_pixel_unrounded (absolute_time.earlier (_offset));
const double model_x = PublicEditor::instance().time_to_pixel_unrounded (absolute_time.earlier (_offset));
if (view_x != model_x) {
@ -808,7 +809,7 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp)
* measures the distance from the origin for this line.
*/
const timecnt_t view_samples (trackview.editor().pixel_to_sample (view_x)); /* implicit zero origin */
const timecnt_t view_samples (PublicEditor::instance().pixel_to_sample (view_x)); /* implicit zero origin */
/* adjust to measure distance from origin (this preserves time domain) */
const timecnt_t distance_from_origin = get_origin().distance (timepos_t (view_samples));
@ -850,7 +851,7 @@ AutomationLine::control_points_adjacent (double xval, uint32_t & before, uint32_
ControlPoint *acp = 0;
double unit_xval;
unit_xval = trackview.editor().sample_to_pixel_unrounded (xval);
unit_xval = PublicEditor::instance().sample_to_pixel_unrounded (xval);
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
@ -906,17 +907,16 @@ AutomationLine::is_first_point (ControlPoint& cp)
void
AutomationLine::remove_point (ControlPoint& cp)
{
trackview.editor().begin_reversible_command (_("remove control point"));
PublicEditor::instance().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
trackview.editor ().get_selection ().clear_points ();
PublicEditor::instance().get_selection ().clear_points ();
alist->erase (cp.model());
trackview.editor().session()->add_command(
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
_session.add_command (new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
trackview.editor().commit_reversible_command ();
trackview.editor().session()->set_dirty ();
PublicEditor::instance().commit_reversible_command ();
_session.set_dirty ();
}
/** Get selectable points within an area.
@ -930,8 +930,8 @@ void
AutomationLine::get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list<Selectable*>& results)
{
/* convert fractions to display coordinates with 0 at the top of the track */
double const bot_track = (1 - topfrac) * trackview.current_height ();
double const top_track = (1 - botfrac) * trackview.current_height ();
double const bot_track = (1 - topfrac) * _height;
double const top_track = (1 - botfrac) * _height;
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
@ -1038,7 +1038,7 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
* zoom and scroll into account).
*/
double px = trackview.editor().time_to_pixel_unrounded (tx);
double px = PublicEditor::instance().time_to_pixel_unrounded (tx);
/* convert from canonical view height (0..1.0) to actual
* height coordinates (using X11's top-left rooted system)
@ -1084,7 +1084,7 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
update_visibility ();
}
set_selected_points (trackview.editor().get_selection().points);
set_selected_points (PublicEditor::instance().get_selection().points);
}
void
@ -1114,7 +1114,7 @@ AutomationLine::queue_reset ()
{
/* this must be called from the GUI thread */
if (trackview.editor().session()->transport_rolling() && alist->automation_write()) {
if (_session.transport_rolling() && alist->automation_write()) {
/* automation write pass ... defer to a timeout */
/* redraw in 1/4 second */
if (!have_timeout) {
@ -1136,8 +1136,7 @@ AutomationLine::clear ()
XMLNode &before = alist->get_state();
alist->clear();
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
_session.add_command (new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
}
void

View File

@ -39,12 +39,15 @@
#include "ardour/automation_list.h"
#include "ardour/parameter_descriptor.h"
#include "ardour/session_handle.h"
#include "ardour/types.h"
#include "canvas/types.h"
#include "canvas/container.h"
#include "canvas/poly_line.h"
#include "time_thing.h"
class AutomationLine;
class ControlPoint;
class PointSelection;
@ -54,9 +57,8 @@ class Selectable;
class Selection;
class PublicEditor;
/** A GUI representation of an ARDOUR::AutomationList */
class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
class AutomationLine : public ARDOUR::SessionHandleRef, public sigc::trackable, public PBD::StatefulDestructible
{
public:
enum VisibleAspects {
@ -66,6 +68,8 @@ public:
};
AutomationLine (const std::string& name,
TimeThing const & tt,
ARDOUR::Session& s,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
boost::shared_ptr<ARDOUR::AutomationList> al,
@ -115,8 +119,6 @@ public:
bool get_uses_gain_mapping () const;
TimeAxisView& trackview;
ArdourCanvas::Container& canvas_group() const { return *group; }
ArdourCanvas::Item& parent_group() const { return _parent_group; }
ArdourCanvas::Item& grab_item() const { return *line; }
@ -164,11 +166,15 @@ public:
samplepos_t session_sample_position (ARDOUR::AutomationList::const_iterator) const;
Temporal::timepos_t session_position (ARDOUR::AutomationList::const_iterator) const;
protected:
std::string _name;
guint32 _height;
uint32_t _line_color;
TimeAxisView& trackview() { return _trackview; }
protected:
TimeAxisView& _trackview;
TimeThing const & time_thing;
std::string _name;
guint32 _height;
uint32_t _line_color;
boost::shared_ptr<ARDOUR::AutomationList> alist;
@ -193,7 +199,7 @@ public:
ContiguousControlPoints (AutomationLine& al);
double clamp_dx (double dx);
void move (double dx, double dvalue);
void compute_x_bounds (PublicEditor& e);
void compute_x_bounds (TimeThing const & e);
private:
AutomationLine& line;
double before_x;

View File

@ -47,13 +47,14 @@
using namespace Temporal;
AutomationRegionView::AutomationRegionView (ArdourCanvas::Container* parent,
TimeThing const & tt,
AutomationTimeAxisView& time_axis,
boost::shared_ptr<ARDOUR::Region> region,
const Evoral::Parameter& param,
boost::shared_ptr<ARDOUR::AutomationList> list,
double spu,
uint32_t basic_color)
: RegionView(parent, time_axis, region, spu, basic_color, true)
: RegionView(parent, tt, time_axis, region, spu, basic_color, true)
, _parameter(param)
{
TimeAxisViewItem::set_position (_region->position(), this);
@ -65,9 +66,9 @@ AutomationRegionView::AutomationRegionView (ArdourCanvas::Container*
group->raise_to_top();
trackview.editor().MouseModeChanged.connect(_mouse_mode_connection, invalidator (*this),
boost::bind (&AutomationRegionView::mouse_mode_changed, this),
gui_context ());
PublicEditor::instance().MouseModeChanged.connect(_mouse_mode_connection, invalidator (*this),
boost::bind (&AutomationRegionView::mouse_mode_changed, this),
gui_context ());
}
AutomationRegionView::~AutomationRegionView ()
@ -85,8 +86,6 @@ AutomationRegionView::init (bool /*wfd*/)
reset_width_dependent_items ((double) _region->length_samples() / samples_per_pixel);
set_height (trackview.current_height());
fill_color_name = "midi frame base";
set_colors ();
@ -98,11 +97,13 @@ AutomationRegionView::create_line (boost::shared_ptr<ARDOUR::AutomationList> lis
{
_line = boost::shared_ptr<AutomationLine> (new MidiAutomationLine(
ARDOUR::EventTypeMap::instance().to_symbol(list->parameter()),
trackview, *get_canvas_group(), list,
PublicEditor::instance(),
*trackview.session(),
trackview,
*get_canvas_group(), list,
boost::dynamic_pointer_cast<ARDOUR::MidiRegion> (_region),
_parameter));
_line->set_colors();
_line->set_height ((uint32_t)rint(trackview.current_height() - 2.5 - NAME_HIGHLIGHT_SIZE));
_line->set_visibility (AutomationLine::VisibleAspects (AutomationLine::Line|AutomationLine::ControlPoints));
_line->set_maximum_time (timepos_t (_region->length()));
_line->set_offset (_region->start ());
@ -112,7 +113,7 @@ uint32_t
AutomationRegionView::get_fill_color() const
{
const std::string mod_name = (_dragging ? "dragging region" :
trackview.editor().internal_editing() ? "editable region" :
PublicEditor::instance().internal_editing() ? "editable region" :
"midi frame base");
if (_selected) {
return UIConfiguration::instance().color_mod ("selected region base", mod_name);
@ -136,9 +137,9 @@ AutomationRegionView::canvas_group_event (GdkEvent* ev)
return false;
}
PublicEditor& e = trackview.editor ();
PublicEditor& e (PublicEditor::instance());
if (trackview.editor().internal_editing() &&
if (e.internal_editing() &&
ev->type == GDK_BUTTON_RELEASE &&
ev->button.button == 1 &&
e.current_mouse_mode() == Editing::MouseDraw &&

View File

@ -34,11 +34,13 @@ namespace ARDOUR {
};
class TimeAxisView;
class TimeThing;
class AutomationRegionView : public RegionView
{
public:
AutomationRegionView(ArdourCanvas::Container*,
TimeThing const &,
AutomationTimeAxisView&,
boost::shared_ptr<ARDOUR::Region>,
const Evoral::Parameter& parameter,

View File

@ -121,7 +121,7 @@ AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region
}
region_view = new AutomationRegionView (
_canvas_group, _automation_view, region,
_canvas_group, PublicEditor::instance(), _automation_view, region,
_automation_view.parameter (), list,
_samples_per_pixel, region_color
);

View File

@ -302,6 +302,8 @@ AutomationTimeAxisView::AutomationTimeAxisView (
boost::shared_ptr<AutomationLine> line (
new AutomationLine (
ARDOUR::EventTypeMap::instance().to_symbol(_parameter),
PublicEditor::instance(),
*session(),
*this,
*_canvas_display,
_control->alist(),

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) 2005-2014 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2005 Nick Mainsbridge <mainsbridge@gmail.com>
* Copyright (C) 2005 Taybin Rutkin <taybin@taybin.com>
* Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
* Copyright (C) 2007-2011 Carl Hetherington <carl@carlh.net>
*
* 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_crossfade_view_h__
#define __gtk_ardour_crossfade_view_h__
#include <vector>
#include "pbd/signals.h"
#include "ardour/crossfade.h"
#include "time_axis_view_item.h"
class RouteTimeAxisView;
class AudioRegionView;
namespace ArdourCanvas {
class PolyLine;
}
class CrossfadeView : public TimeAxisViewItem
{
public:
CrossfadeView (ArdourCanvas::Container*,
RouteTimeAxisView&,
boost::shared_ptr<ARDOUR::Crossfade>,
double initial_samples_per_pixel,
Gdk::Color& basic_color,
AudioRegionView& leftview,
AudioRegionView& rightview);
~CrossfadeView ();
boost::shared_ptr<ARDOUR::Crossfade> crossfade; // ok, let 'em have it
AudioRegionView& left_view; // and these too
AudioRegionView& right_view;
void set_heights (double, double);
bool valid() const { return _valid; }
bool visible() const { return _visible; }
void set_valid (bool yn);
static PBD::Signal1<void,CrossfadeView*> CatchDeletion;
void fake_hide ();
void hide ();
void show ();
void horizontal_position_changed ();
protected:
void reset_width_dependent_items (double pixel_width);
private:
bool _valid;
bool _visible;
bool _all_in_view;
double _child_height;
ArdourCanvas::PolyLine *fade_in;
ArdourCanvas::PolyLine *fade_out;
void crossfade_changed (const PBD::PropertyChange&);
void crossfade_fades_changed ();
void active_changed ();
void redraw_curves ();
void color_handler ();
};
#endif /* __gtk_ardour_crossfade_view_h__ */

View File

@ -660,7 +660,7 @@ Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, C
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
clicked_control_point = cp;
clicked_axisview = &cp->line().trackview;
clicked_axisview = &cp->line().trackview();
clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
clicked_regionview = 0;
break;
@ -689,7 +689,7 @@ Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, Automation
}
clicked_control_point = 0;
clicked_axisview = &al->trackview;
clicked_axisview = &al->trackview();
clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
return typed_event (item, event, type);

View File

@ -4427,7 +4427,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
timepos_t earliest (earliest_time);
/* XXX: not ideal, as there may be more than one track involved in the point selection */
_last_cut_copy_source_track = &selection->points.front()->line().trackview;
_last_cut_copy_source_track = &selection->points.front()->line().trackview();
/* Keep a record of the AutomationLists that we end up using in this operation */
typedef std::map<boost::shared_ptr<AutomationList>, AutomationRecord> Lists;

View File

@ -68,7 +68,7 @@ GhostRegion::GhostRegion (RegionView& rv,
CANVAS_DEBUG_NAME (base_rect, "ghost region rect");
base_rect->set_x0 (0);
base_rect->set_y0 (1.0);
base_rect->set_y1 (trackview.current_height());
base_rect->set_y1 (2.0); /* set height will change this later */
base_rect->set_outline (false);
if (!is_automation_ghost()) {
@ -97,9 +97,15 @@ GhostRegion::set_duration (double units)
}
void
GhostRegion::set_height ()
GhostRegion::set_height (double h)
{
base_rect->set_y1 (trackview.current_height());
base_rect->set_y1 (h);
}
double
GhostRegion::height() const
{
return base_rect->y1 ();
}
void
@ -141,14 +147,14 @@ AudioGhostRegion::set_samples_per_pixel (double fpp)
}
void
AudioGhostRegion::set_height ()
AudioGhostRegion::set_height (double h)
{
vector<ArdourWaveView::WaveView*>::iterator i;
uint32_t n;
GhostRegion::set_height();
GhostRegion::set_height (h);
double const ht = ((trackview.current_height()) / (double) waves.size());
double const ht = (h / (double) waves.size());
for (n = 0, i = waves.begin(); i != waves.end(); ++i, ++n) {
(*i)->set_height (ht);
@ -274,9 +280,9 @@ MidiGhostRegion::midi_view ()
}
void
MidiGhostRegion::set_height ()
MidiGhostRegion::set_height (double h)
{
GhostRegion::set_height();
GhostRegion::set_height (h);
update_contents_height ();
}
@ -293,22 +299,20 @@ MidiGhostRegion::set_colors()
}
static double
note_height(TimeAxisView& trackview, MidiStreamView* mv)
note_height(GhostRegion const & gr, MidiStreamView* mv)
{
const double tv_height = trackview.current_height();
const double note_range = mv->contents_note_range();
return std::max(1.0, floor(tv_height / note_range - 1.0));
return std::max(1.0, floor (gr.height() / note_range - 1.0));
}
static double
note_y(TimeAxisView& trackview, MidiStreamView* mv, uint8_t note_num)
note_y (GhostRegion const & gr, MidiStreamView* mv, uint8_t note_num)
{
const double tv_height = trackview.current_height();
const double note_range = mv->contents_note_range();
const double s = tv_height / note_range;
const double s = gr.height() / note_range;
return tv_height - (note_num + 1 - mv->lowest_note()) * s;
return gr.height() - (note_num + 1 - mv->lowest_note()) * s;
}
void
@ -320,12 +324,12 @@ MidiGhostRegion::update_contents_height ()
return;
}
double const h = note_height(trackview, mv);
double const h = note_height (*this, mv);
for (EventList::iterator it = events.begin(); it != events.end(); ++it) {
uint8_t const note_num = it->second->event->note()->note();
double const y = note_y(trackview, mv, note_num);
double const y = note_y (*this, mv, note_num);
if (!it->second->is_hit) {
_tmp_rect = static_cast<ArdourCanvas::Rectangle*>(it->second->item);
@ -357,8 +361,8 @@ MidiGhostRegion::add_note (NoteBase* n)
event->item->hide();
} else {
uint8_t const note_num = n->note()->note();
double const h = note_height(trackview, mv);
double const y = note_y(trackview, mv, note_num);
double const h = note_height (*this, mv);
double const y = note_y (*this, mv, note_num);
if (!event->is_hit) {
_tmp_rect = static_cast<ArdourCanvas::Rectangle*>(event->item);
_tmp_rect->set (ArdourCanvas::Rect (_tmp_rect->x0(), y, _tmp_rect->x1(), y + h));
@ -396,8 +400,8 @@ MidiGhostRegion::update_note (GhostEvent* ev)
_tmp_rect = static_cast<ArdourCanvas::Rectangle*>(ev->item);
uint8_t const note_num = ev->event->note()->note();
double const y = note_y(trackview, mv, note_num);
double const h = note_height(trackview, mv);
double const y = note_y (*this, mv, note_num);
double const h = note_height (*this, mv);
_tmp_rect->set (ArdourCanvas::Rect (ev->event->x0(), y, ev->event->x1(), y + h));
}
@ -417,8 +421,8 @@ MidiGhostRegion::update_hit (GhostEvent* ev)
_tmp_poly = static_cast<ArdourCanvas::Polygon*>(ev->item);
uint8_t const note_num = ev->event->note()->note();
double const h = note_height(trackview, mv);
double const y = note_y(trackview, mv, note_num);
double const h = note_height (*this, mv);
double const y = note_y (*this, mv, note_num);
ArdourCanvas::Duple ppos = ev->item->position();
ArdourCanvas::Duple gpos = _tmp_poly->position();

View File

@ -43,7 +43,7 @@ class MidiRegionView;
class GhostRegion : public sigc::trackable
{
public:
public:
GhostRegion(RegionView& rv,
ArdourCanvas::Container* parent,
TimeAxisView& tv,
@ -53,10 +53,12 @@ public:
virtual ~GhostRegion();
virtual void set_samples_per_pixel (double) = 0;
virtual void set_height();
virtual void set_height (double h);
virtual void set_colors();
void set_duration(double units);
double height() const;
void set_duration (double units);
guint source_track_color(unsigned char alpha = 0xff);
bool is_automation_ghost();
@ -78,7 +80,7 @@ public:
double initial_unit_pos);
void set_samples_per_pixel (double);
void set_height();
void set_height (double h);
void set_colors();
std::vector<ArdourWaveView::WaveView*> waves;
@ -111,7 +113,7 @@ public:
MidiStreamView* midi_view();
void set_height();
void set_height (double h);
void set_samples_per_pixel (double spu);
void set_colors();

View File

@ -32,13 +32,15 @@
using namespace std;
MidiAutomationLine::MidiAutomationLine (
const std::string& name,
TimeAxisView& tav,
ArdourCanvas::Item& parent,
boost::shared_ptr<ARDOUR::AutomationList> list,
boost::shared_ptr<ARDOUR::MidiRegion> region,
Evoral::Parameter parameter)
: AutomationLine (name, tav, parent, list, parameter)
const std::string& name,
TimeThing const & tt,
ARDOUR::Session& s,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
boost::shared_ptr<ARDOUR::AutomationList> list,
boost::shared_ptr<ARDOUR::MidiRegion> region,
Evoral::Parameter parameter)
: AutomationLine (name, tt, s, tv, parent, list, parameter)
, _region (region)
, _parameter (parameter)
{
@ -71,7 +73,7 @@ MidiAutomationLine::get_verbose_cursor_string (double fraction) const
return AutomationLine::get_verbose_cursor_string(fraction);
}
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(trackview.get_parent());
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*> (_trackview.get_parent());
if (!mtv) {
return AutomationLine::get_verbose_cursor_string(fraction);
}

View File

@ -24,13 +24,17 @@ namespace ARDOUR {
class MidiRegion;
}
class MidiTimeAxisView;
/** Stub class so that lines for MIDI AutomationRegionViews can use the correct
* MementoCommandBinder.
*/
class MidiAutomationLine : public AutomationLine
{
public:
MidiAutomationLine (const std::string&, TimeAxisView&, ArdourCanvas::Item&,
MidiAutomationLine (const std::string&, TimeThing const &, ARDOUR::Session&,
TimeAxisView& tv,
ArdourCanvas::Item&,
boost::shared_ptr<ARDOUR::AutomationList>,
boost::shared_ptr<ARDOUR::MidiRegion>,
Evoral::Parameter);

View File

@ -90,6 +90,7 @@
#include "hit.h"
#include "patch_change.h"
#include "sys_ex.h"
#include "time_thing.h"
#include "ui_config.h"
#include "pbd/i18n.h"
@ -104,11 +105,12 @@ using Gtkmm2ext::Keyboard;
#define MIDI_BP_ZERO ((Config->get_first_midi_bank_is_zero())?0:1)
MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
TimeThing const & tt,
RouteTimeAxisView& tv,
boost::shared_ptr<MidiRegion> r,
double spu,
uint32_t basic_color)
: RegionView (parent, tv, r, spu, basic_color)
: RegionView (parent, tt, tv, r, spu, basic_color)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
@ -144,13 +146,14 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
}
MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
TimeThing const & tt,
RouteTimeAxisView& tv,
boost::shared_ptr<MidiRegion> r,
double spu,
uint32_t basic_color,
bool recording,
TimeAxisViewItem::Visibility visibility)
: RegionView (parent, tv, r, spu, basic_color, recording, visibility)
: RegionView (parent, tt, tv, r, spu, basic_color, recording, visibility)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
@ -268,8 +271,6 @@ MidiRegionView::init (bool wfd)
RegionView::init (false);
//set_height (trackview.current_height());
region_muted ();
region_sync_changed ();
region_resized (ARDOUR::bounds_change);
@ -1254,9 +1255,9 @@ MidiRegionView::display_patch_changes_on_channel (uint8_t channel, bool active_c
p->hide();
} else {
const timepos_t flag_time = _region->source_beats_to_absolute_time ((*i)->time());
const double flag_x = trackview.editor().time_to_pixel (flag_time);
const double flag_x = time_thing.time_to_pixel (flag_time);
const double region_x = trackview.editor().time_to_pixel (_region->position());
const double region_x = time_thing.time_to_pixel (_region->position());
p->canvas_item()->set_position (ArdourCanvas::Duple (flag_x-region_x, 1.0));
p->update_name ();
@ -1327,7 +1328,7 @@ MidiRegionView::display_sysexes()
}
string text = str.str();
const double x = trackview.editor().time_to_pixel (_region->source_beats_to_region_time (time.beats()));
const double x = time_thing.time_to_pixel (_region->source_beats_to_region_time (time.beats()));
double height = midi_stream_view()->contents_height();
@ -1461,7 +1462,7 @@ MidiRegionView::apply_note_range (uint8_t min, uint8_t max, bool force)
GhostRegion*
MidiRegionView::add_ghost (TimeAxisView& tv)
{
double unit_position = trackview.editor().time_to_pixel (_region->position ());
double unit_position = time_thing.time_to_pixel (_region->position ());
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(&tv);
MidiGhostRegion* ghost;
@ -1475,7 +1476,6 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
}
ghost->set_colors ();
ghost->set_height ();
ghost->set_duration (_region->length().samples() / samples_per_pixel);
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
@ -1530,7 +1530,7 @@ MidiRegionView::resolve_note (uint8_t note, Temporal::Beats end_time)
_active_notes[note]->note()->set_length (end_time - _active_notes[note]->note()->time());
/* End time is relative to the region being recorded. */
_active_notes[note]->set_x1 (trackview.editor().time_to_pixel (_region->region_beats_to_region_time (end_time)));
_active_notes[note]->set_x1 (time_thing.time_to_pixel (_region->region_beats_to_region_time (end_time)));
_active_notes[note]->set_outline_all ();
_active_notes[note] = 0;
}
@ -1548,7 +1548,7 @@ MidiRegionView::extend_active_notes()
for (unsigned i = 0; i < 128; ++i) {
if (_active_notes[i]) {
_active_notes[i]->set_x1 (trackview.editor().duration_to_pixels (_region->length()));
_active_notes[i]->set_x1 (time_thing.duration_to_pixels (_region->length()));
}
}
}
@ -1658,7 +1658,7 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
const samplepos_t note_start_samples = (note_start + session_source_start).earlier ( _region->position()).samples();
const double x0 = trackview.editor().sample_to_pixel (note_start_samples);
const double x0 = time_thing.sample_to_pixel (note_start_samples);
double x1;
@ -1683,13 +1683,13 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
const samplepos_t note_end_samples = _region->position().distance ((note_end + session_source_start)).samples();
x1 = std::max(1., trackview.editor().sample_to_pixel (note_end_samples)) - 1;
x1 = std::max(1., time_thing.sample_to_pixel (note_end_samples)) - 1;
} else {
/* nascent note currently being recorded, noteOff has not yet arrived */
x1 = std::max(1., trackview.editor().duration_to_pixels (_region->length())) - 1;
x1 = std::max(1., time_thing.duration_to_pixels (_region->length())) - 1;
}
y1 = y0 + std::max(1., floor(note_height()) - 1);
@ -1731,7 +1731,7 @@ MidiRegionView::update_hit (Hit* ev, bool update_ghost_regions)
boost::shared_ptr<NoteType> note = ev->note();
const timepos_t note_time = _region->source_beats_to_absolute_time (note->time());
const double x = trackview.editor().time_to_pixel(note_time) - trackview.editor().time_to_pixel (_region->position());
const double x = time_thing.time_to_pixel(note_time) - time_thing.time_to_pixel (_region->position());
const double diamond_size = std::max(1., floor(note_height()) - 2.);
const double y = 1.5 + floor(note_to_y(note->note())) + diamond_size * .5;
@ -2380,8 +2380,8 @@ MidiRegionView::update_drag_selection(timepos_t const & start, timepos_t const &
// Convert to local coordinates
const double y = midi_view()->y_position();
const double x0 = editor.time_to_pixel (max (timepos_t(), _region->region_relative_position (start)));
const double x1 = editor.time_to_pixel (max (timepos_t(), _region->region_relative_position (end)));
const double x0 = time_thing.time_to_pixel (max (timepos_t(), _region->region_relative_position (start)));
const double x1 = time_thing.time_to_pixel (max (timepos_t(), _region->region_relative_position (end)));
const double y0 = max(0.0, gy0 - y);
const double y1 = max(0.0, gy1 - y);
@ -2513,7 +2513,6 @@ void
MidiRegionView::move_selection(timecnt_t const & dx_qn, double dy, double cumulative_dy)
{
typedef vector<boost::shared_ptr<NoteType> > PossibleChord;
Editor* editor = dynamic_cast<Editor*> (&trackview.editor());
PossibleChord to_play;
Temporal::Beats earliest = earliest_in_selection();
@ -2526,13 +2525,13 @@ MidiRegionView::move_selection(timecnt_t const & dx_qn, double dy, double cumula
double dx = 0.0;
if (midi_view()->note_mode() == Sustained) {
dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
dx = time_thing.time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
- n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
} else {
/* Hit::x0() is offset by _position.x, unlike Note::x0() */
Hit* hit = dynamic_cast<Hit*>(n);
if (hit) {
dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
dx = time_thing.time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
- n->item()->item_to_canvas (ArdourCanvas::Duple (((hit->x0() + hit->x1()) / 2.0) - hit->position().x, 0)).x;
}
}
@ -2542,7 +2541,7 @@ MidiRegionView::move_selection(timecnt_t const & dx_qn, double dy, double cumula
/* update length */
if (midi_view()->note_mode() == Sustained) {
Note* sus = dynamic_cast<Note*> (*i);
double const len_dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
double const len_dx = time_thing.time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
sus->set_x1 (n->item()->canvas_to_item (ArdourCanvas::Duple (len_dx, 0)).x);
}
@ -2637,7 +2636,7 @@ MidiRegionView::move_copies (timecnt_t const & dx_qn, double dy, double cumulati
if (midi_view()->note_mode() == Sustained) {
Note* sus = dynamic_cast<Note*> (*i);
double const len_dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
double const len_dx = time_thing.time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
sus->set_x1 (n->item()->canvas_to_item (ArdourCanvas::Duple (len_dx, 0)).x);
}
@ -2797,20 +2796,20 @@ MidiRegionView::snap_pixel_to_time (double x, bool ensure_snap)
double
MidiRegionView::snap_to_pixel(double x, bool ensure_snap)
{
return (double) trackview.editor().time_to_pixel(snap_pixel_to_time(x, ensure_snap));
return (double) time_thing.time_to_pixel(snap_pixel_to_time(x, ensure_snap));
}
double
MidiRegionView::get_position_pixels()
{
return trackview.editor().time_to_pixel(get_position());
return time_thing.time_to_pixel(get_position());
}
double
MidiRegionView::get_end_position_pixels()
{
const timepos_t end = get_position() + get_duration ();
return trackview.editor().time_to_pixel (end);
return time_thing.time_to_pixel (end);
}
void
@ -2893,8 +2892,8 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
*/
current_x = 0;
}
if (current_x > trackview.editor().duration_to_pixels (_region->length())) {
current_x = trackview.editor().duration_to_pixels (_region->length());
if (current_x > time_thing.duration_to_pixels (_region->length())) {
current_x = time_thing.duration_to_pixels (_region->length());
}
if (at_front) {
@ -2934,7 +2933,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
if (with_snap) {
snapped_x = snap_pixel_to_time (current_x, ensure_snap); /* units depend on snap settings */
} else {
snapped_x = timepos_t (trackview.editor ().pixel_to_sample (current_x)); /* probably samples */
snapped_x = timepos_t (time_thing.pixel_to_sample (current_x)); /* probably samples */
}
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
@ -3013,12 +3012,12 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
current_x = 0;
}
if (current_x > trackview.editor().duration_to_pixels (_region->length())) {
current_x = trackview.editor().duration_to_pixels (_region->length());
if (current_x > time_thing.duration_to_pixels (_region->length())) {
current_x = time_thing.duration_to_pixels (_region->length());
}
/* Convert snap delta from pixels to beats with sign. */
timepos_t snap_delta_time (trackview.editor().pixel_to_sample (snap_delta));
timepos_t snap_delta_time (time_thing.pixel_to_sample (snap_delta));
Temporal::Beats snap_delta_beats;
int sign = 1;
@ -3034,7 +3033,7 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
if (with_snap) {
current_time = snap_pixel_to_time (current_x, ensure_snap);
} else {
current_time = timepos_t (trackview.editor().pixel_to_sample (current_x));
current_time = timepos_t (time_thing.pixel_to_sample (current_x));
}
/* and then to beats */
@ -3884,7 +3883,7 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state)
PublicEditor& editor = trackview.editor ();
samplepos_t const unsnapped_sample = editor.pixel_to_sample (global_x);
samplepos_t const unsnapped_sample = time_thing.pixel_to_sample (global_x);
const Temporal::timepos_t snapped_pos = editor.snap_to_bbt (timepos_t (unsnapped_sample), RoundDownAlways, SnapToGrid_Unscaled);
const Temporal::Beats snapped_beats = _region->position().distance (snapped_pos).beats ();
@ -4051,7 +4050,7 @@ MidiRegionView::move_step_edit_cursor (Temporal::Beats pos)
_step_edit_cursor_position = pos;
if (_step_edit_cursor) {
double pixel = trackview.editor().time_to_pixel (_region->region_beats_to_region_time (pos));
double pixel = time_thing.time_to_pixel (_region->region_beats_to_region_time (pos));
_step_edit_cursor->set_x0 (pixel);
set_step_edit_cursor_width (_step_edit_cursor_width);
}
@ -4071,7 +4070,7 @@ MidiRegionView::set_step_edit_cursor_width (Temporal::Beats beats)
_step_edit_cursor_width = beats;
if (_step_edit_cursor) {
_step_edit_cursor->set_x1 (_step_edit_cursor->x0() + trackview.editor().duration_to_pixels (
_step_edit_cursor->set_x1 (_step_edit_cursor->x0() + time_thing.duration_to_pixels (
_region->region_beats_to_region_time (_step_edit_cursor_position).distance
(_region->region_beats_to_region_time (_step_edit_cursor_position + beats))));
}

View File

@ -75,12 +75,14 @@ public:
typedef Evoral::Sequence<Temporal::Beats>::Notes Notes;
MidiRegionView (ArdourCanvas::Container* parent,
TimeThing const & tt,
RouteTimeAxisView& tv,
boost::shared_ptr<ARDOUR::MidiRegion> r,
double samples_per_pixel,
uint32_t basic_color);
MidiRegionView (ArdourCanvas::Container* parent,
TimeThing const & tt,
RouteTimeAxisView& tv,
boost::shared_ptr<ARDOUR::MidiRegion> r,
double samples_per_pixel,

View File

@ -117,11 +117,11 @@ MidiStreamView::create_region_view (boost::shared_ptr<Region> r, bool /*wfd*/, b
RegionView* region_view = NULL;
if (recording) {
region_view = new MidiRegionView (
_canvas_group, _trackview, region,
_canvas_group, PublicEditor::instance(), _trackview, region,
_samples_per_pixel, region_color, recording,
TimeAxisViewItem::Visibility(TimeAxisViewItem::ShowFrame));
} else {
region_view = new MidiRegionView (_canvas_group, _trackview, region,
region_view = new MidiRegionView (_canvas_group, PublicEditor::instance(), _trackview, region,
_samples_per_pixel, region_color);
}

View File

@ -63,6 +63,7 @@
#include "axis_provider.h"
#include "editing.h"
#include "selection.h"
#include "time_thing.h"
namespace ARDOUR {
class Session;
@ -116,7 +117,7 @@ using ARDOUR::samplecnt_t;
* of PublicEditor need not be recompiled if private methods or member variables
* change.
*/
class PublicEditor : public ArdourWidgets::Tabbable, public ARDOUR::SessionHandlePtr, public AxisViewProvider
class PublicEditor : public ArdourWidgets::Tabbable, public ARDOUR::SessionHandlePtr, public AxisViewProvider, public TimeThing
{
public:
PublicEditor (Gtk::Widget& content);
@ -211,14 +212,6 @@ public:
virtual void separate_region_from_selection () = 0;
virtual void transition_to_rolling (bool fwd) = 0;
virtual samplepos_t pixel_to_sample (double pixel) const = 0;
virtual samplepos_t playhead_cursor_sample () const = 0;
virtual double sample_to_pixel (samplepos_t sample) const = 0;
virtual double sample_to_pixel_unrounded (samplepos_t sample) const = 0;
virtual double time_to_pixel (Temporal::timepos_t const &) const = 0;
virtual double time_to_pixel_unrounded (Temporal::timepos_t const &) const = 0;
virtual double duration_to_pixels (Temporal::timecnt_t const &) const = 0;
virtual double duration_to_pixels_unrounded (Temporal::timecnt_t const &) const = 0;
virtual Selection& get_selection () const = 0;
virtual bool get_selection_extents (Temporal::timepos_t &start, Temporal::timepos_t &end) const = 0;

View File

@ -43,8 +43,8 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView& r, ArdourCanvas::Container& parent, boost::shared_ptr<AutomationList> l)
: AutomationLine (name, r.get_time_axis_view(), parent, l, l->parameter())
AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView& r, TimeThing const & tt, TimeAxisView& tv, ArdourCanvas::Container& parent, boost::shared_ptr<AutomationList> l)
: AutomationLine (name, tt, r.region()->session(), tv, parent, l, l->parameter())
, rv (r)
{
// If this isn't true something is horribly wrong, and we'll get catastrophic gain values
@ -72,7 +72,7 @@ AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fracti
// 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));
_session.add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), &rv.audio_region()->get_state(), 0));
rv.audio_region()->set_envelope_active(false);
}
}
@ -81,21 +81,22 @@ AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fracti
void
AudioRegionGainLine::remove_point (ControlPoint& cp)
{
trackview.editor().begin_reversible_command (_("remove control point"));
PublicEditor& e (PublicEditor::instance());
e.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()));
_session.add_command(new StatefulDiffCommand (rv.audio_region()));
}
trackview.editor ().get_selection ().clear_points ();
e.get_selection ().clear_points ();
alist->erase (cp.model());
trackview.editor().session()->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
trackview.editor().commit_reversible_command ();
trackview.editor().session()->set_dirty ();
_session.add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
e.commit_reversible_command ();
_session.set_dirty ();
}
void
@ -103,7 +104,7 @@ 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()));
_session.add_command (new MementoCommand<AudioRegion>(*(rv.audio_region().get()), 0, &rv.audio_region()->get_state()));
}
AutomationLine::end_drag (with_push, final_index);

View File

@ -40,7 +40,7 @@ class AudioRegionView;
class AudioRegionGainLine : public AutomationLine
{
public:
AudioRegionGainLine (const std::string & name, AudioRegionView&, ArdourCanvas::Container& parent, boost::shared_ptr<ARDOUR::AutomationList>);
AudioRegionGainLine (const std::string & name, AudioRegionView&, TimeThing const &, TimeAxisView& tv, ArdourCanvas::Container& parent, boost::shared_ptr<ARDOUR::AutomationList>);
Temporal::timepos_t get_origin() const;

View File

@ -74,12 +74,13 @@ static const int32_t sync_mark_width = 9;
PBD::Signal1<void,RegionView*> RegionView::RegionViewGoingAway;
RegionView::RegionView (ArdourCanvas::Container* parent,
TimeThing const & tt,
TimeAxisView& tv,
boost::shared_ptr<ARDOUR::Region> r,
double spu,
uint32_t basic_color,
bool automation)
: TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), false, automation,
: TimeAxisViewItem (r->name(), *parent, tt, tv, spu, basic_color, r->position(), r->length(), false, automation,
(automation ? TimeAxisViewItem::ShowFrame :
TimeAxisViewItem::Visibility ((UIConfiguration::instance().get_show_region_name() ? TimeAxisViewItem::ShowNameText : 0) |
TimeAxisViewItem::ShowNameHighlight| TimeAxisViewItem::ShowFrame)))
@ -153,13 +154,14 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other
RegionView::RegionView (ArdourCanvas::Container* parent,
TimeThing const & tt,
TimeAxisView& tv,
boost::shared_ptr<ARDOUR::Region> r,
double spu,
uint32_t basic_color,
bool recording,
TimeAxisViewItem::Visibility visibility)
: TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), recording, false, visibility)
: TimeAxisViewItem (r->name(), *parent, tt, tv, spu, basic_color, r->position(), r->length(), recording, false, visibility)
, _region (r)
, sync_mark(0)
, sync_line(0)
@ -242,9 +244,6 @@ RegionView::init (bool wfd)
_enable_display = true;
}
/* derived class calls set_height () including RegionView::set_height() in ::init() */
//set_height (trackview.current_height());
_region->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RegionView::region_changed, this, _1), gui_context());
/* derived class calls set_colors () including RegionView::set_colors() in ::init() */
@ -310,8 +309,8 @@ RegionView::set_silent_frames (const AudioIntervalResult& silences, double /*thr
/* coordinates for the rect are relative to the regionview origin */
cr->set_x0 (trackview.editor().sample_to_pixel (i->first - _region->start_sample()));
cr->set_x1 (trackview.editor().sample_to_pixel (i->second - _region->start_sample()));
cr->set_x0 (time_thing.sample_to_pixel (i->first - _region->start_sample()));
cr->set_x1 (time_thing.sample_to_pixel (i->second - _region->start_sample()));
cr->set_y0 (1);
cr->set_y1 (_height - 2);
cr->set_outline (false);
@ -345,7 +344,7 @@ RegionView::set_silent_frames (const AudioIntervalResult& silences, double /*thr
/* both positions are relative to the region start offset in source */
_silence_text->set_x_position (trackview.editor().sample_to_pixel (silences.front().first - _region->start_sample()) + 10.0);
_silence_text->set_x_position (time_thing.sample_to_pixel (silences.front().first - _region->start_sample()) + 10.0);
_silence_text->set_y_position (20.0);
double ms = (float) shortest/_region->session().sample_rate();
@ -505,7 +504,7 @@ RegionView::reset_width_dependent_items (double pixel_width)
if (_xrun_markers_visible) {
const samplepos_t start = _region->start_sample();
for (list<std::pair<samplepos_t, ArdourCanvas::Arrow*> >::iterator i = _xrun_markers.begin(); i != _xrun_markers.end(); ++i) {
float x_pos = trackview.editor().sample_to_pixel (i->first - start);
float x_pos = time_thing.sample_to_pixel (i->first - start);
i->second->set_x (x_pos);
}
}
@ -522,7 +521,7 @@ RegionView::update_xrun_markers ()
const samplepos_t start = _region->start_sample();
const samplepos_t length = _region->length_samples();
for (list<std::pair<samplepos_t, ArdourCanvas::Arrow*> >::iterator i = _xrun_markers.begin(); i != _xrun_markers.end(); ++i) {
float x_pos = trackview.editor().sample_to_pixel (i->first - start);
float x_pos = time_thing.sample_to_pixel (i->first - start);
i->second->set_x (x_pos);
if (show_xruns_markers && (i->first >= start && i->first < start + length)) {
i->second->show ();
@ -881,7 +880,7 @@ RegionView::region_sync_changed ()
//points = sync_mark->property_points().get_value();
double offset = trackview.editor().duration_to_pixels (sync_offset);
double offset = time_thing.duration_to_pixels (sync_offset);
points.push_back (ArdourCanvas::Duple (offset - ((sync_mark_width-1)/2), 1));
points.push_back (ArdourCanvas::Duple (offset + ((sync_mark_width-1)/2), 1));
points.push_back (ArdourCanvas::Duple (offset, sync_mark_width - 1));
@ -958,7 +957,7 @@ RegionView::set_height (double h)
int sync_dir;
timecnt_t sync_offset;
sync_offset = _region->sync_offset (sync_dir);
double offset = trackview.editor().duration_to_pixels (sync_offset);
double offset = time_thing.duration_to_pixels (sync_offset);
sync_line->set (
ArdourCanvas::Duple (offset, 0),
@ -1020,14 +1019,14 @@ RegionView::update_coverage_frame (LayerDisplay d)
bool const new_me = (pl->top_unmuted_region_at (t) == _region);
/* finish off any old rect, if required */
if (cr && me != new_me) {
cr->set_x1 (trackview.editor().duration_to_pixels (position.distance (t)));
cr->set_x1 (time_thing.duration_to_pixels (position.distance (t)));
}
/* start off any new rect, if required */
if (cr == 0 || me != new_me) {
cr = new ArdourCanvas::Rectangle (group);
_coverage_frame.push_back (cr);
cr->set_x0 (trackview.editor().duration_to_pixels (position.distance (t)));
cr->set_x0 (time_thing.duration_to_pixels (position.distance (t)));
cr->set_y0 (1);
cr->set_y1 (_height + 1);
cr->set_outline (false);
@ -1049,7 +1048,7 @@ RegionView::update_coverage_frame (LayerDisplay d)
if (cr) {
/* finish off the last rectangle */
cr->set_x1 (trackview.editor().duration_to_pixels (position.distance (end)));
cr->set_x1 (time_thing.duration_to_pixels (position.distance (end)));
}
if (frame_handle_start) {

View File

@ -41,6 +41,7 @@
#include "marker.h"
class TimeAxisView;
class TimeThing;
class RegionEditor;
class GhostRegion;
class AutomationTimeAxisView;
@ -55,6 +56,7 @@ class RegionView : public TimeAxisViewItem
{
public:
RegionView (ArdourCanvas::Container* parent,
TimeThing const & time_thing,
TimeAxisView& time_view,
boost::shared_ptr<ARDOUR::Region> region,
double samples_per_pixel,
@ -141,6 +143,7 @@ protected:
* to the TimeAxisViewItem parent class
*/
RegionView (ArdourCanvas::Container *,
TimeThing const &,
TimeAxisView&,
boost::shared_ptr<ARDOUR::Region>,
double samples_per_pixel,

View File

@ -1116,7 +1116,7 @@ Selection::get_state () const
}
for (PointSelection::const_iterator i = points.begin(); i != points.end(); ++i) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (&(*i)->line().trackview);
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (&(*i)->line().trackview());
if (atv) {
XMLNode* r = node->add_child (X_("ControlPoint"));

View File

@ -350,10 +350,6 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
}
}
for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
(*i)->set_height ();
}
/* put separator at the bottom of this time axis view */
_canvas_separator->set (ArdourCanvas::Duple(0, height), ArdourCanvas::Duple(ArdourCanvas::COORD_MAX, height));
@ -621,7 +617,7 @@ TimeAxisView::set_height (uint32_t h, TrackHeightMode m)
set_gui_property ("height", height);
for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
(*i)->set_height ();
(*i)->set_height (current_height());
}
if (selection_group->visible ()) {
@ -1105,6 +1101,7 @@ TimeAxisView::add_ghost (RegionView* rv)
GhostRegion* gr = rv->add_ghost (*this);
if (gr) {
gr->set_height (current_height());
ghosts.push_back(gr);
}
}

View File

@ -49,6 +49,7 @@
#include "ui_config.h"
#include "utils.h"
#include "rgb_macros.h"
#include "time_thing.h"
#include "pbd/i18n.h"
@ -120,10 +121,11 @@ TimeAxisViewItem::set_constant_heights ()
* @param automation true if this is an automation region view
*/
TimeAxisViewItem::TimeAxisViewItem(
const string & it_name, ArdourCanvas::Item& parent, TimeAxisView& tv, double spu, uint32_t base_color,
const string & it_name, ArdourCanvas::Item& parent, TimeThing const & tt, TimeAxisView& tv, double spu, uint32_t base_color,
timepos_t const & start, timecnt_t const & duration, bool recording, bool automation, Visibility vis
)
: trackview (tv)
, time_thing (tt)
, item_name (it_name)
, selection_frame (0)
, _height (1.0)
@ -140,6 +142,7 @@ TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
, Selectable (other)
, PBD::ScopedConnectionList()
, trackview (other.trackview)
, time_thing (other.time_thing)
, item_name (other.item_name)
, selection_frame (0)
, _height (1.0)
@ -189,8 +192,8 @@ TimeAxisViewItem::init (ArdourCanvas::Item* parent, double fpp, uint32_t base_co
if (visibility & ShowFrame) {
frame = new ArdourCanvas::Rectangle (group,
ArdourCanvas::Rect (0.0, 0.0,
trackview.editor().duration_to_pixels (duration),
trackview.current_height()));
time_thing.duration_to_pixels (duration),
1.0)); /* set_height() will fix */
frame->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::LEFT|ArdourCanvas::Rectangle::RIGHT));
frame->show ();
@ -220,11 +223,7 @@ TimeAxisViewItem::init (ArdourCanvas::Item* parent, double fpp, uint32_t base_co
if (visibility & ShowNameText) {
name_text = new ArdourCanvas::Text (group);
CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
if (UIConfiguration::instance().get_show_name_highlight()) {
name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, trackview.current_height() - NAME_Y_OFFSET));
} else {
name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, NAME_Y_OFFSET));
}
/* ::set_height() will set the position */
name_text->set_font_description (NAME_FONT);
name_text->set_ignore_events (true);
} else {
@ -236,13 +235,13 @@ TimeAxisViewItem::init (ArdourCanvas::Item* parent, double fpp, uint32_t base_co
double top = TimeAxisViewItem::GRAB_HANDLE_TOP;
double width = TimeAxisViewItem::GRAB_HANDLE_WIDTH;
frame_handle_start = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()));
frame_handle_start = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, 1.0));
CANVAS_DEBUG_NAME (frame_handle_start, "TAVI frame handle start");
frame_handle_start->set_outline (false);
frame_handle_start->set_fill (false);
frame_handle_start->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_start));
frame_handle_end = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()));
frame_handle_end = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, 1.0));
CANVAS_DEBUG_NAME (frame_handle_end, "TAVI frame handle end");
frame_handle_end->set_outline (false);
frame_handle_end->set_fill (false);
@ -289,7 +288,7 @@ TimeAxisViewItem::set_position(timepos_t const & pos, void* src, double* delta)
time_position = pos;
double new_unit_pos = trackview.editor().time_to_pixel (time_position);
double new_unit_pos = time_thing.time_to_pixel (time_position);
if (delta) {
(*delta) = new_unit_pos - group->position().x;
@ -342,8 +341,8 @@ TimeAxisViewItem::set_duration (timecnt_t const & dur, void* src)
item_duration = dur;
double end_pixel = trackview.editor().time_to_pixel (time_position + dur);
double first_pixel = trackview.editor().time_to_pixel (time_position);
double end_pixel = time_thing.time_to_pixel (time_position + dur);
double first_pixel = time_thing.time_to_pixel (time_position);
reset_width_dependent_items (end_pixel - first_pixel);
@ -506,7 +505,7 @@ TimeAxisViewItem::set_selected(bool yn)
selection_frame->set_outline_color (UIConfiguration::instance().color ("selected time axis frame"));
selection_frame->set_ignore_events (true);
}
selection_frame->set (frame->get().shrink (1.0));
selection_frame->set (frame->get().shrink (0.0, 0.0, 0.0, 1.0));
selection_frame->show ();
} else {
if (selection_frame) {
@ -573,7 +572,7 @@ TimeAxisViewItem::set_height (double height)
}
if (selection_frame) {
selection_frame->set (frame->get().shrink (1.0));
selection_frame->set (frame->get().shrink (0.0, 0.0, 0.0, 1.0));
}
}
}
@ -806,8 +805,8 @@ TimeAxisViewItem::set_samples_per_pixel (double fpp)
samples_per_pixel = fpp;
set_position (this->get_position(), this);
double end_pixel = trackview.editor().time_to_pixel (time_position + get_duration());
double first_pixel = trackview.editor().time_to_pixel (time_position);
double end_pixel = time_thing.time_to_pixel (time_position + get_duration());
double first_pixel = time_thing.time_to_pixel (time_position);
reset_width_dependent_items (end_pixel - first_pixel);
}
@ -841,7 +840,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
frame->set_x1 (pixel_width);
if (selection_frame) {
selection_frame->set (frame->get().shrink (1.0));
selection_frame->set (frame->get().shrink (0.0, 0.0, 0.0, 1.0));
}
}

View File

@ -33,6 +33,7 @@
#include "selectable.h"
class TimeAxisView;
class TimeThing;
namespace ArdourCanvas {
class Pixbuf;
@ -160,7 +161,7 @@ public:
virtual void update_visibility () {}
protected:
TimeAxisViewItem (const std::string &, ArdourCanvas::Item&, TimeAxisView&, double, uint32_t fill_color,
TimeAxisViewItem (const std::string &, ArdourCanvas::Item&, TimeThing const &, TimeAxisView&, double, uint32_t fill_color,
Temporal::timepos_t const &, Temporal::timecnt_t const &, bool recording = false, bool automation = false, Visibility v = Visibility (0));
TimeAxisViewItem (const TimeAxisViewItem&);
@ -182,6 +183,9 @@ protected:
/** time axis that this item is on */
TimeAxisView& trackview;
/** TimeThing used to provide pixel<->time conversions */
TimeThing const & time_thing;
/** indicates whether this item is locked to its current position */
bool position_locked;

34
gtk2_ardour/time_thing.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2021 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_time_thing_h__
#define __gtk2_ardour_time_thing_h__
struct TimeThing {
virtual ~TimeThing() {}
virtual samplepos_t pixel_to_sample (double pixel) const = 0;
virtual samplepos_t playhead_cursor_sample () const = 0;
virtual double sample_to_pixel (samplepos_t sample) const = 0;
virtual double sample_to_pixel_unrounded (samplepos_t sample) const = 0;
virtual double time_to_pixel (Temporal::timepos_t const &) const = 0;
virtual double time_to_pixel_unrounded (Temporal::timepos_t const &) const = 0;
virtual double duration_to_pixels (Temporal::timecnt_t const &) const = 0;
virtual double duration_to_pixels_unrounded (Temporal::timecnt_t const &) const = 0;
};
#endif /* __gtk2_ardour_time_thing_h__ */

View File

@ -38,6 +38,8 @@
#include "ui_config.h"
#include "utils.h"
#include "audio_clip_editor.h"
#include "pbd/i18n.h"
#define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ()))
@ -53,6 +55,9 @@ TriggerPage::TriggerPage ()
load_bindings ();
register_actions ();
_clip_editor = new AudioClipEditor;
_parameter_box.pack_start (*_clip_editor);
#if 1 /* Placeholders */
_slot_area_box.pack_start (*Gtk::manage (new Gtk::Label ("Fixed\nWidth\nSlot\nArea")));
_browser_box.pack_start (*Gtk::manage (new Gtk::Label ("File Browser")));

View File

@ -30,6 +30,7 @@
#include "widgets/tabbable.h"
class TriggerStrip;
class AudioClipEditor;
class TriggerPage : public ArdourWidgets::Tabbable, public ARDOUR::SessionHandlePtr, public PBD::ScopedConnectionList
{
@ -76,6 +77,8 @@ private:
Gtk::VBox _browser_box;
Gtk::HBox _parameter_box;
AudioClipEditor* _clip_editor;
std::list<TriggerStrip*> _strips;
sigc::connection _fast_screen_update_connection;
};