the continuing co-evolution of Editor,EditingContext & MidiCueEditor

This commit is contained in:
Paul Davis 2024-02-04 21:21:00 -07:00
parent e2e660b4cd
commit e6b6152f5a
13 changed files with 163 additions and 144 deletions

View File

@ -190,22 +190,6 @@ CueEditor::step_mouse_mode (bool next)
}
void
CueEditor::set_canvas_cursor (Gdk::Cursor*)
{
}
size_t
CueEditor::push_canvas_cursor (Gdk::Cursor*)
{
return 0;
}
void
CueEditor::pop_canvas_cursor ()
{
}
void
CueEditor::reset_x_origin_to_follow_playhead ()
{

View File

@ -98,9 +98,6 @@ class CueEditor : public EditingContext
void end_local_tempo_map (std::shared_ptr<Temporal::TempoMap const>);
protected:
void set_canvas_cursor (Gdk::Cursor*);
size_t push_canvas_cursor (Gdk::Cursor*);
void pop_canvas_cursor ();
void reset_x_origin_to_follow_playhead ();
};

View File

@ -24,7 +24,8 @@
CursorContext::CursorContext(EditingContext& ec, Gdk::Cursor* cursor)
: editing_context(ec)
, _index (editing_context.push_canvas_cursor(cursor))
{}
{
}
CursorContext::~CursorContext()
{

View File

@ -61,6 +61,7 @@ Gtkmm2ext::Bindings* EditingContext::button_bindings = nullptr;
Glib::RefPtr<Gtk::ActionGroup> EditingContext::_midi_actions;
std::queue<EditingContext*> EditingContext::ec_stack;
std::vector<std::string> EditingContext::grid_type_strings;
MouseCursors* EditingContext::_cursors = nullptr;
static const gchar *_grid_type_strings[] = {
N_("No Grid"),
@ -106,7 +107,6 @@ EditingContext::EditingContext ()
, selection (new Selection (this, true))
, cut_buffer (new Selection (this, false))
, _selection_memento (new SelectionMemento())
, _cursors (nullptr)
, _verbose_cursor (nullptr)
, samples_per_pixel (2048)
, zoom_focus (ZoomFocusPlayhead)
@ -116,6 +116,8 @@ EditingContext::EditingContext ()
, _visible_canvas_width (0)
, _visible_canvas_height (0)
, quantize_dialog (nullptr)
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
{
if (!button_bindings) {
button_bindings = new Bindings ("editor-mouse");
@ -131,6 +133,12 @@ EditingContext::EditingContext ()
if (grid_type_strings.empty()) {
grid_type_strings = I18N (_grid_type_strings);
}
if (!_cursors) {
_cursors = new MouseCursors;
_cursors->set_cursor_set (UIConfiguration::instance().get_icon_set());
std::cerr << "Set cursor set to " << UIConfiguration::instance().get_icon_set() << std::endl;
}
}
EditingContext::~EditingContext()
@ -1978,3 +1986,74 @@ EditingContext::pop_editing_context ()
{
ec_stack.pop ();
}
double
EditingContext::horizontal_position () const
{
return sample_to_pixel (_leftmost_sample);
}
void
EditingContext::set_horizontal_position (double p)
{
p = std::max (0., p);
std::cerr << "new hp: " << p << std::endl;
horizontal_adjustment.set_value (p);
_leftmost_sample = (samplepos_t) floor (p * samples_per_pixel);
}
Gdk::Cursor*
EditingContext::get_canvas_cursor () const
{
/* The top of the cursor stack is always the currently visible cursor. */
return _cursor_stack.back();
}
void
EditingContext::set_canvas_cursor (Gdk::Cursor* cursor)
{
Glib::RefPtr<Gdk::Window> win = get_canvas_viewport()->get_window();
if (win && !_cursors->is_invalid (cursor)) {
/* glibmm 2.4 doesn't allow null cursor pointer because it uses
a Gdk::Cursor& as the argument to Gdk::Window::set_cursor().
But a null pointer just means "use parent window cursor",
and so should be allowed. Gtkmm 3.x has fixed this API.
For now, drop down and use C API
*/
gdk_window_set_cursor (win->gobj(), cursor ? cursor->gobj() : 0);
}
}
size_t
EditingContext::push_canvas_cursor (Gdk::Cursor* cursor)
{
if (!_cursors->is_invalid (cursor)) {
_cursor_stack.push_back (cursor);
set_canvas_cursor (cursor);
}
return _cursor_stack.size() - 1;
}
void
EditingContext::pop_canvas_cursor ()
{
while (true) {
if (_cursor_stack.size() <= 1) {
PBD::error << "attempt to pop default cursor" << endmsg;
return;
}
_cursor_stack.pop_back();
if (_cursor_stack.back()) {
/* Popped to an existing cursor, we're done. Otherwise, the
context that created this cursor has been destroyed, so we need
to skip to the next down the stack. */
set_canvas_cursor (_cursor_stack.back());
return;
}
}
}

View File

@ -295,8 +295,8 @@ public:
/** @return Whether the current mouse mode is an "internal" editing mode. */
virtual bool internal_editing() const = 0;
virtual Gdk::Cursor* get_canvas_cursor () const = 0;
virtual MouseCursors const* cursors () const {
virtual Gdk::Cursor* get_canvas_cursor () const;
static MouseCursors const* cursors () {
return _cursors;
}
virtual VerboseCursor* verbose_cursor () const {
@ -333,15 +333,23 @@ public:
bool typed_event (ArdourCanvas::Item*, GdkEvent*, ItemType);
void set_horizontal_position (double);
double horizontal_position () const;
virtual samplecnt_t current_page_samples() const = 0;
virtual ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const = 0;
virtual ArdourCanvas::Canvas* get_canvas() const = 0;
protected:
static Glib::RefPtr<Gtk::ActionGroup> _midi_actions;
/* Cursor stuff. Do not use directly, use via CursorContext. */
friend class CursorContext;
std::vector<Gdk::Cursor*> _cursor_stack;
virtual void set_canvas_cursor (Gdk::Cursor*) = 0;
virtual size_t push_canvas_cursor (Gdk::Cursor*) = 0;
virtual void pop_canvas_cursor () = 0;
virtual void set_canvas_cursor (Gdk::Cursor*);
virtual size_t push_canvas_cursor (Gdk::Cursor*);
virtual void pop_canvas_cursor ();
Editing::GridType pre_internal_grid_type;
Editing::SnapMode pre_internal_snap_mode;
@ -397,7 +405,6 @@ public:
virtual void mark_region_boundary_cache_dirty () {}
virtual void update_tempo_based_rulers () {};
virtual void show_rulers_for_grid () {};
virtual samplecnt_t current_page_samples() const = 0;
samplepos_t _leftmost_sample;
@ -417,7 +424,7 @@ public:
std::list<XMLNode*> before; /* used in *_reversible_command */
MouseCursors* _cursors;
static MouseCursors* _cursors;
VerboseCursor* _verbose_cursor;
@ -505,8 +512,14 @@ public:
static void push_editing_context (EditingContext*);
static void pop_editing_context ();
/** the adjustment that controls the overall editing vertical scroll position */
friend class EditorSummary;
Gtk::Adjustment vertical_adjustment;
Gtk::Adjustment horizontal_adjustment;
private:
static std::queue<EditingContext*> ec_stack;
};

View File

@ -312,8 +312,6 @@ Editor::Editor ()
, videotl_group (0)
, _region_boundary_cache_dirty (true)
, edit_packer (4, 4, true)
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
, unused_adjustment (0.0, 0.0, 10.0, 400.0)
, controls_layout (unused_adjustment, vertical_adjustment)
, _scroll_callbacks (0)
@ -578,10 +576,6 @@ Editor::Editor ()
controls_layout.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::edit_controls_button_event));
controls_layout.signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false);
_cursors = new MouseCursors;
_cursors->set_cursor_set (UIConfiguration::instance().get_icon_set());
cerr << "Set cursor set to " << UIConfiguration::instance().get_icon_set() << endl;
/* Push default cursor to ever-present bottom of cursor stack. */
push_canvas_cursor(_cursors->grabber);
@ -4316,9 +4310,8 @@ Editor::on_samples_per_pixel_changed ()
ZoomChanged (); /* EMIT_SIGNAL */
ArdourCanvas::GtkCanvasViewport* c;
ArdourCanvas::GtkCanvasViewport* c = get_canvas_viewport ();
c = get_track_canvas();
if (c) {
c->canvas()->zoomed ();
}

View File

@ -456,8 +456,6 @@ public:
void set_current_trimmable (std::shared_ptr<ARDOUR::Trimmable>);
void set_current_movable (std::shared_ptr<ARDOUR::Movable>);
Gdk::Cursor* get_canvas_cursor () const;
double clamp_verbose_cursor_x (double);
double clamp_verbose_cursor_y (double);
@ -485,7 +483,8 @@ public:
ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; }
ArdourCanvas::Container* get_drag_motion_group () const { return _drag_motion_group; }
ArdourCanvas::GtkCanvasViewport* get_track_canvas () const;
ArdourCanvas::GtkCanvasViewport* get_canvas_viewport () const;
ArdourCanvas::Canvas* get_canvas () const;
void override_visible_track_count ();
@ -785,10 +784,6 @@ private:
Gtk::HBox global_hpacker;
Gtk::VBox global_vpacker;
void set_canvas_cursor (Gdk::Cursor* cursor);
size_t push_canvas_cursor (Gdk::Cursor*);
void pop_canvas_cursor ();
Gdk::Cursor* which_track_cursor () const;
Gdk::Cursor* which_mode_cursor () const;
Gdk::Cursor* which_trim_cursor (bool left_side) const;
@ -1025,10 +1020,6 @@ private:
Gtk::Table edit_packer;
/** the adjustment that controls the overall editor vertical scroll position */
Gtk::Adjustment vertical_adjustment;
Gtk::Adjustment horizontal_adjustment;
Gtk::Adjustment unused_adjustment; // yes, really; Gtk::Layout constructor requires refs
Gtk::Layout controls_layout;
bool control_layout_scroll (GdkEventScroll* ev);
@ -1075,8 +1066,6 @@ private:
sigc::connection control_scroll_connection;
void tie_vertical_scrolling ();
void set_horizontal_position (double);
double horizontal_position () const;
struct VisualChange {
enum Type {

View File

@ -1034,14 +1034,6 @@ Editor::tie_vertical_scrolling ()
}
}
void
Editor::set_horizontal_position (double p)
{
horizontal_adjustment.set_value (p);
_leftmost_sample = (samplepos_t) floor (p * samples_per_pixel);
}
void
Editor::color_handler()
{
@ -1122,10 +1114,16 @@ Editor::color_handler()
*/
}
double
Editor::horizontal_position () const
ArdourCanvas::GtkCanvasViewport*
Editor::get_canvas_viewport() const
{
return sample_to_pixel (_leftmost_sample);
return _track_canvas_viewport;
}
ArdourCanvas::Canvas*
Editor::get_canvas() const
{
return _track_canvas_viewport->canvas();
}
bool
@ -1159,66 +1157,6 @@ Editor::clamp_verbose_cursor_y (double y)
return y;
}
ArdourCanvas::GtkCanvasViewport*
Editor::get_track_canvas() const
{
return _track_canvas_viewport;
}
Gdk::Cursor*
Editor::get_canvas_cursor () const
{
/* The top of the cursor stack is always the currently visible cursor. */
return _cursor_stack.back();
}
void
Editor::set_canvas_cursor (Gdk::Cursor* cursor)
{
Glib::RefPtr<Gdk::Window> win = _track_canvas->get_window();
if (win && !_cursors->is_invalid (cursor)) {
/* glibmm 2.4 doesn't allow null cursor pointer because it uses
a Gdk::Cursor& as the argument to Gdk::Window::set_cursor().
But a null pointer just means "use parent window cursor",
and so should be allowed. Gtkmm 3.x has fixed this API.
For now, drop down and use C API
*/
gdk_window_set_cursor (win->gobj(), cursor ? cursor->gobj() : 0);
}
}
size_t
Editor::push_canvas_cursor (Gdk::Cursor* cursor)
{
if (!_cursors->is_invalid (cursor)) {
_cursor_stack.push_back (cursor);
set_canvas_cursor (cursor);
}
return _cursor_stack.size() - 1;
}
void
Editor::pop_canvas_cursor ()
{
while (true) {
if (_cursor_stack.size() <= 1) {
PBD::error << "attempt to pop default cursor" << endmsg;
return;
}
_cursor_stack.pop_back();
if (_cursor_stack.back()) {
/* Popped to an existing cursor, we're done. Otherwise, the
context that created this cursor has been destroyed, so we need
to skip to the next down the stack. */
set_canvas_cursor (_cursor_stack.back());
return;
}
}
}
Gdk::Cursor*
Editor::which_trim_cursor (bool left) const
{

View File

@ -7075,7 +7075,7 @@ RegionCutDrag::motion (GdkEvent* event, bool)
void
RegionCutDrag::finished (GdkEvent* event, bool)
{
_editor.get_track_canvas ()->canvas ()->re_enter ();
_editor.get_canvas()->re_enter ();
timepos_t pos (_drags->current_pointer_time ());
editing_context.snap_to_with_modifier (pos, event);

View File

@ -52,7 +52,7 @@ MidiCueEditor::MidiCueEditor()
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
, view (nullptr)
, mouse_mode (Editing::MouseDraw)
, mouse_mode (Editing::MouseContent)
, bbt_metric (*this)
{
build_canvas ();
@ -70,6 +70,29 @@ MidiCueEditor::~MidiCueEditor ()
{
}
ArdourCanvas::GtkCanvasViewport*
MidiCueEditor::get_canvas_viewport() const
{
return _canvas_viewport;
}
ArdourCanvas::Canvas*
MidiCueEditor::get_canvas() const
{
return _canvas;
}
bool
MidiCueEditor::canvas_event (GdkEvent* ev)
{
if (view) {
return view->canvas_event (ev);
}
return false;
}
void
MidiCueEditor::build_canvas ()
{
@ -77,6 +100,7 @@ MidiCueEditor::build_canvas ()
_canvas = _canvas_viewport->canvas ();
_canvas->set_background_color (UIConfiguration::instance().color ("arrange base"));
_canvas->signal_event().connect (sigc::mem_fun (*this, &MidiCueEditor::canvas_event));
dynamic_cast<ArdourCanvas::GtkCanvas*>(_canvas)->use_nsglview (UIConfiguration::instance().get_nsgl_view_mode () == NSGLHiRes);
/* scroll group for items that should not automatically scroll
@ -84,23 +108,19 @@ MidiCueEditor::build_canvas ()
*/
no_scroll_group = new ArdourCanvas::Container (_canvas->root());
ArdourCanvas::ScrollGroup* hsg;
ArdourCanvas::ScrollGroup* hg;
ArdourCanvas::ScrollGroup* cg;
h_scroll_group = hg = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally);
h_scroll_group = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally);
CANVAS_DEBUG_NAME (h_scroll_group, "canvas h scroll");
_canvas->add_scroller (*hg);
_canvas->add_scroller (*h_scroll_group);
hv_scroll_group = hsg = new ArdourCanvas::ScrollGroup (_canvas->root(),
hv_scroll_group = new ArdourCanvas::ScrollGroup (_canvas->root(),
ArdourCanvas::ScrollGroup::ScrollSensitivity (ArdourCanvas::ScrollGroup::ScrollsVertically|
ArdourCanvas::ScrollGroup::ScrollsHorizontally));
CANVAS_DEBUG_NAME (hv_scroll_group, "cue canvas hv scroll");
_canvas->add_scroller (*hsg);
_canvas->add_scroller (*hv_scroll_group);
cursor_scroll_group = cg = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally);
cursor_scroll_group = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally);
CANVAS_DEBUG_NAME (cursor_scroll_group, "cue canvas cursor scroll");
_canvas->add_scroller (*cg);
_canvas->add_scroller (*cursor_scroll_group);
/*a group to hold global rects like punch/loop indicators */
global_rect_group = new ArdourCanvas::Container (hv_scroll_group);
@ -187,12 +207,6 @@ MidiCueEditor::canvas_allocate (Gtk::Allocation alloc)
_visible_canvas_height = alloc.get_height();
bg->set_size (alloc.get_width(), alloc.get_height());
std::cerr << "bg is " << bg->width() << std::endl;
if (view) {
ArdourCanvas::Rect r (0., timebar_height * n_timebars, ArdourCanvas::COORD_MAX, alloc.get_height() - (timebar_height * n_timebars));
view->set_size (r);
}
}
timepos_t

View File

@ -79,6 +79,9 @@ class MidiCueEditor : public CueEditor
double timebar_height;
size_t n_timebars;
ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const;
ArdourCanvas::Canvas* get_canvas() const;
protected:
Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start,
Temporal::RoundMode direction,
@ -157,6 +160,8 @@ class MidiCueEditor : public CueEditor
};
BBTMetric bbt_metric;
bool canvas_event (GdkEvent*);
};

View File

@ -555,6 +555,8 @@ MidiView::motion (GdkEventMotion* ev)
bool
MidiView::scroll (GdkEventScroll* ev)
{
std::cerr << "scroll\n";
if (_editing_context.drags()->active()) {
return false;
}
@ -598,11 +600,17 @@ MidiView::scroll (GdkEventScroll* ev)
set_note_range (min (127, _midi_context.lowest_note() - step), max (0, _midi_context.highest_note() - step));
}
return true;
case GDK_SCROLL_LEFT:
break;
case GDK_SCROLL_RIGHT:
case GDK_SCROLL_LEFT:
std::cerr << "left minus\n";
_editing_context.set_horizontal_position (_editing_context.horizontal_position() - 20.0);
break;
case GDK_SCROLL_RIGHT:
std::cerr << "right plus\n";
_editing_context.set_horizontal_position (_editing_context.horizontal_position() + 20.0);
break;
default:
break;
}

View File

@ -402,8 +402,6 @@ public:
virtual ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const = 0;
virtual ArdourCanvas::Container* get_drag_motion_group () const = 0;
virtual ArdourCanvas::GtkCanvasViewport* get_track_canvas() const = 0;
virtual void set_current_trimmable (std::shared_ptr<ARDOUR::Trimmable>) = 0;
virtual void set_current_movable (std::shared_ptr<ARDOUR::Movable>) = 0;