mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-11 00:56:33 +01:00
Fix various cursor problems.
Add a new scoped cursor system that makes it much harder to screw up and end up with stick cursors and so on.
This commit is contained in:
parent
5d8021bf44
commit
670938c8c4
13 changed files with 254 additions and 149 deletions
62
gtk2_ardour/cursor_context.cc
Normal file
62
gtk2_ardour/cursor_context.cc
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2014 Paul Davis
|
||||||
|
Author: David Robillard
|
||||||
|
|
||||||
|
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pbd/error.h>
|
||||||
|
|
||||||
|
#include "editor.h"
|
||||||
|
#include "cursor_context.h"
|
||||||
|
|
||||||
|
CursorContext::CursorContext(Editor& editor, Gdk::Cursor* cursor)
|
||||||
|
: _editor(editor)
|
||||||
|
, _index(editor.push_canvas_cursor(cursor))
|
||||||
|
{}
|
||||||
|
|
||||||
|
CursorContext::~CursorContext()
|
||||||
|
{
|
||||||
|
if (_index == _editor._cursor_stack.size() - 1) {
|
||||||
|
_editor.pop_canvas_cursor();
|
||||||
|
} else {
|
||||||
|
_editor._cursor_stack[_index] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorContext::Handle
|
||||||
|
CursorContext::create(Editor& editor, Gdk::Cursor* cursor)
|
||||||
|
{
|
||||||
|
return CursorContext::Handle(new CursorContext(editor, cursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CursorContext::change(Gdk::Cursor* cursor)
|
||||||
|
{
|
||||||
|
_editor._cursor_stack[_index] = cursor;
|
||||||
|
if (_index == _editor._cursor_stack.size() - 1) {
|
||||||
|
_editor.set_canvas_cursor(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CursorContext::set(Handle* handle, Editor& editor, Gdk::Cursor* cursor)
|
||||||
|
{
|
||||||
|
if (*handle) {
|
||||||
|
(*handle)->change(cursor);
|
||||||
|
} else {
|
||||||
|
*handle = CursorContext::create(editor, cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
75
gtk2_ardour/cursor_context.h
Normal file
75
gtk2_ardour/cursor_context.h
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2014 Paul Davis
|
||||||
|
Author: David Robillard
|
||||||
|
|
||||||
|
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ardour_gtk_cursor_context_h__
|
||||||
|
#define __ardour_gtk_cursor_context_h__
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <gdkmm/cursor.h>
|
||||||
|
|
||||||
|
class Editor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 boost::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(Editor& editor, 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, Editor& editor, Gdk::Cursor* cursor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Editor& _editor;
|
||||||
|
size_t _index;
|
||||||
|
|
||||||
|
CursorContext(Editor& editor, Gdk::Cursor* cursor);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __ardour_gtk_cursor_context_h__ */
|
||||||
|
|
@ -313,7 +313,6 @@ Editor::Editor ()
|
||||||
clicked_routeview = 0;
|
clicked_routeview = 0;
|
||||||
clicked_control_point = 0;
|
clicked_control_point = 0;
|
||||||
last_update_frame = 0;
|
last_update_frame = 0;
|
||||||
pre_press_cursor = 0;
|
|
||||||
last_paste_pos = 0;
|
last_paste_pos = 0;
|
||||||
paste_count = 0;
|
paste_count = 0;
|
||||||
_drags = new DragManager (this);
|
_drags = new DragManager (this);
|
||||||
|
|
@ -374,6 +373,7 @@ Editor::Editor ()
|
||||||
current_stepping_trackview = 0;
|
current_stepping_trackview = 0;
|
||||||
entered_track = 0;
|
entered_track = 0;
|
||||||
entered_regionview = 0;
|
entered_regionview = 0;
|
||||||
|
_entered_item_type = NoItem;
|
||||||
entered_marker = 0;
|
entered_marker = 0;
|
||||||
clear_entered_track = false;
|
clear_entered_track = false;
|
||||||
current_timefx = 0;
|
current_timefx = 0;
|
||||||
|
|
@ -400,7 +400,6 @@ Editor::Editor ()
|
||||||
|
|
||||||
zoom_focus = ZoomFocusLeft;
|
zoom_focus = ZoomFocusLeft;
|
||||||
_edit_point = EditAtMouse;
|
_edit_point = EditAtMouse;
|
||||||
current_canvas_cursor = 0;
|
|
||||||
_visible_track_count = -1;
|
_visible_track_count = -1;
|
||||||
|
|
||||||
samples_per_pixel = 2048; /* too early to use reset_zoom () */
|
samples_per_pixel = 2048; /* too early to use reset_zoom () */
|
||||||
|
|
@ -520,6 +519,9 @@ Editor::Editor ()
|
||||||
_cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
|
_cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
|
||||||
cerr << "Set cursor set to " << ARDOUR_UI::config()->get_icon_set() << endl;
|
cerr << "Set cursor set to " << ARDOUR_UI::config()->get_icon_set() << endl;
|
||||||
|
|
||||||
|
/* Push default cursor to ever-present bottom of cursor stack. */
|
||||||
|
push_canvas_cursor(_cursors->grabber);
|
||||||
|
|
||||||
ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ());
|
ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ());
|
||||||
|
|
||||||
ArdourCanvas::Line* pad_line_1 = new ArdourCanvas::Line (time_pad->root());
|
ArdourCanvas::Line* pad_line_1 = new ArdourCanvas::Line (time_pad->root());
|
||||||
|
|
@ -2120,7 +2122,9 @@ Editor::set_edit_point_preference (EditPoint ep, bool force)
|
||||||
edit_point_selector.set_text (str);
|
edit_point_selector.set_text (str);
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_canvas_cursor ();
|
if (_entered_item_type != NoItem) {
|
||||||
|
choose_canvas_cursor_on_entry (_entered_item_type);
|
||||||
|
}
|
||||||
|
|
||||||
if (!force && !changed) {
|
if (!force && !changed) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -5744,9 +5748,10 @@ Editor::ui_parameter_changed (string parameter)
|
||||||
{
|
{
|
||||||
if (parameter == "icon-set") {
|
if (parameter == "icon-set") {
|
||||||
while (!_cursor_stack.empty()) {
|
while (!_cursor_stack.empty()) {
|
||||||
_cursor_stack.pop();
|
_cursor_stack.pop_back();
|
||||||
}
|
}
|
||||||
_cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
|
_cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
|
||||||
|
_cursor_stack.push_back(_cursors->grabber);
|
||||||
} else if (parameter == "draggable-playhead") {
|
} else if (parameter == "draggable-playhead") {
|
||||||
if (_verbose_cursor) {
|
if (_verbose_cursor) {
|
||||||
playhead_cursor->set_sensitive (ARDOUR_UI::config()->get_draggable_playhead());
|
playhead_cursor->set_sensitive (ARDOUR_UI::config()->get_draggable_playhead());
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,14 @@
|
||||||
#ifndef __ardour_editor_h__
|
#ifndef __ardour_editor_h__
|
||||||
#define __ardour_editor_h__
|
#define __ardour_editor_h__
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stack>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sys/time.h>
|
#include <vector>
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
|
@ -97,6 +98,7 @@ class AutomationTimeAxisView;
|
||||||
class BundleManager;
|
class BundleManager;
|
||||||
class ButtonJoiner;
|
class ButtonJoiner;
|
||||||
class ControlPoint;
|
class ControlPoint;
|
||||||
|
class CursorContext;
|
||||||
class DragManager;
|
class DragManager;
|
||||||
class EditNoteDialog;
|
class EditNoteDialog;
|
||||||
class EditorCursor;
|
class EditorCursor;
|
||||||
|
|
@ -439,11 +441,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
void maybe_autoscroll (bool, bool, bool);
|
void maybe_autoscroll (bool, bool, bool);
|
||||||
bool autoscroll_active() const;
|
bool autoscroll_active() const;
|
||||||
|
|
||||||
Gdk::Cursor* get_canvas_cursor () const { return current_canvas_cursor; }
|
Gdk::Cursor* get_canvas_cursor () const;
|
||||||
void set_canvas_cursor (Gdk::Cursor*, bool save=false);
|
|
||||||
|
|
||||||
void push_canvas_cursor (Gdk::Cursor*);
|
|
||||||
void pop_canvas_cursor ();
|
|
||||||
|
|
||||||
void set_current_trimmable (boost::shared_ptr<ARDOUR::Trimmable>);
|
void set_current_trimmable (boost::shared_ptr<ARDOUR::Trimmable>);
|
||||||
void set_current_movable (boost::shared_ptr<ARDOUR::Movable>);
|
void set_current_movable (boost::shared_ptr<ARDOUR::Movable>);
|
||||||
|
|
@ -726,14 +724,18 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
Gtk::VBox global_vpacker;
|
Gtk::VBox global_vpacker;
|
||||||
Gtk::VBox vpacker;
|
Gtk::VBox vpacker;
|
||||||
|
|
||||||
std::stack<Gdk::Cursor*> _cursor_stack;
|
/* Cursor stuff. Do not use directly, use via CursorContext. */
|
||||||
Gdk::Cursor* current_canvas_cursor;
|
friend class CursorContext;
|
||||||
|
std::vector<Gdk::Cursor*> _cursor_stack;
|
||||||
|
void set_canvas_cursor (Gdk::Cursor*);
|
||||||
|
size_t push_canvas_cursor (Gdk::Cursor*);
|
||||||
|
void pop_canvas_cursor ();
|
||||||
|
|
||||||
Gdk::Cursor* which_grabber_cursor () const;
|
Gdk::Cursor* which_grabber_cursor () const;
|
||||||
Gdk::Cursor* which_track_cursor () const;
|
Gdk::Cursor* which_track_cursor () const;
|
||||||
Gdk::Cursor* which_mode_cursor () const;
|
Gdk::Cursor* which_mode_cursor () const;
|
||||||
Gdk::Cursor* which_trim_cursor (bool left_side) const;
|
Gdk::Cursor* which_trim_cursor (bool left_side) const;
|
||||||
bool reset_canvas_cursor ();
|
void choose_canvas_cursor_on_entry (ItemType);
|
||||||
void choose_canvas_cursor_on_entry (GdkEventCrossing*, ItemType);
|
|
||||||
|
|
||||||
ArdourCanvas::GtkCanvas* _track_canvas;
|
ArdourCanvas::GtkCanvas* _track_canvas;
|
||||||
ArdourCanvas::GtkCanvasViewport* _track_canvas_viewport;
|
ArdourCanvas::GtkCanvasViewport* _track_canvas_viewport;
|
||||||
|
|
@ -1095,7 +1097,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
framepos_t cut_buffer_start;
|
framepos_t cut_buffer_start;
|
||||||
framecnt_t cut_buffer_length;
|
framecnt_t cut_buffer_length;
|
||||||
|
|
||||||
Gdk::Cursor* pre_press_cursor;
|
boost::shared_ptr<CursorContext> _press_cursor_ctx; ///< Button press cursor context
|
||||||
|
boost::shared_ptr<CursorContext> _enter_cursor_ctx; ///< Entered item cursor context
|
||||||
|
|
||||||
boost::weak_ptr<ARDOUR::Trimmable> _trimmable;
|
boost::weak_ptr<ARDOUR::Trimmable> _trimmable;
|
||||||
boost::weak_ptr<ARDOUR::Movable> _movable;
|
boost::weak_ptr<ARDOUR::Movable> _movable;
|
||||||
|
|
||||||
|
|
@ -1978,6 +1982,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
*/
|
*/
|
||||||
RegionView* entered_regionview;
|
RegionView* entered_regionview;
|
||||||
|
|
||||||
|
ItemType _entered_item_type;
|
||||||
|
|
||||||
bool clear_entered_track;
|
bool clear_entered_track;
|
||||||
bool left_track_canvas (GdkEventCrossing*);
|
bool left_track_canvas (GdkEventCrossing*);
|
||||||
bool entered_track_canvas (GdkEventCrossing*);
|
bool entered_track_canvas (GdkEventCrossing*);
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
#include "pbd/memento_command.h"
|
#include "pbd/memento_command.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"
|
||||||
|
|
@ -475,7 +476,7 @@ Editor::import_sndfiles (vector<string> paths, ImportDisposition disposition, Im
|
||||||
import_status.track = track;
|
import_status.track = track;
|
||||||
import_status.replace = replace;
|
import_status.replace = replace;
|
||||||
|
|
||||||
set_canvas_cursor (_cursors->wait);
|
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||||
gdk_flush ();
|
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()
|
||||||
|
|
@ -512,7 +513,6 @@ Editor::import_sndfiles (vector<string> paths, ImportDisposition disposition, Im
|
||||||
}
|
}
|
||||||
|
|
||||||
import_status.sources.clear();
|
import_status.sources.clear();
|
||||||
set_canvas_cursor (current_canvas_cursor);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -526,9 +526,8 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
||||||
SourceList sources;
|
SourceList sources;
|
||||||
string linked_path;
|
string linked_path;
|
||||||
SoundFileInfo finfo;
|
SoundFileInfo finfo;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
push_canvas_cursor (_cursors->wait);
|
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||||
gdk_flush ();
|
gdk_flush ();
|
||||||
|
|
||||||
for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
|
for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
|
||||||
|
|
@ -540,7 +539,7 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
||||||
|
|
||||||
if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
|
if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
|
||||||
error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), path, error_msg ) << endmsg;
|
error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), path, error_msg ) << endmsg;
|
||||||
goto out;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_sample_rate && (finfo.samplerate != (int) _session->frame_rate())) {
|
if (check_sample_rate && (finfo.samplerate != (int) _session->frame_rate())) {
|
||||||
|
|
@ -562,19 +561,16 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
||||||
|
|
||||||
switch (resx) {
|
switch (resx) {
|
||||||
case 0: /* stop a multi-file import */
|
case 0: /* stop a multi-file import */
|
||||||
ret = -2;
|
return -2;
|
||||||
goto out;
|
|
||||||
case 1: /* don't embed this one */
|
case 1: /* don't embed this one */
|
||||||
ret = -1;
|
return -1;
|
||||||
goto out;
|
|
||||||
case 2: /* do it, and the rest without asking */
|
case 2: /* do it, and the rest without asking */
|
||||||
check_sample_rate = false;
|
check_sample_rate = false;
|
||||||
break;
|
break;
|
||||||
case 3: /* do it */
|
case 3: /* do it */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -2;
|
return -2;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
choices.push_back (_("Cancel"));
|
choices.push_back (_("Cancel"));
|
||||||
|
|
@ -590,13 +586,11 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
||||||
|
|
||||||
switch (resx) {
|
switch (resx) {
|
||||||
case 0: /* don't import */
|
case 0: /* don't import */
|
||||||
ret = -1;
|
return -1;
|
||||||
goto out;
|
|
||||||
case 1: /* do it */
|
case 1: /* do it */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -2;
|
return -2;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -627,23 +621,18 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
catch (failed_constructor& err) {
|
||||||
error << string_compose(_("could not open %1"), path) << endmsg;
|
error << string_compose(_("could not open %1"), path) << endmsg;
|
||||||
goto out;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_main_iteration();
|
gtk_main_iteration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sources.empty()) {
|
if (!sources.empty()) {
|
||||||
goto out;
|
return add_sources (paths, sources, pos, disposition, mode, target_regions, target_tracks, track, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
ret = add_sources (paths, sources, pos, disposition, mode, target_regions, target_tracks, track, true);
|
|
||||||
|
|
||||||
out:
|
|
||||||
pop_canvas_cursor ();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
#include "ardour/rc_configuration.h"
|
#include "ardour/rc_configuration.h"
|
||||||
#include "ardour/smf_source.h"
|
#include "ardour/smf_source.h"
|
||||||
|
|
||||||
|
#include "pbd/error.h"
|
||||||
|
|
||||||
#include "canvas/canvas.h"
|
#include "canvas/canvas.h"
|
||||||
#include "canvas/rectangle.h"
|
#include "canvas/rectangle.h"
|
||||||
#include "canvas/pixbuf.h"
|
#include "canvas/pixbuf.h"
|
||||||
|
|
@ -367,8 +369,10 @@ 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 (current_canvas_cursor) {
|
if (!_cursor_stack.empty()) {
|
||||||
set_canvas_cursor (current_canvas_cursor);
|
set_canvas_cursor (get_canvas_cursor());
|
||||||
|
} else {
|
||||||
|
PBD::error << "cursor stack is empty" << endmsg;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -985,13 +989,16 @@ Editor::get_track_canvas() const
|
||||||
return _track_canvas_viewport;
|
return _track_canvas_viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
Gdk::Cursor*
|
||||||
Editor::set_canvas_cursor (Gdk::Cursor* cursor, bool save)
|
Editor::get_canvas_cursor () const
|
||||||
{
|
{
|
||||||
if (save) {
|
/* The top of the cursor stack is always the currently visible cursor. */
|
||||||
current_canvas_cursor = cursor;
|
return _cursor_stack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::set_canvas_cursor (Gdk::Cursor* cursor)
|
||||||
|
{
|
||||||
Glib::RefPtr<Gdk::Window> win = _track_canvas->get_window();
|
Glib::RefPtr<Gdk::Window> win = _track_canvas->get_window();
|
||||||
|
|
||||||
if (win && cursor) {
|
if (win && cursor) {
|
||||||
|
|
@ -999,22 +1006,32 @@ Editor::set_canvas_cursor (Gdk::Cursor* cursor, bool save)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
size_t
|
||||||
Editor::push_canvas_cursor (Gdk::Cursor* cursor)
|
Editor::push_canvas_cursor (Gdk::Cursor* cursor)
|
||||||
{
|
{
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
_cursor_stack.push (cursor);
|
_cursor_stack.push_back (cursor);
|
||||||
set_canvas_cursor (cursor, false);
|
set_canvas_cursor (cursor);
|
||||||
}
|
}
|
||||||
|
return _cursor_stack.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::pop_canvas_cursor ()
|
Editor::pop_canvas_cursor ()
|
||||||
{
|
{
|
||||||
if (!_cursor_stack.empty()) {
|
while (true) {
|
||||||
Gdk::Cursor* cursor = _cursor_stack.top ();
|
if (_cursor_stack.size() <= 1) {
|
||||||
_cursor_stack.pop ();
|
PBD::error << "attempt to pop default cursor" << endmsg;
|
||||||
set_canvas_cursor (cursor, false);
|
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. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1147,29 +1164,8 @@ Editor::which_track_cursor () const
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
Editor::reset_canvas_cursor ()
|
|
||||||
{
|
|
||||||
if (!is_drawable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Gdk::Cursor* cursor = which_mode_cursor ();
|
|
||||||
|
|
||||||
if (!cursor) {
|
|
||||||
cursor = which_grabber_cursor ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor) {
|
|
||||||
set_canvas_cursor (cursor);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType type)
|
Editor::choose_canvas_cursor_on_entry (ItemType type)
|
||||||
{
|
{
|
||||||
Gdk::Cursor* cursor = 0;
|
Gdk::Cursor* cursor = 0;
|
||||||
|
|
||||||
|
|
@ -1179,7 +1175,8 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
|
||||||
|
|
||||||
cursor = which_mode_cursor ();
|
cursor = which_mode_cursor ();
|
||||||
|
|
||||||
if (mouse_mode == MouseObject || get_smart_mode ()) {
|
if ((mouse_mode == MouseObject || get_smart_mode ()) ||
|
||||||
|
mouse_mode == MouseContent) {
|
||||||
|
|
||||||
/* find correct cursor to use in object/smart mode */
|
/* find correct cursor to use in object/smart mode */
|
||||||
|
|
||||||
|
|
@ -1238,9 +1235,6 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
|
||||||
case FadeOutTrimHandleItem:
|
case FadeOutTrimHandleItem:
|
||||||
cursor = _cursors->fade_out;
|
cursor = _cursors->fade_out;
|
||||||
break;
|
break;
|
||||||
case NoteItem:
|
|
||||||
cursor = which_grabber_cursor();
|
|
||||||
break;
|
|
||||||
case FeatureLineItem:
|
case FeatureLineItem:
|
||||||
cursor = _cursors->cross_hair;
|
cursor = _cursors->cross_hair;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1313,7 +1307,8 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
set_canvas_cursor (cursor, true);
|
CursorContext::set(&_enter_cursor_ctx, *this, cursor);
|
||||||
|
_entered_item_type = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
|
||||||
} else {
|
} else {
|
||||||
/* CAIROCANVAS need a variant here that passes *cursor */
|
/* CAIROCANVAS need a variant here that passes *cursor */
|
||||||
_item->grab ();
|
_item->grab ();
|
||||||
_editor->push_canvas_cursor (cursor);
|
_cursor_ctx = CursorContext::create(*_editor, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_editor->session() && _editor->session()->transport_rolling()) {
|
if (_editor->session() && _editor->session()->transport_rolling()) {
|
||||||
|
|
@ -311,7 +311,7 @@ Drag::end_grab (GdkEvent* event)
|
||||||
finished (event, _move_threshold_passed);
|
finished (event, _move_threshold_passed);
|
||||||
|
|
||||||
_editor->verbose_cursor()->hide ();
|
_editor->verbose_cursor()->hide ();
|
||||||
_editor->pop_canvas_cursor ();
|
_cursor_ctx.reset();
|
||||||
|
|
||||||
return _move_threshold_passed;
|
return _move_threshold_passed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
||||||
|
#include "cursor_context.h"
|
||||||
#include "editor_items.h"
|
#include "editor_items.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
@ -240,6 +241,7 @@ private:
|
||||||
ARDOUR::framepos_t _raw_grab_frame; ///< unsnapped frame that the mouse was at when start_grab was called, or 0
|
ARDOUR::framepos_t _raw_grab_frame; ///< unsnapped frame that the mouse was at when start_grab was called, or 0
|
||||||
ARDOUR::framepos_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0
|
ARDOUR::framepos_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0
|
||||||
ARDOUR::framepos_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred
|
ARDOUR::framepos_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred
|
||||||
|
CursorContext::Handle _cursor_ctx; ///< cursor change context
|
||||||
};
|
};
|
||||||
|
|
||||||
class RegionDrag;
|
class RegionDrag;
|
||||||
|
|
|
||||||
|
|
@ -705,7 +705,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
case RegionViewName:
|
case RegionViewName:
|
||||||
case StreamItem:
|
case StreamItem:
|
||||||
case AutomationTrackItem:
|
case AutomationTrackItem:
|
||||||
_drags->set (new RegionCutDrag (this, item, canvas_event_sample (event)), event, current_canvas_cursor);
|
_drags->set (new RegionCutDrag (this, item, canvas_event_sample (event)), event, get_canvas_cursor());
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -719,7 +719,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
/* Existing note: allow trimming/motion */
|
/* Existing note: allow trimming/motion */
|
||||||
if ((note = reinterpret_cast<NoteBase*> (item->get_data ("notebase")))) {
|
if ((note = reinterpret_cast<NoteBase*> (item->get_data ("notebase")))) {
|
||||||
if (note->big_enough_to_trim() && note->mouse_near_ends()) {
|
if (note->big_enough_to_trim() && note->mouse_near_ends()) {
|
||||||
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
|
_drags->set (new NoteResizeDrag (this, item), event, get_canvas_cursor());
|
||||||
} else {
|
} else {
|
||||||
_drags->set (new NoteDrag (this, item), event);
|
_drags->set (new NoteDrag (this, item), event);
|
||||||
}
|
}
|
||||||
|
|
@ -938,7 +938,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
if ((note = reinterpret_cast<NoteBase*>(item->get_data ("notebase")))) {
|
if ((note = reinterpret_cast<NoteBase*>(item->get_data ("notebase")))) {
|
||||||
if (note->big_enough_to_trim() && note->mouse_near_ends()) {
|
if (note->big_enough_to_trim() && note->mouse_near_ends()) {
|
||||||
/* Note is big and pointer is near the end, trim */
|
/* Note is big and pointer is near the end, trim */
|
||||||
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
|
_drags->set (new NoteResizeDrag (this, item), event, get_canvas_cursor());
|
||||||
} else {
|
} else {
|
||||||
/* Drag note */
|
/* Drag note */
|
||||||
_drags->set (new NoteDrag (this, item), event);
|
_drags->set (new NoteDrag (this, item), event);
|
||||||
|
|
@ -964,7 +964,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
/* resize-drag notes */
|
/* resize-drag notes */
|
||||||
if ((note = reinterpret_cast<NoteBase*>(item->get_data ("notebase")))) {
|
if ((note = reinterpret_cast<NoteBase*>(item->get_data ("notebase")))) {
|
||||||
if (note->big_enough_to_trim()) {
|
if (note->big_enough_to_trim()) {
|
||||||
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
|
_drags->set (new NoteResizeDrag (this, item), event, get_canvas_cursor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -976,12 +976,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MouseAudition:
|
case MouseAudition:
|
||||||
_drags->set (new ScrubDrag (this, item), event);
|
_drags->set (new ScrubDrag (this, item), event, _cursors->transparent);
|
||||||
scrub_reversals = 0;
|
scrub_reversals = 0;
|
||||||
scrub_reverse_distance = 0;
|
scrub_reverse_distance = 0;
|
||||||
last_scrub_x = event->button.x;
|
last_scrub_x = event->button.x;
|
||||||
scrubbing_direction = 0;
|
scrubbing_direction = 0;
|
||||||
push_canvas_cursor (_cursors->transparent);
|
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1068,8 +1067,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre_press_cursor = current_canvas_cursor;
|
|
||||||
|
|
||||||
_track_canvas->grab_focus();
|
_track_canvas->grab_focus();
|
||||||
|
|
||||||
if (_session && _session->actively_recording()) {
|
if (_session && _session->actively_recording()) {
|
||||||
|
|
@ -1141,10 +1138,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
framepos_t where = canvas_event_sample (event);
|
framepos_t where = canvas_event_sample (event);
|
||||||
AutomationTimeAxisView* atv = 0;
|
AutomationTimeAxisView* atv = 0;
|
||||||
|
|
||||||
if (pre_press_cursor) {
|
_press_cursor_ctx.reset();
|
||||||
set_canvas_cursor (pre_press_cursor);
|
|
||||||
pre_press_cursor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no action if we're recording */
|
/* no action if we're recording */
|
||||||
|
|
||||||
|
|
@ -1441,7 +1435,6 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MouseAudition:
|
case MouseAudition:
|
||||||
pop_canvas_cursor ();
|
|
||||||
if (scrubbing_direction == 0) {
|
if (scrubbing_direction == 0) {
|
||||||
/* no drag, just a click */
|
/* no drag, just a click */
|
||||||
switch (item_type) {
|
switch (item_type) {
|
||||||
|
|
@ -1529,7 +1522,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||||
* (e.g. the actual entered regionview)
|
* (e.g. the actual entered regionview)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
choose_canvas_cursor_on_entry (&event->crossing, item_type);
|
choose_canvas_cursor_on_entry (item_type);
|
||||||
|
|
||||||
switch (item_type) {
|
switch (item_type) {
|
||||||
case ControlPointItem:
|
case ControlPointItem:
|
||||||
|
|
@ -1649,7 +1642,8 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
|
||||||
bool is_start;
|
bool is_start;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
reset_canvas_cursor ();
|
_enter_cursor_ctx.reset();
|
||||||
|
_entered_item_type = NoItem;
|
||||||
|
|
||||||
switch (item_type) {
|
switch (item_type) {
|
||||||
case ControlPointItem:
|
case ControlPointItem:
|
||||||
|
|
@ -2321,8 +2315,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;
|
||||||
|
|
||||||
if (_join_object_range_state != old) {
|
if (_join_object_range_state != old && _enter_cursor_ctx) {
|
||||||
set_canvas_cursor (which_track_cursor ());
|
_enter_cursor_ctx->change(which_track_cursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (entered_track) {
|
} else if (entered_track) {
|
||||||
|
|
@ -2354,8 +2348,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_join_object_range_state != old) {
|
if (_join_object_range_state != old && _enter_cursor_ctx) {
|
||||||
set_canvas_cursor (which_track_cursor ());
|
_enter_cursor_ctx->change(which_track_cursor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3689,14 +3689,13 @@ Editor::freeze_route ()
|
||||||
|
|
||||||
pthread_create_and_store (X_("freezer"), &itt.thread, _freeze_thread, this);
|
pthread_create_and_store (X_("freezer"), &itt.thread, _freeze_thread, this);
|
||||||
|
|
||||||
set_canvas_cursor (_cursors->wait);
|
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||||
|
|
||||||
while (!itt.done && !itt.cancel) {
|
while (!itt.done && !itt.cancel) {
|
||||||
gtk_main_iteration ();
|
gtk_main_iteration ();
|
||||||
}
|
}
|
||||||
|
|
||||||
current_interthread_info = 0;
|
current_interthread_info = 0;
|
||||||
set_canvas_cursor (current_canvas_cursor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -4734,7 +4733,7 @@ Editor::normalize_region ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_canvas_cursor (_cursors->wait);
|
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||||
gdk_flush ();
|
gdk_flush ();
|
||||||
|
|
||||||
/* XXX: should really only count audio regions here */
|
/* XXX: should really only count audio regions here */
|
||||||
|
|
@ -4753,7 +4752,6 @@ Editor::normalize_region ()
|
||||||
|
|
||||||
if (a == -1) {
|
if (a == -1) {
|
||||||
/* the user cancelled the operation */
|
/* the user cancelled the operation */
|
||||||
set_canvas_cursor (current_canvas_cursor);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4784,7 +4782,6 @@ Editor::normalize_region ()
|
||||||
}
|
}
|
||||||
|
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
set_canvas_cursor (current_canvas_cursor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4955,7 +4952,7 @@ Editor::fork_region ()
|
||||||
|
|
||||||
begin_reversible_command (_("Fork Region(s)"));
|
begin_reversible_command (_("Fork Region(s)"));
|
||||||
|
|
||||||
set_canvas_cursor (_cursors->wait);
|
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||||
gdk_flush ();
|
gdk_flush ();
|
||||||
|
|
||||||
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
|
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
|
||||||
|
|
@ -4982,8 +4979,6 @@ Editor::fork_region ()
|
||||||
}
|
}
|
||||||
|
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
|
|
||||||
set_canvas_cursor (current_canvas_cursor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -5102,7 +5097,7 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
|
||||||
|
|
||||||
begin_reversible_command (command);
|
begin_reversible_command (command);
|
||||||
|
|
||||||
set_canvas_cursor (_cursors->wait);
|
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||||
gdk_flush ();
|
gdk_flush ();
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
@ -5155,7 +5150,7 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
|
||||||
|
|
||||||
_session->add_command(new StatefulDiffCommand (playlist));
|
_session->add_command(new StatefulDiffCommand (playlist));
|
||||||
} else {
|
} else {
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress) {
|
if (progress) {
|
||||||
|
|
@ -5168,9 +5163,6 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
|
||||||
}
|
}
|
||||||
|
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
|
|
||||||
out:
|
|
||||||
set_canvas_cursor (current_canvas_cursor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,6 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
|
||||||
, _last_event_y (0)
|
, _last_event_y (0)
|
||||||
, _grabbed_keyboard (false)
|
, _grabbed_keyboard (false)
|
||||||
, _entered (false)
|
, _entered (false)
|
||||||
, pre_enter_cursor (0)
|
|
||||||
, pre_press_cursor (0)
|
|
||||||
, pre_note_enter_cursor (0)
|
|
||||||
, _note_player (0)
|
, _note_player (0)
|
||||||
{
|
{
|
||||||
CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
|
CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
|
||||||
|
|
@ -171,9 +168,6 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
|
||||||
, _last_event_y (0)
|
, _last_event_y (0)
|
||||||
, _grabbed_keyboard (false)
|
, _grabbed_keyboard (false)
|
||||||
, _entered (false)
|
, _entered (false)
|
||||||
, pre_enter_cursor (0)
|
|
||||||
, pre_press_cursor (0)
|
|
||||||
, pre_note_enter_cursor (0)
|
|
||||||
, _note_player (0)
|
, _note_player (0)
|
||||||
{
|
{
|
||||||
CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
|
CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
|
||||||
|
|
@ -225,9 +219,6 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
|
||||||
, _last_event_y (0)
|
, _last_event_y (0)
|
||||||
, _grabbed_keyboard (false)
|
, _grabbed_keyboard (false)
|
||||||
, _entered (false)
|
, _entered (false)
|
||||||
, pre_enter_cursor (0)
|
|
||||||
, pre_press_cursor (0)
|
|
||||||
, pre_note_enter_cursor (0)
|
|
||||||
, _note_player (0)
|
, _note_player (0)
|
||||||
{
|
{
|
||||||
init (false);
|
init (false);
|
||||||
|
|
@ -258,9 +249,6 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
|
||||||
, _last_event_y (0)
|
, _last_event_y (0)
|
||||||
, _grabbed_keyboard (false)
|
, _grabbed_keyboard (false)
|
||||||
, _entered (false)
|
, _entered (false)
|
||||||
, pre_enter_cursor (0)
|
|
||||||
, pre_press_cursor (0)
|
|
||||||
, pre_note_enter_cursor (0)
|
|
||||||
, _note_player (0)
|
, _note_player (0)
|
||||||
{
|
{
|
||||||
init (true);
|
init (true);
|
||||||
|
|
@ -427,6 +415,8 @@ bool
|
||||||
MidiRegionView::leave_notify (GdkEventCrossing*)
|
MidiRegionView::leave_notify (GdkEventCrossing*)
|
||||||
{
|
{
|
||||||
leave_internal();
|
leave_internal();
|
||||||
|
_note_cursor_ctx.reset();
|
||||||
|
_press_cursor_ctx.reset();
|
||||||
|
|
||||||
_entered = false;
|
_entered = false;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -487,8 +477,7 @@ MidiRegionView::button_press (GdkEventButton* ev)
|
||||||
MouseMode m = editor->current_mouse_mode();
|
MouseMode m = editor->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())) {
|
||||||
pre_press_cursor = editor->get_canvas_cursor ();
|
_press_cursor_ctx = CursorContext::create(*editor, editor->cursors()->midi_pencil);
|
||||||
editor->set_canvas_cursor (editor->cursors()->midi_pencil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_mouse_state != SelectTouchDragging) {
|
if (_mouse_state != SelectTouchDragging) {
|
||||||
|
|
@ -521,10 +510,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
|
||||||
|
|
||||||
PublicEditor& editor = trackview.editor ();
|
PublicEditor& editor = trackview.editor ();
|
||||||
|
|
||||||
if (pre_press_cursor) {
|
_press_cursor_ctx.reset();
|
||||||
dynamic_cast<Editor*>(&editor)->set_canvas_cursor (pre_press_cursor, false);
|
|
||||||
pre_press_cursor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (_mouse_state) {
|
switch (_mouse_state) {
|
||||||
case Pressed: // Clicked
|
case Pressed: // Clicked
|
||||||
|
|
@ -3154,13 +3140,14 @@ MidiRegionView::note_entered(NoteBase* ev)
|
||||||
{
|
{
|
||||||
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
|
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
|
||||||
|
|
||||||
pre_note_enter_cursor = editor->get_canvas_cursor ();
|
|
||||||
|
|
||||||
if (_mouse_state == SelectTouchDragging) {
|
if (_mouse_state == SelectTouchDragging) {
|
||||||
note_selected (ev, true);
|
note_selected (ev, true);
|
||||||
}
|
} else if (editor->current_mouse_mode() == MouseContent) {
|
||||||
|
CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->grabber_note);
|
||||||
show_verbose_cursor (ev->note ());
|
show_verbose_cursor (ev->note ());
|
||||||
|
} else if (editor->current_mouse_mode() == MouseDraw) {
|
||||||
|
show_verbose_cursor (ev->note ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -3174,10 +3161,7 @@ MidiRegionView::note_left (NoteBase*)
|
||||||
|
|
||||||
editor->verbose_cursor()->hide ();
|
editor->verbose_cursor()->hide ();
|
||||||
|
|
||||||
if (pre_note_enter_cursor) {
|
_note_cursor_ctx.reset();
|
||||||
editor->set_canvas_cursor (pre_note_enter_cursor);
|
|
||||||
pre_note_enter_cursor = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -3230,11 +3214,11 @@ MidiRegionView::note_mouse_position (float x_fraction, float /*y_fraction*/, boo
|
||||||
|
|
||||||
if (can_set_cursor) {
|
if (can_set_cursor) {
|
||||||
if (trimmable && x_fraction > 0.0 && x_fraction < 0.2) {
|
if (trimmable && x_fraction > 0.0 && x_fraction < 0.2) {
|
||||||
editor->set_canvas_cursor (editor->cursors()->left_side_trim);
|
CursorContext::set(&_note_cursor_ctx, *editor, editor->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) {
|
||||||
editor->set_canvas_cursor (editor->cursors()->right_side_trim);
|
CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->right_side_trim);
|
||||||
} else if (pre_note_enter_cursor) {
|
} else {
|
||||||
editor->set_canvas_cursor (pre_note_enter_cursor);
|
CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->grabber_note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ class EditNoteDialog;
|
||||||
class NotePlayer;
|
class NotePlayer;
|
||||||
class PatchChange;
|
class PatchChange;
|
||||||
class ItemCounts;
|
class ItemCounts;
|
||||||
|
class CursorContext;
|
||||||
|
|
||||||
class MidiRegionView : public RegionView
|
class MidiRegionView : public RegionView
|
||||||
{
|
{
|
||||||
|
|
@ -496,9 +497,8 @@ private:
|
||||||
|
|
||||||
PBD::ScopedConnection _mouse_mode_connection;
|
PBD::ScopedConnection _mouse_mode_connection;
|
||||||
|
|
||||||
Gdk::Cursor* pre_enter_cursor;
|
boost::shared_ptr<CursorContext> _note_cursor_ctx;
|
||||||
Gdk::Cursor* pre_press_cursor;
|
boost::shared_ptr<CursorContext> _press_cursor_ctx;
|
||||||
Gdk::Cursor* pre_note_enter_cursor;
|
|
||||||
|
|
||||||
NotePlayer* _note_player;
|
NotePlayer* _note_player;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ gtk2_ardour_sources = [
|
||||||
'configinfo.cc',
|
'configinfo.cc',
|
||||||
'control_point.cc',
|
'control_point.cc',
|
||||||
'control_point_dialog.cc',
|
'control_point_dialog.cc',
|
||||||
|
'cursor_context.cc',
|
||||||
'curvetest.cc',
|
'curvetest.cc',
|
||||||
'debug.cc',
|
'debug.cc',
|
||||||
'edit_note_dialog.cc',
|
'edit_note_dialog.cc',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue