remove all trace of cursor stacks; canvas cursor is always "just set"

This commit is contained in:
Paul Davis 2024-12-08 12:13:41 -07:00
parent 5b112e489b
commit 98c9c03e9f
22 changed files with 55 additions and 306 deletions

View file

@ -459,10 +459,6 @@
RelativePath="..\gtk2_ardour\control_slave_ui.cc" RelativePath="..\gtk2_ardour\control_slave_ui.cc"
> >
</File> </File>
<File
RelativePath="..\gtk2_ardour\cursor_context.cc"
>
</File>
<File <File
RelativePath="..\gtk2_ardour\curvetest.cc" RelativePath="..\gtk2_ardour\curvetest.cc"
> >
@ -1641,10 +1637,6 @@
RelativePath="..\gtk2_ardour\crossfade_edit.h" RelativePath="..\gtk2_ardour\crossfade_edit.h"
> >
</File> </File>
<File
RelativePath="..\gtk2_ardour\cursor_context.h"
>
</File>
<File <File
RelativePath="..\gtk2_ardour\debug.h" RelativePath="..\gtk2_ardour\debug.h"
> >

View file

@ -106,12 +106,6 @@ CueEditor::instant_save()
{ {
} }
EditingContext::EnterContext*
CueEditor::get_enter_context(ItemType type)
{
return nullptr;
}
void void
CueEditor::begin_selection_op_history () CueEditor::begin_selection_op_history ()
{ {

View file

@ -51,13 +51,6 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner, public sigc::
void instant_save(); void instant_save();
/** Get the topmost enter context for the given item type.
*
* This is used to change the cursor associated with a given enter context,
* which may not be on the top of the stack.
*/
EnterContext* get_enter_context(ItemType type);
void begin_selection_op_history (); void begin_selection_op_history ();
void begin_reversible_selection_op (std::string cmd_name); void begin_reversible_selection_op (std::string cmd_name);
void commit_reversible_selection_op (); void commit_reversible_selection_op ();

View file

@ -1,62 +0,0 @@
/*
* Copyright (C) 2014 David Robillard <d@drobilla.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.
*/
#include <pbd/error.h>
#include "editing_context.h"
#include "cursor_context.h"
CursorContext::CursorContext(EditingContext& ec, Gdk::Cursor* cursor)
: editing_context(ec)
, _index (editing_context.push_canvas_cursor(cursor))
{
}
CursorContext::~CursorContext()
{
if (_index == editing_context._cursor_stack.size() - 1) {
editing_context.pop_canvas_cursor();
} else {
editing_context._cursor_stack[_index] = NULL;
}
}
CursorContext::Handle
CursorContext::create(EditingContext& ec, Gdk::Cursor* cursor)
{
return CursorContext::Handle(new CursorContext(ec, cursor));
}
void
CursorContext::change(Gdk::Cursor* cursor)
{
editing_context._cursor_stack[_index] = cursor;
if (_index == editing_context._cursor_stack.size() - 1) {
editing_context.set_canvas_cursor(cursor);
}
}
void
CursorContext::set(Handle* handle, EditingContext& ec, Gdk::Cursor* cursor)
{
if (*handle) {
(*handle)->change(cursor);
} else {
*handle = CursorContext::create(ec, cursor);
}
}

View file

@ -1,73 +0,0 @@
/*
* Copyright (C) 2014 David Robillard <d@drobilla.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.
*/
#pragma once
#include <memory>
#include <gdkmm/cursor.h>
class EditingContext;
/**
A scoped handle for changing the editor mouse cursor.
This is a safe way to change the cursor that ensures it is only modified in
a strict stack-like fashion. Whenever this handle goes out of scope, the
cursor is restored to the previous one.
This is not quite entirely fool-proof, there is one case to be careful of:
if a cursor context handle exists, to change it, you must first reset that
handle (destroying the context) then set it. Assigning a new context to a
non-NULL handle will create the new context (pushing a cursor), then destroy
the old one, which would attempt to pop a non-top context which is an
error. To account for this, when replacing a possibly existing context, use
set() which will automatically do the right thing.
*/
class CursorContext
{
public:
/** A smart handle for a cursor change context. */
typedef std::shared_ptr<CursorContext> Handle;
~CursorContext();
/** Change the editor cursor and return a cursor context handle.
*
* When the returned handle goes out of scope, the cursor will be reset to
* the previous value.
*/
static Handle create(EditingContext&, Gdk::Cursor* cursor);
/** Change the editor cursor of an existing cursor context. */
void change(Gdk::Cursor* cursor);
/** Set a context handle to a new context.
*
* If the handle points to an existing context, it will first be reset
* before the new context is created.
*/
static void set(Handle* handle, EditingContext&, Gdk::Cursor* cursor);
private:
EditingContext& editing_context;
size_t _index;
CursorContext(EditingContext&, Gdk::Cursor* cursor);
};

View file

@ -2065,8 +2065,13 @@ EditingContext::set_horizontal_position (double p)
Gdk::Cursor* Gdk::Cursor*
EditingContext::get_canvas_cursor () const EditingContext::get_canvas_cursor () const
{ {
/* The top of the cursor stack is always the currently visible cursor. */ Glib::RefPtr<Gdk::Window> win = get_canvas_viewport()->get_window();
return _cursor_stack.back();
if (win) {
return _cursors->from_gdk_cursor (gdk_window_get_cursor (win->gobj()));
}
return nullptr;
} }
void void
@ -2087,36 +2092,6 @@ EditingContext::set_canvas_cursor (Gdk::Cursor* cursor)
} }
} }
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) {
set_canvas_cursor (nullptr);
return;
}
_cursor_stack.pop_back();
if (!_cursor_stack.empty()) {
/* 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;
}
}
}
void void
EditingContext::pack_draw_box () EditingContext::pack_draw_box ()
{ {
@ -2763,18 +2738,6 @@ EditingContext::reset_point_selection ()
} }
} }
EditingContext::EnterContext*
EditingContext::get_enter_context(ItemType type)
{
for (ssize_t i = _enter_stack.size() - 1; i >= 0; --i) {
if (_enter_stack[i].item_type == type) {
return &_enter_stack[i];
}
}
return NULL;
}
void void
EditingContext::choose_canvas_cursor_on_entry (ItemType type) EditingContext::choose_canvas_cursor_on_entry (ItemType type)
{ {
@ -2782,20 +2745,11 @@ EditingContext::choose_canvas_cursor_on_entry (ItemType type)
return; return;
} }
Gdk::Cursor* cursor = which_canvas_cursor(type); Gdk::Cursor* cursor = which_canvas_cursor (type);
if (!_cursors->is_invalid (cursor)) { if (!_cursors->is_invalid (cursor)) {
// Push a new enter context // Push a new enter context
const EnterContext ctx = { type, CursorContext::create(*this, cursor) }; set_canvas_cursor (cursor);
_enter_stack.push_back(ctx);
}
}
void
EditingContext::update_all_enter_cursors ()
{
for (auto & ec : _enter_stack) {
ec.cursor_ctx->change(which_canvas_cursor (ec.item_type));
} }
} }

View file

@ -75,12 +75,6 @@ class SelectableOwner;
class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
{ {
public: public:
/** Context for mouse entry (stored in a stack). */
struct EnterContext {
ItemType item_type;
std::shared_ptr<CursorContext> cursor_ctx;
};
EditingContext (std::string const &); EditingContext (std::string const &);
~EditingContext (); ~EditingContext ();
@ -348,9 +342,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
/** Push the appropriate enter/cursor context on item entry. */ /** Push the appropriate enter/cursor context on item entry. */
void choose_canvas_cursor_on_entry (ItemType); void choose_canvas_cursor_on_entry (ItemType);
/** Update all enter cursors based on current settings. */
void update_all_enter_cursors ();
virtual Gdk::Cursor* get_canvas_cursor () const; virtual Gdk::Cursor* get_canvas_cursor () const;
static MouseCursors const* cursors () { static MouseCursors const* cursors () {
return _cursors; return _cursors;
@ -399,9 +390,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
virtual ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const = 0; virtual ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const = 0;
virtual ArdourCanvas::GtkCanvas* get_canvas() const = 0; virtual ArdourCanvas::GtkCanvas* get_canvas() const = 0;
virtual size_t push_canvas_cursor (Gdk::Cursor*);
virtual void pop_canvas_cursor ();
virtual void mouse_mode_toggled (Editing::MouseMode) = 0; virtual void mouse_mode_toggled (Editing::MouseMode) = 0;
bool on_velocity_scroll_event (GdkEventScroll*); bool on_velocity_scroll_event (GdkEventScroll*);
@ -409,13 +397,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
void select_automation_line (GdkEventButton*, ArdourCanvas::Item*, ARDOUR::SelectionOperation); void select_automation_line (GdkEventButton*, ArdourCanvas::Item*, ARDOUR::SelectionOperation);
/** Get the topmost enter context for the given item type.
*
* This is used to change the cursor associated with a given enter context,
* which may not be on the top of the stack.
*/
virtual EnterContext* get_enter_context(ItemType type);
virtual Gdk::Cursor* which_track_cursor () const = 0; virtual Gdk::Cursor* which_track_cursor () const = 0;
virtual Gdk::Cursor* which_mode_cursor () const = 0; virtual Gdk::Cursor* which_mode_cursor () const = 0;
virtual Gdk::Cursor* which_trim_cursor (bool left_side) const = 0; virtual Gdk::Cursor* which_trim_cursor (bool left_side) const = 0;
@ -437,17 +418,14 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
static EditingContext* current_editing_context(); static EditingContext* current_editing_context();
static void switch_editing_context(EditingContext*); static void switch_editing_context(EditingContext*);
virtual void set_canvas_cursor (Gdk::Cursor*);
protected: protected:
std::string _name; std::string _name;
static Glib::RefPtr<Gtk::ActionGroup> _midi_actions; static Glib::RefPtr<Gtk::ActionGroup> _midi_actions;
static Glib::RefPtr<Gtk::ActionGroup> _common_actions; static Glib::RefPtr<Gtk::ActionGroup> _common_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*);
Editing::GridType pre_internal_grid_type; Editing::GridType pre_internal_grid_type;
Editing::SnapMode pre_internal_snap_mode; Editing::SnapMode pre_internal_snap_mode;
Editing::GridType internal_grid_type; Editing::GridType internal_grid_type;
@ -712,8 +690,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
virtual void set_entered_track (TimeAxisView*) {}; virtual void set_entered_track (TimeAxisView*) {};
std::vector<EnterContext> _enter_stack;
PBD::ScopedConnection escape_connection; PBD::ScopedConnection escape_connection;
virtual void escape () {} virtual void escape () {}

View file

@ -537,8 +537,7 @@ Editor::Editor ()
_group_tabs->signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false); _group_tabs->signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false);
/* Push default cursor to ever-present bottom of cursor stack. */ set_canvas_cursor (nullptr);
push_canvas_cursor (nullptr);
ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ()); ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ());
@ -2095,8 +2094,6 @@ Editor::set_edit_point_preference (EditPoint ep, bool force)
edit_point_selector.set_text (str); edit_point_selector.set_text (str);
} }
update_all_enter_cursors();
if (!force && !changed) { if (!force && !changed) {
return; return;
} }
@ -5673,11 +5670,7 @@ Editor::ui_parameter_changed (string parameter)
EditingContext::ui_parameter_changed (parameter); EditingContext::ui_parameter_changed (parameter);
if (parameter == "icon-set") { if (parameter == "icon-set") {
while (!_cursor_stack.empty()) {
_cursor_stack.pop_back();
}
_cursors->set_cursor_set (UIConfiguration::instance().get_icon_set()); _cursors->set_cursor_set (UIConfiguration::instance().get_icon_set());
_cursor_stack.push_back(nullptr);
content_right_pane.set_drag_cursor (*PublicEditor::instance().cursors()->expand_left_right); content_right_pane.set_drag_cursor (*PublicEditor::instance().cursors()->expand_left_right);
editor_summary_pane.set_drag_cursor (*_cursors->expand_up_down); editor_summary_pane.set_drag_cursor (*_cursors->expand_up_down);

View file

@ -56,7 +56,6 @@
#include "ardour_message.h" #include "ardour_message.h"
#include "ardour_ui.h" #include "ardour_ui.h"
#include "cursor_context.h"
#include "editor.h" #include "editor.h"
#include "sfdb_ui.h" #include "sfdb_ui.h"
#include "editing.h" #include "editing.h"
@ -575,8 +574,7 @@ Editor::import_sndfiles (vector<string> paths,
import_status.track = track; import_status.track = track;
import_status.replace = replace; import_status.replace = replace;
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); set_canvas_cursor (_cursors->wait);
gdk_flush ();
/* start import thread for this spec. this will ultimately call Session::import_files() /* start import thread for this spec. this will ultimately call Session::import_files()
which, if successful, will add the files as regions to the region list. its up to us which, if successful, will add the files as regions to the region list. its up to us
@ -638,8 +636,7 @@ Editor::embed_sndfiles (vector<string> paths,
/* skip periodic saves while importing */ /* skip periodic saves while importing */
Session::StateProtector sp (_session); Session::StateProtector sp (_session);
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); set_canvas_cursor (_cursors->wait);
gdk_flush ();
for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) { for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {

View file

@ -384,11 +384,7 @@ Editor::reset_controls_layout_height (int32_t h)
bool bool
Editor::track_canvas_map_handler (GdkEventAny* /*ev*/) Editor::track_canvas_map_handler (GdkEventAny* /*ev*/)
{ {
if (!_cursor_stack.empty()) { set_canvas_cursor (get_canvas_cursor());
set_canvas_cursor (get_canvas_cursor());
} else {
PBD::error << "cursor stack is empty" << endmsg;
}
return false; return false;
} }
@ -1550,10 +1546,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
MeterMarker *m_marker; MeterMarker *m_marker;
bool ret = true; bool ret = true;
if (!_enter_stack.empty()) {
_enter_stack.pop_back();
}
switch (item_type) { switch (item_type) {
case GridZoneItem: case GridZoneItem:
break; break;

View file

@ -332,11 +332,7 @@ Drag::swap_grab (ArdourCanvas::Item* new_item, Gdk::Cursor* cursor, uint32_t /*t
_item->ungrab (); _item->ungrab ();
_item = new_item; _item = new_item;
if (!_cursor_ctx) { editing_context.set_canvas_cursor (cursor);
_cursor_ctx = CursorContext::create (editing_context, cursor);
} else {
_cursor_ctx->change (cursor);
}
_item->grab (); _item->grab ();
} }
@ -392,7 +388,7 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
if (!editing_context.cursors ()->is_invalid (cursor)) { if (!editing_context.cursors ()->is_invalid (cursor)) {
/* CAIROCANVAS need a variant here that passes *cursor */ /* CAIROCANVAS need a variant here that passes *cursor */
_cursor_ctx = CursorContext::create (editing_context, cursor); editing_context.set_canvas_cursor (cursor);
} }
if (editing_context.session () && editing_context.session ()->transport_rolling ()) { if (editing_context.session () && editing_context.session ()->transport_rolling ()) {
@ -425,7 +421,6 @@ Drag::end_grab (GdkEvent* event)
finished (event, _starting_point_passed); finished (event, _starting_point_passed);
editing_context.verbose_cursor ()->hide (); editing_context.verbose_cursor ()->hide ();
_cursor_ctx.reset ();
return _starting_point_passed; return _starting_point_passed;
} }

View file

@ -41,7 +41,6 @@
#include "gtkmm2ext/bindings.h" #include "gtkmm2ext/bindings.h"
#include "cursor_context.h"
#include "editor_items.h" #include "editor_items.h"
#include "mouse_cursors.h" #include "mouse_cursors.h"
#include "editing.h" #include "editing.h"
@ -353,7 +352,6 @@ private:
* samplepos. used for relative snap. * samplepos. used for relative snap.
*/ */
Temporal::timecnt_t _snap_delta; Temporal::timecnt_t _snap_delta;
CursorContext::Handle _cursor_ctx; ///< cursor change context
bool _constraint_pressed; ///< if the keyboard indicated constraint modifier was pressed on start_grab() bool _constraint_pressed; ///< if the keyboard indicated constraint modifier was pressed on start_grab()
int _grab_button; int _grab_button;

View file

@ -301,8 +301,6 @@ Editor::mouse_mode_toggled (MouseMode m)
get_selection().clear_regions (); get_selection().clear_regions ();
} }
update_all_enter_cursors ();
MouseModeChanged (); /* EMIT SIGNAL */ MouseModeChanged (); /* EMIT SIGNAL */
if ((was_internal && !internal_editing()) || if ((was_internal && !internal_editing()) ||
@ -2385,9 +2383,8 @@ Editor::update_join_object_range_location (double y)
_join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT; _join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT;
Editor::EnterContext* ctx = get_enter_context(RegionItem); if (_join_object_range_state != old) {
if (_join_object_range_state != old && ctx) { set_canvas_cursor (which_track_cursor());
ctx->cursor_ctx->change(which_track_cursor());
} }
} else if (entered_track) { } else if (entered_track) {
@ -2419,9 +2416,8 @@ Editor::update_join_object_range_location (double y)
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT; _join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
} }
Editor::EnterContext* ctx = get_enter_context(StreamItem); if (_join_object_range_state != old) {
if (_join_object_range_state != old && ctx) { set_canvas_cursor (which_track_cursor());
ctx->cursor_ctx->change(which_track_cursor());
} }
} }
} }

View file

@ -4379,7 +4379,7 @@ Editor::freeze_route ()
pthread_create_and_store (X_("freezer"), &itt.thread, _freeze_thread, this, 0); pthread_create_and_store (X_("freezer"), &itt.thread, _freeze_thread, this, 0);
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); set_canvas_cursor (_cursors->wait);
while (!itt.done && !itt.cancel) { while (!itt.done && !itt.cancel) {
gtk_main_iteration (); gtk_main_iteration ();
@ -5921,8 +5921,7 @@ Editor::normalize_region ()
return; return;
} }
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); set_canvas_cursor (_cursors->wait);
gdk_flush ();
/* XXX: should really only count audio regions here */ /* XXX: should really only count audio regions here */
int const regions = rs.size (); int const regions = rs.size ();
@ -6201,11 +6200,9 @@ Editor::fork_regions_from_unselected ()
return; return;
} }
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); set_canvas_cursor (_cursors->wait);
bool in_command = false; bool in_command = false;
gdk_flush ();
/* find the set of all MidiSources associated with the selected regions */ /* find the set of all MidiSources associated with the selected regions */
std::set<std::shared_ptr<MidiSource> > sources_list; std::set<std::shared_ptr<MidiSource> > sources_list;
for (const auto& r : rs) { for (const auto& r : rs) {
@ -6281,11 +6278,9 @@ Editor::fork_selected_regions ()
return; return;
} }
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); set_canvas_cursor (_cursors->wait);
bool in_command = false; bool in_command = false;
gdk_flush ();
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) { for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
RegionSelection::iterator tmp = r; RegionSelection::iterator tmp = r;
++tmp; ++tmp;
@ -6365,11 +6360,9 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
return; return;
} }
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); set_canvas_cursor (_cursors->wait);
bool in_command = false; bool in_command = false;
gdk_flush ();
int n = 0; int n = 0;
int const N = rs.size (); int const N = rs.size ();

View file

@ -48,7 +48,6 @@
#include "ptformat/ptformat.h" #include "ptformat/ptformat.h"
#include "ardour_ui.h" #include "ardour_ui.h"
#include "cursor_context.h"
#include "editor.h" #include "editor.h"
#include "sfdb_ui.h" #include "sfdb_ui.h"
#include "editing.h" #include "editing.h"

View file

@ -1728,10 +1728,6 @@ MidiCueEditor::leave_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType i
{ {
EditorAutomationLine* al; EditorAutomationLine* al;
if (!_enter_stack.empty()) {
_enter_stack.pop_back();
}
switch (item_type) { switch (item_type) {
case ControlPointItem: case ControlPointItem:
_verbose_cursor->hide (); _verbose_cursor->hide ();

View file

@ -382,7 +382,7 @@ MidiRegionView::button_press (GdkEventButton* ev)
MouseMode m = _editing_context.current_mouse_mode(); MouseMode m = _editing_context.current_mouse_mode();
if (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) { if (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
_press_cursor_ctx = CursorContext::create(_editing_context, _editing_context.cursors()->midi_pencil); _editing_context.set_canvas_cursor (_editing_context.cursors()->midi_pencil);
} }
if (_mouse_state != SelectTouchDragging) { if (_mouse_state != SelectTouchDragging) {

View file

@ -507,7 +507,7 @@ MidiView::button_press (GdkEventButton* ev)
MouseMode m = _editing_context.current_mouse_mode(); MouseMode m = _editing_context.current_mouse_mode();
if (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) { if (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
_press_cursor_ctx = CursorContext::create(_editing_context, _editing_context.cursors()->midi_pencil); _editing_context.set_canvas_cursor (_editing_context.cursors()->midi_pencil);
} }
if (_mouse_state != SelectTouchDragging) { if (_mouse_state != SelectTouchDragging) {
@ -3948,14 +3948,13 @@ MidiView::note_mouse_position (float x_fraction, float /*y_fraction*/, bool can_
Editing::MouseMode mm = _editing_context.current_mouse_mode(); Editing::MouseMode mm = _editing_context.current_mouse_mode();
bool trimmable = (mm == MouseContent || mm == MouseTimeFX || mm == MouseDraw); bool trimmable = (mm == MouseContent || mm == MouseTimeFX || mm == MouseDraw);
EditingContext::EnterContext* ctx = _editing_context.get_enter_context(NoteItem); if (can_set_cursor) {
if (can_set_cursor && ctx) {
if (trimmable && x_fraction > 0.0 && x_fraction < 0.2) { if (trimmable && x_fraction > 0.0 && x_fraction < 0.2) {
ctx->cursor_ctx->change(_editing_context.cursors()->left_side_trim); _editing_context.set_canvas_cursor (_editing_context.cursors()->left_side_trim);
} else if (trimmable && x_fraction >= 0.8 && x_fraction < 1.0) { } else if (trimmable && x_fraction >= 0.8 && x_fraction < 1.0) {
ctx->cursor_ctx->change(_editing_context.cursors()->right_side_trim); _editing_context.set_canvas_cursor (_editing_context.cursors()->right_side_trim);
} else { } else {
ctx->cursor_ctx->change(_editing_context.cursors()->grabber_note); _editing_context.set_canvas_cursor (_editing_context.cursors()->grabber_note);
} }
} }
} }

View file

@ -129,7 +129,9 @@ MouseCursors::make_cursor (const char* name, int hotspot_x, int hotspot_y)
} }
Glib::RefPtr<Gdk::Pixbuf> p (::get_icon (name, _cursor_set)); Glib::RefPtr<Gdk::Pixbuf> p (::get_icon (name, _cursor_set));
return new Gdk::Cursor (Gdk::Display::get_default(), p, hotspot_x, hotspot_y); Gdk::Cursor* c = new Gdk::Cursor (Gdk::Display::get_default(), p, hotspot_x, hotspot_y);
cursors.push_back (c);
return c;
} }
void void
@ -218,3 +220,16 @@ MouseCursors::create_invalid()
Gdk::Color c; Gdk::Color c;
_invalid = new Gdk::Cursor (bits, bits, c, c, 0, 0); _invalid = new Gdk::Cursor (bits, bits, c, c, 0, 0);
} }
Gdk::Cursor*
MouseCursors::from_gdk_cursor (GdkCursor* gc)
{
for (auto & c : cursors) {
if (c->gobj() == gc) {
return c;
}
}
return nullptr;
}

View file

@ -39,6 +39,8 @@ public:
void set_cursor_set (const std::string& name); void set_cursor_set (const std::string& name);
std::string cursor_set() const { return _cursor_set; } std::string cursor_set() const { return _cursor_set; }
Gdk::Cursor* from_gdk_cursor (GdkCursor*);
Gdk::Cursor* cross_hair; Gdk::Cursor* cross_hair;
Gdk::Cursor* scissors; Gdk::Cursor* scissors;
Gdk::Cursor* trimmer; Gdk::Cursor* trimmer;
@ -88,6 +90,7 @@ public:
static Gdk::Cursor* invalid_cursor() { if (!_invalid) { create_invalid(); } return _invalid; } static Gdk::Cursor* invalid_cursor() { if (!_invalid) { create_invalid(); } return _invalid; }
private: private:
std::vector<Gdk::Cursor*> cursors;
std::string _cursor_set; std::string _cursor_set;
void drop_all (); void drop_all ();

View file

@ -637,17 +637,17 @@ PianoRollHeader::motion_handler (GdkEventMotion* ev)
if (evd.y > scroomer_top - 5 && evd.y < scroomer_top + edge){ if (evd.y > scroomer_top - 5 && evd.y < scroomer_top + edge){
if (_scroomer_state != TOP) { if (_scroomer_state != TOP) {
_view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->resize_top); _view->editing_context().set_canvas_cursor (_view->editing_context().cursors()->resize_top);
_scroomer_state = TOP; _scroomer_state = TOP;
} }
} else if (evd.y > scroomer_bottom - edge && evd.y < scroomer_bottom + edge){ } else if (evd.y > scroomer_bottom - edge && evd.y < scroomer_bottom + edge){
if (_scroomer_state != BOTTOM) { if (_scroomer_state != BOTTOM) {
_view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->resize_bottom); _view->editing_context().set_canvas_cursor (_view->editing_context().cursors()->resize_bottom);
_scroomer_state = BOTTOM; _scroomer_state = BOTTOM;
} }
} else { } else {
if (_scroomer_state != MOVE) { if (_scroomer_state != MOVE) {
_view->editing_context().push_canvas_cursor (_view->editing_context().cursors()->grabber); _view->editing_context().set_canvas_cursor (_view->editing_context().cursors()->grabber);
_scroomer_state = MOVE; _scroomer_state = MOVE;
} }
} }
@ -870,7 +870,7 @@ PianoRollHeader::leave_handler (GdkEventCrossing*)
{ {
if (!_scroomer_drag){ if (!_scroomer_drag){
if (_view) { if (_view) {
_view->editing_context().pop_canvas_cursor (); /* XXX we used to pop the cursor stack here */
} }
} }
invalidate_note_range(_highlighted_note, _highlighted_note); invalidate_note_range(_highlighted_note, _highlighted_note);

View file

@ -65,7 +65,6 @@ gtk2_ardour_sources = [
'control_slave_ui.cc', 'control_slave_ui.cc',
'cuebox_ui.cc', 'cuebox_ui.cc',
'cue_editor.cc', 'cue_editor.cc',
'cursor_context.cc',
'curvetest.cc', 'curvetest.cc',
'debug.cc', 'debug.cc',
'dsp_stats_ui.cc', 'dsp_stats_ui.cc',