#include "ardour/session.h"
#include "ardour/smf_source.h"
-#include "ardour_ui.h"
-#include "global_signals.h"
#include "gui_thread.h"
#include "midi_region_view.h"
#include "midi_streamview.h"
#include "region_view.h"
#include "rgb_macros.h"
#include "selection.h"
+#include "ui_config.h"
#include "utils.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace std;
using namespace ARDOUR;
can be put below ghost regions from MIDI underlays
*/
_note_lines = new ArdourCanvas::LineSet (_canvas_group, ArdourCanvas::LineSet::Horizontal);
-
+
_note_lines->Event.connect(
sigc::bind(sigc::mem_fun(_trackview.editor(),
&PublicEditor::canvas_stream_view_event),
color_handler ();
- ColorsChanged.connect(sigc::mem_fun(*this, &MidiStreamView::color_handler));
+ UIConfiguration::instance().ColorsChanged.connect(sigc::mem_fun(*this, &MidiStreamView::color_handler));
note_range_adjustment.set_page_size(_highest_note - _lowest_note);
note_range_adjustment.set_value(_lowest_note);
}
RegionView*
-MidiStreamView::create_region_view (boost::shared_ptr<Region> r, bool /*wfd*/, bool)
+MidiStreamView::create_region_view (boost::shared_ptr<Region> r, bool /*wfd*/, bool recording)
{
boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion> (r);
return 0;
}
- RegionView* region_view = new MidiRegionView (_canvas_group, _trackview, region,
- _samples_per_pixel, region_color);
+ RegionView* region_view = NULL;
+ if (recording) {
+ region_view = new MidiRegionView (
+ _canvas_group, _trackview, region,
+ _samples_per_pixel, region_color, recording,
+ TimeAxisViewItem::Visibility(TimeAxisViewItem::ShowFrame));
+ } else {
+ region_view = new MidiRegionView (_canvas_group, _trackview, region,
+ _samples_per_pixel, region_color);
+ }
region_view->init (false);
region_views.push_front (region_view);
- if (_trackview.editor().internal_editing()) {
- region_view->hide_rect ();
- } else {
- region_view->show_rect ();
- }
-
/* display events and find note range */
display_region (region_view, wait_for_data);
}
if (load_model) {
- source->load_model();
+ Glib::Threads::Mutex::Lock lm(source->mutex());
+ source->load_model(lm);
}
if (!source->model()) {
{
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(r);
if (mr) {
- mr->midi_source(0)->load_model();
+ Glib::Threads::Mutex::Lock lm(mr->midi_source(0)->mutex());
+ mr->midi_source(0)->load_model(lm);
_range_dirty = update_data_note_range(
mr->model()->lowest_note(),
mr->model()->highest_note());
return dirty;
}
+void
+MidiStreamView::set_layer_display (LayerDisplay d)
+{
+
+//revert this change for now. Although stacked view is weirdly implemented wrt the "scroomer", it is still necessary to manage layered midi regions.
+// if (d != Overlaid) {
+// return;
+// }
+
+ StreamView::set_layer_display (d);
+}
+
void
MidiStreamView::redisplay_track ()
{
*/
if (i <= highest_note()) {
- _note_lines->add (y, 1.0, ARDOUR_UI::config()->color ("piano roll black outline"));
+ _note_lines->add (y, 1.0, UIConfiguration::instance().color ("piano roll black outline"));
}
/* now add a thicker line/bar which covers the entire vertical
case 6:
case 8:
case 10:
- color = ARDOUR_UI::config()->color ("piano roll black");
+ color = UIConfiguration::instance().color_mod ("piano roll black", "piano roll black");
break;
default:
- color = ARDOUR_UI::config()->color_mod ("piano roll white", "piano roll white");
+ color = UIConfiguration::instance().color_mod ("piano roll white", "piano roll white");
break;
}
double h = y - prev_y;
double mid = y + (h/2.0);
-
+
if (height > 1.0) { // XXX ? should that not be h >= 1 ?
_note_lines->add (mid, h, color);
}
if (!rec_active &&
_trackview.session()->record_status() == Session::Recording &&
- _trackview.track()->record_enabled()) {
+ _trackview.track()->rec_enable_control()->get_value()) {
- if (Config->get_show_waveforms_while_recording() && rec_regions.size() == rec_rects.size()) {
+ if (UIConfiguration::instance().get_show_waveforms_while_recording() && rec_regions.size() == rec_rects.size()) {
/* add a new region, but don't bother if they set show-waveforms-while-recording mid-record */
if (region) {
region->set_start (_trackview.track()->current_capture_start()
- _trackview.track()->get_capture_start_frame (0));
- region->set_position (_trackview.track()->current_capture_start());
- RegionView* rv = add_region_view_internal (region, false);
+ region->set_position (_trackview.session()->transport_frame());
+
+ RegionView* rv = add_region_view_internal (region, false, true);
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (rv);
mrv->begin_write ();
-
/* rec region will be destroyed in setup_rec_box */
rec_regions.push_back (make_pair (region, rv));
/* start a new rec box */
- boost::shared_ptr<MidiTrack> mt = _trackview.midi_track(); /* we know what it is already */
- framepos_t const frame_pos = mt->current_capture_start ();
- gdouble const xstart = _trackview.editor().sample_to_pixel (frame_pos);
- gdouble const xend = xstart;
- uint32_t fill_color;
-
- fill_color = ARDOUR_UI::config()->color ("recording rect");
-
- ArdourCanvas::Rectangle * rec_rect = new ArdourCanvas::Rectangle (_canvas_group);
- rec_rect->set (ArdourCanvas::Rect (xstart, 1, xend, _trackview.current_height() - 1));
- rec_rect->set_outline_color (ARDOUR_UI::config()->color ("recording rect"));
- rec_rect->set_fill_color (fill_color);
- rec_rect->lower_to_bottom();
-
- RecBoxInfo recbox;
- recbox.rectangle = rec_rect;
- recbox.start = _trackview.session()->transport_frame();
- recbox.length = 0;
-
- rec_rects.push_back (recbox);
-
- screen_update_connection.disconnect();
- screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (
- sigc::mem_fun (*this, &MidiStreamView::update_rec_box));
- rec_updating = true;
- rec_active = true;
+ create_rec_box(_trackview.midi_track()->current_capture_start(), 0);
} else if (rec_active &&
(_trackview.session()->record_status() != Session::Recording ||
- !_trackview.track()->record_enabled())) {
+ !_trackview.track()->rec_enable_control()->get_value())) {
screen_update_connection.disconnect();
rec_active = false;
rec_updating = false;
/* disconnect rapid update */
screen_update_connection.disconnect();
rec_data_ready_connections.drop_connections ();
-
rec_updating = false;
rec_active = false;
draw_note_lines ();
if (_trackview.is_midi_track()) {
- canvas_rect->set_fill_color (ARDOUR_UI::config()->color ("midi track base"));
+ canvas_rect->set_fill_color (UIConfiguration::instance().color_mod ("midi track base", "midi track base"));
} else {
- canvas_rect->set_fill_color (ARDOUR_UI::config()->color ("midi bus base"));
+ canvas_rect->set_fill_color (UIConfiguration::instance().color ("midi bus base"));
}
}
/* Update the region being recorded to reflect where we currently are */
boost::shared_ptr<ARDOUR::Region> region = rec_regions.back().first;
- region->set_length (_trackview.track()->current_capture_end () - _trackview.track()->current_capture_start());
+ region->set_length (_trackview.track()->current_capture_end () - _trackview.track()->current_capture_start(), 0);
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (rec_regions.back().second);
mrv->extend_active_notes ();
uint8_t
MidiStreamView::y_to_note (double y) const
{
- int const n = ((contents_height() - y - 1) / contents_height() * (double)contents_note_range())
+ int const n = ((contents_height() - y) / contents_height() * (double)contents_note_range())
+ lowest_note();
if (n < 0) {
return 127;
}
- return n;
+ /* min due to rounding and/or off-by-one errors */
+ return min ((uint8_t) n, highest_note());
}
/** Suspend updates to the regions' note ranges and our
MidiStreamView::resume_updates ()
{
_updates_suspended = false;
-
+
draw_note_lines ();
apply_note_range_to_regions ();
_canvas_group->redraw ();
}
-void
-MidiStreamView::leave_internal_edit_mode ()
+struct RegionPositionSorter {
+ bool operator() (RegionView* a, RegionView* b) {
+ return a->region()->position() < b->region()->position();
+ }
+};
+
+bool
+MidiStreamView::paste (ARDOUR::framepos_t pos, const Selection& selection, PasteContext& ctx, const int32_t sub_num)
{
- StreamView::leave_internal_edit_mode ();
- for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*i);
- if (mrv) {
- mrv->clear_selection ();
+ /* Paste into the first region which starts on or before pos. Only called when
+ using an internal editing tool. */
+
+ if (region_views.empty()) {
+ return false;
+ }
+
+ region_views.sort (RegionView::PositionOrder());
+
+ list<RegionView*>::const_iterator prev = region_views.begin ();
+
+ for (list<RegionView*>::const_iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ if ((*i)->region()->position() > pos) {
+ break;
}
+ prev = i;
}
+
+ boost::shared_ptr<Region> r = (*prev)->region ();
+
+ /* If *prev doesn't cover pos, it's no good */
+ if (r->position() > pos || ((r->position() + r->length()) < pos)) {
+ return false;
+ }
+
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*prev);
+ return mrv ? mrv->paste(pos, selection, ctx, sub_num) : false;
}