mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 23:35:03 +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_control_point = 0;
|
||||
last_update_frame = 0;
|
||||
pre_press_cursor = 0;
|
||||
last_paste_pos = 0;
|
||||
paste_count = 0;
|
||||
_drags = new DragManager (this);
|
||||
|
|
@ -374,6 +373,7 @@ Editor::Editor ()
|
|||
current_stepping_trackview = 0;
|
||||
entered_track = 0;
|
||||
entered_regionview = 0;
|
||||
_entered_item_type = NoItem;
|
||||
entered_marker = 0;
|
||||
clear_entered_track = false;
|
||||
current_timefx = 0;
|
||||
|
|
@ -400,7 +400,6 @@ Editor::Editor ()
|
|||
|
||||
zoom_focus = ZoomFocusLeft;
|
||||
_edit_point = EditAtMouse;
|
||||
current_canvas_cursor = 0;
|
||||
_visible_track_count = -1;
|
||||
|
||||
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());
|
||||
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::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);
|
||||
}
|
||||
|
||||
reset_canvas_cursor ();
|
||||
if (_entered_item_type != NoItem) {
|
||||
choose_canvas_cursor_on_entry (_entered_item_type);
|
||||
}
|
||||
|
||||
if (!force && !changed) {
|
||||
return;
|
||||
|
|
@ -5744,9 +5748,10 @@ Editor::ui_parameter_changed (string parameter)
|
|||
{
|
||||
if (parameter == "icon-set") {
|
||||
while (!_cursor_stack.empty()) {
|
||||
_cursor_stack.pop();
|
||||
_cursor_stack.pop_back();
|
||||
}
|
||||
_cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
|
||||
_cursor_stack.push_back(_cursors->grabber);
|
||||
} else if (parameter == "draggable-playhead") {
|
||||
if (_verbose_cursor) {
|
||||
playhead_cursor->set_sensitive (ARDOUR_UI::config()->get_draggable_playhead());
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@
|
|||
#ifndef __ardour_editor_h__
|
||||
#define __ardour_editor_h__
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <sys/time.h>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ class AutomationTimeAxisView;
|
|||
class BundleManager;
|
||||
class ButtonJoiner;
|
||||
class ControlPoint;
|
||||
class CursorContext;
|
||||
class DragManager;
|
||||
class EditNoteDialog;
|
||||
class EditorCursor;
|
||||
|
|
@ -439,11 +441,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
void maybe_autoscroll (bool, bool, bool);
|
||||
bool autoscroll_active() const;
|
||||
|
||||
Gdk::Cursor* get_canvas_cursor () const { return current_canvas_cursor; }
|
||||
void set_canvas_cursor (Gdk::Cursor*, bool save=false);
|
||||
|
||||
void push_canvas_cursor (Gdk::Cursor*);
|
||||
void pop_canvas_cursor ();
|
||||
Gdk::Cursor* get_canvas_cursor () const;
|
||||
|
||||
void set_current_trimmable (boost::shared_ptr<ARDOUR::Trimmable>);
|
||||
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 vpacker;
|
||||
|
||||
std::stack<Gdk::Cursor*> _cursor_stack;
|
||||
Gdk::Cursor* current_canvas_cursor;
|
||||
/* Cursor stuff. Do not use directly, use via CursorContext. */
|
||||
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_track_cursor () const;
|
||||
Gdk::Cursor* which_mode_cursor () const;
|
||||
Gdk::Cursor* which_trim_cursor (bool left_side) const;
|
||||
bool reset_canvas_cursor ();
|
||||
void choose_canvas_cursor_on_entry (GdkEventCrossing*, ItemType);
|
||||
void choose_canvas_cursor_on_entry (ItemType);
|
||||
|
||||
ArdourCanvas::GtkCanvas* _track_canvas;
|
||||
ArdourCanvas::GtkCanvasViewport* _track_canvas_viewport;
|
||||
|
|
@ -1095,7 +1097,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
framepos_t cut_buffer_start;
|
||||
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::Movable> _movable;
|
||||
|
||||
|
|
@ -1978,6 +1982,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
*/
|
||||
RegionView* entered_regionview;
|
||||
|
||||
ItemType _entered_item_type;
|
||||
|
||||
bool clear_entered_track;
|
||||
bool left_track_canvas (GdkEventCrossing*);
|
||||
bool entered_track_canvas (GdkEventCrossing*);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "pbd/memento_command.h"
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "cursor_context.h"
|
||||
#include "editor.h"
|
||||
#include "sfdb_ui.h"
|
||||
#include "editing.h"
|
||||
|
|
@ -475,7 +476,7 @@ Editor::import_sndfiles (vector<string> paths, ImportDisposition disposition, Im
|
|||
import_status.track = track;
|
||||
import_status.replace = replace;
|
||||
|
||||
set_canvas_cursor (_cursors->wait);
|
||||
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||
gdk_flush ();
|
||||
|
||||
/* 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();
|
||||
set_canvas_cursor (current_canvas_cursor);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -526,9 +526,8 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
|||
SourceList sources;
|
||||
string linked_path;
|
||||
SoundFileInfo finfo;
|
||||
int ret = 0;
|
||||
|
||||
push_canvas_cursor (_cursors->wait);
|
||||
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||
gdk_flush ();
|
||||
|
||||
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)) {
|
||||
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())) {
|
||||
|
|
@ -562,19 +561,16 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
|||
|
||||
switch (resx) {
|
||||
case 0: /* stop a multi-file import */
|
||||
ret = -2;
|
||||
goto out;
|
||||
return -2;
|
||||
case 1: /* don't embed this one */
|
||||
ret = -1;
|
||||
goto out;
|
||||
return -1;
|
||||
case 2: /* do it, and the rest without asking */
|
||||
check_sample_rate = false;
|
||||
break;
|
||||
case 3: /* do it */
|
||||
break;
|
||||
default:
|
||||
ret = -2;
|
||||
goto out;
|
||||
return -2;
|
||||
}
|
||||
} else {
|
||||
choices.push_back (_("Cancel"));
|
||||
|
|
@ -590,13 +586,11 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
|||
|
||||
switch (resx) {
|
||||
case 0: /* don't import */
|
||||
ret = -1;
|
||||
goto out;
|
||||
return -1;
|
||||
case 1: /* do it */
|
||||
break;
|
||||
default:
|
||||
ret = -2;
|
||||
goto out;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -627,23 +621,18 @@ Editor::embed_sndfiles (vector<string> paths, bool multifile,
|
|||
|
||||
catch (failed_constructor& err) {
|
||||
error << string_compose(_("could not open %1"), path) << endmsg;
|
||||
goto out;
|
||||
return -3;
|
||||
}
|
||||
|
||||
gtk_main_iteration();
|
||||
}
|
||||
}
|
||||
|
||||
if (sources.empty()) {
|
||||
goto out;
|
||||
if (!sources.empty()) {
|
||||
return add_sources (paths, sources, pos, disposition, mode, target_regions, target_tracks, track, true);
|
||||
}
|
||||
|
||||
|
||||
ret = add_sources (paths, sources, pos, disposition, mode, target_regions, target_tracks, track, true);
|
||||
|
||||
out:
|
||||
pop_canvas_cursor ();
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "ardour/rc_configuration.h"
|
||||
#include "ardour/smf_source.h"
|
||||
|
||||
#include "pbd/error.h"
|
||||
|
||||
#include "canvas/canvas.h"
|
||||
#include "canvas/rectangle.h"
|
||||
#include "canvas/pixbuf.h"
|
||||
|
|
@ -367,8 +369,10 @@ Editor::reset_controls_layout_height (int32_t h)
|
|||
bool
|
||||
Editor::track_canvas_map_handler (GdkEventAny* /*ev*/)
|
||||
{
|
||||
if (current_canvas_cursor) {
|
||||
set_canvas_cursor (current_canvas_cursor);
|
||||
if (!_cursor_stack.empty()) {
|
||||
set_canvas_cursor (get_canvas_cursor());
|
||||
} else {
|
||||
PBD::error << "cursor stack is empty" << endmsg;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -985,13 +989,16 @@ Editor::get_track_canvas() const
|
|||
return _track_canvas_viewport;
|
||||
}
|
||||
|
||||
void
|
||||
Editor::set_canvas_cursor (Gdk::Cursor* cursor, bool save)
|
||||
Gdk::Cursor*
|
||||
Editor::get_canvas_cursor () const
|
||||
{
|
||||
if (save) {
|
||||
current_canvas_cursor = cursor;
|
||||
}
|
||||
/* 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 && cursor) {
|
||||
|
|
@ -999,22 +1006,32 @@ Editor::set_canvas_cursor (Gdk::Cursor* cursor, bool save)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
size_t
|
||||
Editor::push_canvas_cursor (Gdk::Cursor* cursor)
|
||||
{
|
||||
if (cursor) {
|
||||
_cursor_stack.push (cursor);
|
||||
set_canvas_cursor (cursor, false);
|
||||
_cursor_stack.push_back (cursor);
|
||||
set_canvas_cursor (cursor);
|
||||
}
|
||||
return _cursor_stack.size() - 1;
|
||||
}
|
||||
|
||||
void
|
||||
Editor::pop_canvas_cursor ()
|
||||
{
|
||||
if (!_cursor_stack.empty()) {
|
||||
Gdk::Cursor* cursor = _cursor_stack.top ();
|
||||
_cursor_stack.pop ();
|
||||
set_canvas_cursor (cursor, false);
|
||||
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. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1147,29 +1164,8 @@ Editor::which_track_cursor () const
|
|||
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
|
||||
Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType type)
|
||||
Editor::choose_canvas_cursor_on_entry (ItemType type)
|
||||
{
|
||||
Gdk::Cursor* cursor = 0;
|
||||
|
||||
|
|
@ -1179,7 +1175,8 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
|
|||
|
||||
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 */
|
||||
|
||||
|
|
@ -1238,9 +1235,6 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
|
|||
case FadeOutTrimHandleItem:
|
||||
cursor = _cursors->fade_out;
|
||||
break;
|
||||
case NoteItem:
|
||||
cursor = which_grabber_cursor();
|
||||
break;
|
||||
case FeatureLineItem:
|
||||
cursor = _cursors->cross_hair;
|
||||
break;
|
||||
|
|
@ -1313,7 +1307,8 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
|
|||
}
|
||||
|
||||
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 {
|
||||
/* CAIROCANVAS need a variant here that passes *cursor */
|
||||
_item->grab ();
|
||||
_editor->push_canvas_cursor (cursor);
|
||||
_cursor_ctx = CursorContext::create(*_editor, cursor);
|
||||
}
|
||||
|
||||
if (_editor->session() && _editor->session()->transport_rolling()) {
|
||||
|
|
@ -311,7 +311,7 @@ Drag::end_grab (GdkEvent* event)
|
|||
finished (event, _move_threshold_passed);
|
||||
|
||||
_editor->verbose_cursor()->hide ();
|
||||
_editor->pop_canvas_cursor ();
|
||||
_cursor_ctx.reset();
|
||||
|
||||
return _move_threshold_passed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "ardour/types.h"
|
||||
|
||||
#include "cursor_context.h"
|
||||
#include "editor_items.h"
|
||||
|
||||
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 _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
|
||||
CursorContext::Handle _cursor_ctx; ///< cursor change context
|
||||
};
|
||||
|
||||
class RegionDrag;
|
||||
|
|
|
|||
|
|
@ -705,7 +705,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
case RegionViewName:
|
||||
case StreamItem:
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -719,7 +719,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
/* Existing note: allow trimming/motion */
|
||||
if ((note = reinterpret_cast<NoteBase*> (item->get_data ("notebase")))) {
|
||||
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 {
|
||||
_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->big_enough_to_trim() && note->mouse_near_ends()) {
|
||||
/* 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 {
|
||||
/* Drag note */
|
||||
_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 */
|
||||
if ((note = reinterpret_cast<NoteBase*>(item->get_data ("notebase")))) {
|
||||
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;
|
||||
|
|
@ -976,12 +976,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
break;
|
||||
|
||||
case MouseAudition:
|
||||
_drags->set (new ScrubDrag (this, item), event);
|
||||
_drags->set (new ScrubDrag (this, item), event, _cursors->transparent);
|
||||
scrub_reversals = 0;
|
||||
scrub_reverse_distance = 0;
|
||||
last_scrub_x = event->button.x;
|
||||
scrubbing_direction = 0;
|
||||
push_canvas_cursor (_cursors->transparent);
|
||||
return true;
|
||||
break;
|
||||
|
||||
|
|
@ -1068,8 +1067,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
|||
return false;
|
||||
}
|
||||
|
||||
pre_press_cursor = current_canvas_cursor;
|
||||
|
||||
_track_canvas->grab_focus();
|
||||
|
||||
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);
|
||||
AutomationTimeAxisView* atv = 0;
|
||||
|
||||
if (pre_press_cursor) {
|
||||
set_canvas_cursor (pre_press_cursor);
|
||||
pre_press_cursor = 0;
|
||||
}
|
||||
_press_cursor_ctx.reset();
|
||||
|
||||
/* no action if we're recording */
|
||||
|
||||
|
|
@ -1441,7 +1435,6 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
break;
|
||||
|
||||
case MouseAudition:
|
||||
pop_canvas_cursor ();
|
||||
if (scrubbing_direction == 0) {
|
||||
/* no drag, just a click */
|
||||
switch (item_type) {
|
||||
|
|
@ -1529,7 +1522,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
|||
* (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) {
|
||||
case ControlPointItem:
|
||||
|
|
@ -1649,7 +1642,8 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
|
|||
bool is_start;
|
||||
bool ret = true;
|
||||
|
||||
reset_canvas_cursor ();
|
||||
_enter_cursor_ctx.reset();
|
||||
_entered_item_type = NoItem;
|
||||
|
||||
switch (item_type) {
|
||||
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;
|
||||
|
||||
if (_join_object_range_state != old) {
|
||||
set_canvas_cursor (which_track_cursor ());
|
||||
if (_join_object_range_state != old && _enter_cursor_ctx) {
|
||||
_enter_cursor_ctx->change(which_track_cursor());
|
||||
}
|
||||
|
||||
} else if (entered_track) {
|
||||
|
|
@ -2354,8 +2348,8 @@ Editor::update_join_object_range_location (double y)
|
|||
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
|
||||
}
|
||||
|
||||
if (_join_object_range_state != old) {
|
||||
set_canvas_cursor (which_track_cursor ());
|
||||
if (_join_object_range_state != old && _enter_cursor_ctx) {
|
||||
_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);
|
||||
|
||||
set_canvas_cursor (_cursors->wait);
|
||||
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||
|
||||
while (!itt.done && !itt.cancel) {
|
||||
gtk_main_iteration ();
|
||||
}
|
||||
|
||||
current_interthread_info = 0;
|
||||
set_canvas_cursor (current_canvas_cursor);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4734,7 +4733,7 @@ Editor::normalize_region ()
|
|||
return;
|
||||
}
|
||||
|
||||
set_canvas_cursor (_cursors->wait);
|
||||
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||
gdk_flush ();
|
||||
|
||||
/* XXX: should really only count audio regions here */
|
||||
|
|
@ -4753,7 +4752,6 @@ Editor::normalize_region ()
|
|||
|
||||
if (a == -1) {
|
||||
/* the user cancelled the operation */
|
||||
set_canvas_cursor (current_canvas_cursor);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4784,7 +4782,6 @@ Editor::normalize_region ()
|
|||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
set_canvas_cursor (current_canvas_cursor);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4955,7 +4952,7 @@ Editor::fork_region ()
|
|||
|
||||
begin_reversible_command (_("Fork Region(s)"));
|
||||
|
||||
set_canvas_cursor (_cursors->wait);
|
||||
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||
gdk_flush ();
|
||||
|
||||
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
|
||||
|
|
@ -4982,8 +4979,6 @@ Editor::fork_region ()
|
|||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
||||
set_canvas_cursor (current_canvas_cursor);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -5102,7 +5097,7 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
|
|||
|
||||
begin_reversible_command (command);
|
||||
|
||||
set_canvas_cursor (_cursors->wait);
|
||||
CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
|
||||
gdk_flush ();
|
||||
|
||||
int n = 0;
|
||||
|
|
@ -5155,7 +5150,7 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
|
|||
|
||||
_session->add_command(new StatefulDiffCommand (playlist));
|
||||
} else {
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
if (progress) {
|
||||
|
|
@ -5168,9 +5163,6 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
|
|||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
|
||||
out:
|
||||
set_canvas_cursor (current_canvas_cursor);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -122,9 +122,6 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
|
|||
, _last_event_y (0)
|
||||
, _grabbed_keyboard (false)
|
||||
, _entered (false)
|
||||
, pre_enter_cursor (0)
|
||||
, pre_press_cursor (0)
|
||||
, pre_note_enter_cursor (0)
|
||||
, _note_player (0)
|
||||
{
|
||||
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)
|
||||
, _grabbed_keyboard (false)
|
||||
, _entered (false)
|
||||
, pre_enter_cursor (0)
|
||||
, pre_press_cursor (0)
|
||||
, pre_note_enter_cursor (0)
|
||||
, _note_player (0)
|
||||
{
|
||||
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)
|
||||
, _grabbed_keyboard (false)
|
||||
, _entered (false)
|
||||
, pre_enter_cursor (0)
|
||||
, pre_press_cursor (0)
|
||||
, pre_note_enter_cursor (0)
|
||||
, _note_player (0)
|
||||
{
|
||||
init (false);
|
||||
|
|
@ -258,9 +249,6 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
|
|||
, _last_event_y (0)
|
||||
, _grabbed_keyboard (false)
|
||||
, _entered (false)
|
||||
, pre_enter_cursor (0)
|
||||
, pre_press_cursor (0)
|
||||
, pre_note_enter_cursor (0)
|
||||
, _note_player (0)
|
||||
{
|
||||
init (true);
|
||||
|
|
@ -427,6 +415,8 @@ bool
|
|||
MidiRegionView::leave_notify (GdkEventCrossing*)
|
||||
{
|
||||
leave_internal();
|
||||
_note_cursor_ctx.reset();
|
||||
_press_cursor_ctx.reset();
|
||||
|
||||
_entered = false;
|
||||
return false;
|
||||
|
|
@ -487,8 +477,7 @@ MidiRegionView::button_press (GdkEventButton* ev)
|
|||
MouseMode m = editor->current_mouse_mode();
|
||||
|
||||
if (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
|
||||
pre_press_cursor = editor->get_canvas_cursor ();
|
||||
editor->set_canvas_cursor (editor->cursors()->midi_pencil);
|
||||
_press_cursor_ctx = CursorContext::create(*editor, editor->cursors()->midi_pencil);
|
||||
}
|
||||
|
||||
if (_mouse_state != SelectTouchDragging) {
|
||||
|
|
@ -521,10 +510,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
|
|||
|
||||
PublicEditor& editor = trackview.editor ();
|
||||
|
||||
if (pre_press_cursor) {
|
||||
dynamic_cast<Editor*>(&editor)->set_canvas_cursor (pre_press_cursor, false);
|
||||
pre_press_cursor = 0;
|
||||
}
|
||||
_press_cursor_ctx.reset();
|
||||
|
||||
switch (_mouse_state) {
|
||||
case Pressed: // Clicked
|
||||
|
|
@ -3154,13 +3140,14 @@ MidiRegionView::note_entered(NoteBase* ev)
|
|||
{
|
||||
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
|
||||
|
||||
pre_note_enter_cursor = editor->get_canvas_cursor ();
|
||||
|
||||
if (_mouse_state == SelectTouchDragging) {
|
||||
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 ());
|
||||
} else if (editor->current_mouse_mode() == MouseDraw) {
|
||||
show_verbose_cursor (ev->note ());
|
||||
}
|
||||
|
||||
show_verbose_cursor (ev->note ());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3174,10 +3161,7 @@ MidiRegionView::note_left (NoteBase*)
|
|||
|
||||
editor->verbose_cursor()->hide ();
|
||||
|
||||
if (pre_note_enter_cursor) {
|
||||
editor->set_canvas_cursor (pre_note_enter_cursor);
|
||||
pre_note_enter_cursor = 0;
|
||||
}
|
||||
_note_cursor_ctx.reset();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3230,11 +3214,11 @@ MidiRegionView::note_mouse_position (float x_fraction, float /*y_fraction*/, boo
|
|||
|
||||
if (can_set_cursor) {
|
||||
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) {
|
||||
editor->set_canvas_cursor (editor->cursors()->right_side_trim);
|
||||
} else if (pre_note_enter_cursor) {
|
||||
editor->set_canvas_cursor (pre_note_enter_cursor);
|
||||
CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->right_side_trim);
|
||||
} else {
|
||||
CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->grabber_note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ class EditNoteDialog;
|
|||
class NotePlayer;
|
||||
class PatchChange;
|
||||
class ItemCounts;
|
||||
class CursorContext;
|
||||
|
||||
class MidiRegionView : public RegionView
|
||||
{
|
||||
|
|
@ -496,9 +497,8 @@ private:
|
|||
|
||||
PBD::ScopedConnection _mouse_mode_connection;
|
||||
|
||||
Gdk::Cursor* pre_enter_cursor;
|
||||
Gdk::Cursor* pre_press_cursor;
|
||||
Gdk::Cursor* pre_note_enter_cursor;
|
||||
boost::shared_ptr<CursorContext> _note_cursor_ctx;
|
||||
boost::shared_ptr<CursorContext> _press_cursor_ctx;
|
||||
|
||||
NotePlayer* _note_player;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ gtk2_ardour_sources = [
|
|||
'configinfo.cc',
|
||||
'control_point.cc',
|
||||
'control_point_dialog.cc',
|
||||
'cursor_context.cc',
|
||||
'curvetest.cc',
|
||||
'debug.cc',
|
||||
'edit_note_dialog.cc',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue