diff --git a/gtk2_ardour/automation_streamview.cc b/gtk2_ardour/automation_streamview.cc index 1565af2a56..dd50d1e894 100644 --- a/gtk2_ardour/automation_streamview.cc +++ b/gtk2_ardour/automation_streamview.cc @@ -44,7 +44,6 @@ #include "rgb_macros.h" #include "selection.h" #include "ui_config.h" -#include "velocity_region_view.h" #include "pbd/i18n.h" @@ -95,51 +94,28 @@ AutomationStreamView::add_region_view_internal (std::shared_ptr region, RegionView *region_view; - if (_automation_view.parameter().type() == MidiVelocityAutomation) { + for (auto const & rv : region_views) { + if (rv->region() == region) { - for (auto const & rv : region_views) { - if (rv->region() == region) { + /* great. we already have an AutomationRegionView for this Region. use it again. */ + AutomationRegionView* arv = dynamic_cast(rv);; - /* great. we already have an AutomationRegionView for this Region. use it again. */ - VelocityRegionView* vrv = dynamic_cast(rv); - - if (vrv->line()) { - vrv->line()->set_list (list); - } - rv->set_valid (true); - display_region (vrv); - - return 0; + if (arv->line()) { + arv->line()->set_list (list); } + rv->set_valid (true); + display_region (arv); + + return 0; } - - region_view = new VelocityRegionView (_canvas_group, _automation_view, region, list, _samples_per_pixel, region_color); - - } else { - - for (auto const & rv : region_views) { - if (rv->region() == region) { - - /* great. we already have an AutomationRegionView for this Region. use it again. */ - AutomationRegionView* arv = dynamic_cast(rv);; - - if (arv->line()) { - arv->line()->set_list (list); - } - rv->set_valid (true); - display_region (arv); - - return 0; - } - } - - region_view = new AutomationRegionView ( - _canvas_group, _automation_view, region, - _automation_view.parameter (), list, - _samples_per_pixel, region_color - ); } + region_view = new AutomationRegionView ( + _canvas_group, _automation_view, region, + _automation_view.parameter (), list, + _samples_per_pixel, region_color + ); + region_view->init (false); region_views.push_front (region_view); diff --git a/gtk2_ardour/ghostregion.h b/gtk2_ardour/ghostregion.h index 8e771b9b04..4046e37ab1 100644 --- a/gtk2_ardour/ghostregion.h +++ b/gtk2_ardour/ghostregion.h @@ -27,12 +27,22 @@ #include #include + #include "pbd/signals.h" +#include "gtkmm2ext/colors.h" + namespace ArdourWaveView { class WaveView; } +namespace ArdourCanvas { + class Container; + class Rectangle; + class Item; + class Polygon; +} + class NoteBase; class Note; class Hit; @@ -111,10 +121,10 @@ public: void update_contents_height(); - void add_note(NoteBase*); - void update_note (GhostEvent* note); - void update_hit (GhostEvent* hit); - void remove_note (NoteBase*); + virtual void add_note(NoteBase*); + virtual void update_note (GhostEvent* note); + virtual void update_hit (GhostEvent* hit); + virtual void remove_note (NoteBase*); void model_changed(); void view_changed(); diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 0be7a0ed2e..52d84fde62 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -83,6 +83,7 @@ #include "selection.h" #include "streamview.h" #include "patch_change_dialog.h" +#include "velocity_ghost_region.h" #include "verbose_cursor.h" #include "note.h" #include "hit.h" @@ -1627,7 +1628,12 @@ MidiRegionView::add_ghost (TimeAxisView& tv) if (mtv && mtv->midi_view()) { return 0; } else { - ghost = new MidiGhostRegion (*this, tv, trackview, unit_position); + AutomationTimeAxisView* atv = dynamic_cast(&tv); + if (atv && atv->parameter() == Evoral::Parameter (MidiVelocityAutomation)) { + ghost = new VelocityGhostRegion (*this, tv, trackview, unit_position); + } else { + ghost = new MidiGhostRegion (*this, tv, trackview, unit_position); + } } ghost->set_colors (); diff --git a/gtk2_ardour/note_base.h b/gtk2_ardour/note_base.h index e86cdd141f..c1083443af 100644 --- a/gtk2_ardour/note_base.h +++ b/gtk2_ardour/note_base.h @@ -43,7 +43,8 @@ namespace ArdourCanvas { class Text; } -/** Base class for canvas notes (sustained note rectangles and hit diamonds). +/** Base class for canvas notes (sustained note rectangles, percussive hit diamonds, + * and velocity lollipops) * * This is not actually a canvas item itself to avoid the dreaded diamond * inheritance pattern, since various types of canvas items (Note (rect), Hit diff --git a/gtk2_ardour/velocity_ghost_region.cc b/gtk2_ardour/velocity_ghost_region.cc new file mode 100644 index 0000000000..4f53bfd4a6 --- /dev/null +++ b/gtk2_ardour/velocity_ghost_region.cc @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2022 Paul Davis + * + * 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 + +#include "pbd/memento_command.h" + +#include "ardour/automation_control.h" +#include "ardour/event_type_map.h" +#include "ardour/midi_automation_list_binder.h" +#include "ardour/midi_region.h" +#include "ardour/midi_track.h" +#include "ardour/session.h" + +#include "gtkmm2ext/keyboard.h" + +#include "velocity_ghost_region.h" +#include "editing.h" +#include "editor.h" +#include "editor_drag.h" +#include "gui_thread.h" +#include "midi_automation_line.h" +#include "public_editor.h" +#include "ui_config.h" + +#include "pbd/i18n.h" + +using namespace Temporal; + +VelocityGhostRegion::VelocityGhostRegion (MidiRegionView& mrv, TimeAxisView& tv, TimeAxisView& source_tv, double initial_unit_pos) + : MidiGhostRegion (mrv, tv, source_tv, initial_unit_pos) +{ +} + +VelocityGhostRegion::~VelocityGhostRegion () +{ +} + +void +VelocityGhostRegion::add_note(NoteBase*) +{ +} + +void +VelocityGhostRegion::update_note (GhostEvent* note) +{ +} + +void +VelocityGhostRegion::update_hit (GhostEvent* hit) +{ +} + +void +VelocityGhostRegion::remove_note (NoteBase*) +{ +} + + diff --git a/gtk2_ardour/velocity_ghost_region.h b/gtk2_ardour/velocity_ghost_region.h new file mode 100644 index 0000000000..442a9cc827 --- /dev/null +++ b/gtk2_ardour/velocity_ghost_region.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007-2014 David Robillard + * Copyright (C) 2009-2010 Carl Hetherington + * Copyright (C) 2009-2017 Paul Davis + * + * 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_velocity_region_view_h__ +#define __gtk_ardour_velocity_region_view_h__ + +#include "ghostregion.h" + +class VelocityGhostRegion : public MidiGhostRegion +{ +public: + VelocityGhostRegion (MidiRegionView&, TimeAxisView& tv, TimeAxisView& source_tv, double initial_unit_pos); + ~VelocityGhostRegion (); + + void add_note(NoteBase*); + void update_note (GhostEvent* note); + void update_hit (GhostEvent* hit); + void remove_note (NoteBase*); + +private: +}; + +#endif /* __gtk_ardour_velocity_region_view_h__ */ diff --git a/gtk2_ardour/velocity_region_view.cc b/gtk2_ardour/velocity_region_view.cc deleted file mode 100644 index afe14ea60f..0000000000 --- a/gtk2_ardour/velocity_region_view.cc +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2022 Paul Davis - * - * 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 - -#include "pbd/memento_command.h" - -#include "ardour/automation_control.h" -#include "ardour/event_type_map.h" -#include "ardour/midi_automation_list_binder.h" -#include "ardour/midi_region.h" -#include "ardour/midi_track.h" -#include "ardour/session.h" - -#include "gtkmm2ext/keyboard.h" - -#include "velocity_region_view.h" -#include "editing.h" -#include "editor.h" -#include "editor_drag.h" -#include "gui_thread.h" -#include "midi_automation_line.h" -#include "public_editor.h" -#include "ui_config.h" - -#include "pbd/i18n.h" - -using namespace Temporal; - -VelocityRegionView::VelocityRegionView (ArdourCanvas::Container* parent, - AutomationTimeAxisView& time_axis, - boost::shared_ptr region, - boost::shared_ptr list, - double spu, - uint32_t basic_color) - : RegionView(parent, time_axis, region, spu, basic_color, true) - , _parameter(ARDOUR::MidiVelocityAutomation) -{ - TimeAxisViewItem::set_position (_region->position(), this); - - if (list) { - assert(list->parameter().type() == ARDOUR::MidiVelocityAutomation); - create_line(list); - } - - group->raise_to_top(); - - trackview.editor().MouseModeChanged.connect(_mouse_mode_connection, invalidator (*this), - boost::bind (&VelocityRegionView::mouse_mode_changed, this), - gui_context ()); -} - -VelocityRegionView::~VelocityRegionView () -{ - in_destructor = true; - RegionViewGoingAway (this); /* EMIT_SIGNAL */ -} - -void -VelocityRegionView::init (bool /*wfd*/) -{ - DisplaySuspender (*this); - - RegionView::init (false); - - reset_width_dependent_items ((double) _region->length_samples() / samples_per_pixel); - - set_height (trackview.current_height()); - - set_colors (); -} - -void -VelocityRegionView::create_line (boost::shared_ptr list) -{ - _line = boost::shared_ptr (new MidiAutomationLine( - ARDOUR::EventTypeMap::instance().to_symbol(list->parameter()), - trackview, *get_canvas_group(), list, - boost::dynamic_pointer_cast (_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 ()); -} - -uint32_t -VelocityRegionView::get_fill_color() const -{ - const std::string mod_name = (_dragging ? "dragging region" : - trackview.editor().internal_editing() ? "editable region" : fill_color_name); - if (_selected) { - return UIConfiguration::instance().color_mod ("selected region base", mod_name); - } else if (high_enough_for_name || !UIConfiguration::instance().get_color_regions_using_track_color()) { - return UIConfiguration::instance().color_mod (fill_color_name, mod_name); - } - return UIConfiguration::instance().color_mod (fill_color, mod_name); -} - -void -VelocityRegionView::mouse_mode_changed () -{ - /* Adjust frame colour (become more transparent for internal tools) */ - set_frame_color(); -} - -bool -VelocityRegionView::canvas_group_event (GdkEvent* ev) -{ - if (in_destructor) { - return false; - } - - PublicEditor& e = trackview.editor (); - - if (!trackview.editor().internal_editing()) { - return false; - } - - return RegionView::canvas_group_event (ev); -} - -bool -VelocityRegionView::paste (timepos_t const & pos, - unsigned paste_count, - float times, - boost::shared_ptr slist) -{ - using namespace ARDOUR; - - AutomationTimeAxisView* const view = velocity_view(); - boost::shared_ptr my_list = _line->the_list(); - - if (view->session()->transport_rolling() && my_list->automation_write()) { - /* do not paste if this control is in write mode and we're rolling */ - return false; - } - - timecnt_t len = slist->length(); - timepos_t p (pos); - - /* add multi-paste offset if applicable */ - p += view->editor ().get_paste_offset (pos, paste_count > 0 ? 1 : 0, len); - - timepos_t model_pos = pos; - - /* potentially snap */ - - view->editor().snap_to (model_pos, Temporal::RoundNearest); - - /* convert timeline position to model's (source-relative) position */ - - model_pos = timepos_t (_region->source_position().distance (model_pos)); - - XMLNode& before = my_list->get_state(); - my_list->paste (*slist, model_pos); - view->session()->add_command(new MementoCommand(_line->memento_command_binder(), &before, &my_list->get_state())); - - return true; -} - -void -VelocityRegionView::set_height (double h) -{ - RegionView::set_height(h); - - if (_line) { - _line->set_height ((uint32_t)rint(h - 2.5 - NAME_HIGHLIGHT_SIZE)); - } -} - -bool -VelocityRegionView::set_position (timepos_t const & pos, void* src, double* ignored) -{ - if (_line) { - _line->set_maximum_time (timepos_t (_region->length ())); - } - - return RegionView::set_position(pos, src, ignored); -} - - -void -VelocityRegionView::reset_width_dependent_items (double pixel_width) -{ - RegionView::reset_width_dependent_items(pixel_width); - - if (_line) { - _line->reset (); - } -} - -void -VelocityRegionView::region_resized (const PBD::PropertyChange& what_changed) -{ - RegionView::region_resized (what_changed); - - if (!_line) { - return; - } - - if (what_changed.contains (ARDOUR::Properties::start)) { - _line->set_offset (_region->start ()); - } - - if (what_changed.contains (ARDOUR::Properties::length)) { - _line->set_maximum_time (timepos_t (_region->length())); - } -} - -void -VelocityRegionView::tempo_map_changed () -{ - if (_line) { - _line->tempo_map_changed (); - } - - set_position (_region->position(), 0, 0); - set_duration (_region->length(), 0); -} - -void -VelocityRegionView::entered () -{ - if (_line) { - _line->track_entered(); - } -} - - -void -VelocityRegionView::exited () -{ - if (_line) { - _line->track_exited(); - } -} diff --git a/gtk2_ardour/velocity_region_view.h b/gtk2_ardour/velocity_region_view.h deleted file mode 100644 index 1994fcc3f3..0000000000 --- a/gtk2_ardour/velocity_region_view.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2007-2014 David Robillard - * Copyright (C) 2009-2010 Carl Hetherington - * Copyright (C) 2009-2017 Paul Davis - * - * 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_velocity_region_view_h__ -#define __gtk_ardour_velocity_region_view_h__ - -#include "ardour/types.h" - -#include "region_view.h" -#include "automation_time_axis.h" -#include "automation_line.h" -#include "enums.h" - -namespace ARDOUR { - class AutomationList; - class Parameter; -}; - -class TimeAxisView; - -class VelocityRegionView : public RegionView -{ -public: - VelocityRegionView(ArdourCanvas::Container*, - AutomationTimeAxisView&, - boost::shared_ptr, - boost::shared_ptr, - double initial_samples_per_pixel, - uint32_t basic_color); - - ~VelocityRegionView(); - - void init (bool wfd); - - bool paste (Temporal::timepos_t const & pos, - unsigned paste_count, - float times, - boost::shared_ptr slist); - - inline AutomationTimeAxisView* velocity_view() const - { return dynamic_cast(&trackview); } - - boost::shared_ptr line() { return _line; } - - // We are a ghost. Meta ghosts? Crazy talk. - virtual GhostRegion* add_ghost(TimeAxisView&) { return 0; } - - uint32_t get_fill_color() const; - - void set_height (double); - void reset_width_dependent_items(double pixel_width); - - void tempo_map_changed (); - -protected: - void create_line(boost::shared_ptr list); - bool set_position(Temporal::timepos_t const & pos, void* src, double* ignored); - void region_resized (const PBD::PropertyChange&); - bool canvas_group_event(GdkEvent* ev); - void mouse_mode_changed (); - void entered(); - void exited(); - void _redisplay (bool) {} - -private: - Evoral::Parameter _parameter; - boost::shared_ptr _line; - PBD::ScopedConnection _mouse_mode_connection; -}; - -#endif /* __gtk_ardour_velocity_region_view_h__ */ diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 38a787ce20..1055c37eaf 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -342,7 +342,7 @@ gtk2_ardour_sources = [ 'video_monitor.cc', 'transcode_ffmpeg.cc', 'transcode_video_dialog.cc', - 'velocity_region_view.cc', + 'velocity_ghost_region.cc', 'video_server_dialog.cc', 'utils_videotl.cc', 'export_video_dialog.cc'