mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-16 03:36:32 +01:00
(1) remove almost-never used block/unlock_property_changes() methods from PBD::Stateful (2) hide used and path columns from region list (3) detect mouse position within MIDI notes and thus allow move or trim from the same mouse mode (object or trim; first & last 1/4 of each note is for trimming
git-svn-id: svn://localhost/ardour2/branches/3.0@7823 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
e6ecd36b26
commit
90e73a3a6d
14 changed files with 131 additions and 33 deletions
|
|
@ -488,7 +488,7 @@ AudioStreamView::setup_rec_box ()
|
|||
boost::dynamic_pointer_cast<AudioRegion>(RegionFactory::create (sources, plist, false)));
|
||||
|
||||
assert(region);
|
||||
region->block_property_changes ();
|
||||
region->suspend_property_changes ();
|
||||
region->set_position (_trackview.session()->transport_frame(), this);
|
||||
rec_regions.push_back (make_pair(region, (RegionView*) 0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ CanvasNoteEvent::CanvasNoteEvent(MidiRegionView& region, Item* item, const boost
|
|||
, _note(note)
|
||||
, _selected(false)
|
||||
, _valid (true)
|
||||
, _mouse_x_fraction (-1.0)
|
||||
, _mouse_y_fraction (-1.0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -223,6 +225,60 @@ CanvasNoteEvent::base_color()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasNoteEvent::set_mouse_fractions (GdkEvent* ev)
|
||||
{
|
||||
double ix, iy;
|
||||
double bx1, bx2, by1, by2;
|
||||
|
||||
switch (ev->type) {
|
||||
case GDK_MOTION_NOTIFY:
|
||||
ix = ev->motion.x;
|
||||
iy = ev->motion.y;
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
ix = ev->crossing.x;
|
||||
iy = ev->crossing.y;
|
||||
break;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
ix = ev->button.x;
|
||||
iy = ev->button.y;
|
||||
break;
|
||||
default:
|
||||
_mouse_x_fraction = -1.0;
|
||||
_mouse_y_fraction = -1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
_item->get_bounds (bx1, by1, bx2, by2);
|
||||
_item->w2i (ix, iy);
|
||||
/* hmm, something wrong here. w2i should give item-local coordinates
|
||||
but it doesn't. for now, finesse this.
|
||||
*/
|
||||
ix = ix - bx1;
|
||||
iy = iy - by1;
|
||||
|
||||
/* fraction of width/height */
|
||||
double xf;
|
||||
double yf;
|
||||
bool notify = false;
|
||||
|
||||
xf = ix / (bx2 - bx1);
|
||||
yf = iy / (by2 - by1);
|
||||
|
||||
if (xf != _mouse_x_fraction || yf != _mouse_y_fraction) {
|
||||
notify = true;
|
||||
}
|
||||
|
||||
_mouse_x_fraction = xf;
|
||||
_mouse_y_fraction = yf;
|
||||
|
||||
if (notify) {
|
||||
_region.note_mouse_position (_mouse_x_fraction, _mouse_y_fraction);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CanvasNoteEvent::on_event(GdkEvent* ev)
|
||||
{
|
||||
|
|
@ -232,22 +288,21 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
|
|||
|
||||
switch (ev->type) {
|
||||
case GDK_ENTER_NOTIFY:
|
||||
_region.note_entered(this);
|
||||
set_mouse_fractions (ev);
|
||||
_region.note_entered (this);
|
||||
break;
|
||||
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
set_mouse_fractions (ev);
|
||||
_region.note_left (this);
|
||||
break;
|
||||
|
||||
case GDK_MOTION_NOTIFY:
|
||||
double ix, iy;
|
||||
ix = ev->motion.x;
|
||||
iy = ev->motion.y;
|
||||
_item->w2i (ix, iy);
|
||||
cerr << "note motion at " << ix << ',' << iy << endl;
|
||||
set_mouse_fractions (ev);
|
||||
break;
|
||||
|
||||
case GDK_BUTTON_PRESS:
|
||||
set_mouse_fractions (ev);
|
||||
if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) {
|
||||
show_channel_selector();
|
||||
return true;
|
||||
|
|
@ -255,6 +310,7 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
|
|||
break;
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
set_mouse_fractions (ev);
|
||||
if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -267,6 +323,13 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CanvasNoteEvent::mouse_near_ends () const
|
||||
{
|
||||
return (_mouse_x_fraction >= 0.0 && _mouse_x_fraction < 0.25) ||
|
||||
(_mouse_x_fraction >= 0.75 && _mouse_x_fraction < 1.0);
|
||||
}
|
||||
|
||||
} // namespace Canvas
|
||||
} // namespace Gnome
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,9 @@ class CanvasNoteEvent : virtual public sigc::trackable
|
|||
/// hue circle divided into 16 equal-looking parts, courtesy Thorsten Wilms
|
||||
static const uint32_t midi_channel_colors[16];
|
||||
|
||||
protected:
|
||||
bool mouse_near_ends () const;
|
||||
|
||||
protected:
|
||||
enum State { None, Pressed, Dragging };
|
||||
|
||||
MidiRegionView& _region;
|
||||
|
|
@ -151,6 +153,10 @@ protected:
|
|||
bool _own_note;
|
||||
bool _selected;
|
||||
bool _valid;
|
||||
float _mouse_x_fraction;
|
||||
float _mouse_y_fraction;
|
||||
|
||||
void set_mouse_fractions (GdkEvent*);
|
||||
};
|
||||
|
||||
} // namespace Gnome
|
||||
|
|
|
|||
|
|
@ -476,6 +476,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
static Gdk::Cursor* timebar_cursor;
|
||||
static Gdk::Cursor* transparent_cursor;
|
||||
|
||||
Gdk::Cursor* get_canvas_cursor () const { return current_canvas_cursor; }
|
||||
void set_canvas_cursor (Gdk::Cursor*);
|
||||
|
||||
protected:
|
||||
void map_transport_state ();
|
||||
void map_position_change (framepos_t);
|
||||
|
|
@ -686,8 +689,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
Gtk::VBox vpacker;
|
||||
|
||||
Gdk::Cursor* current_canvas_cursor;
|
||||
void set_canvas_cursor ();
|
||||
Gdk::Cursor* which_grabber_cursor ();
|
||||
void set_canvas_cursor ();
|
||||
|
||||
ArdourCanvas::Canvas* track_canvas;
|
||||
|
||||
|
|
|
|||
|
|
@ -917,6 +917,14 @@ Editor::horizontal_position () const
|
|||
{
|
||||
return frame_to_unit (leftmost_frame);
|
||||
}
|
||||
void
|
||||
Editor::set_canvas_cursor (Gdk::Cursor* cursor)
|
||||
{
|
||||
if (is_drawable()) {
|
||||
track_canvas->get_window()->set_cursor(*cursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::track_canvas_key_press (GdkEventKey* event)
|
||||
|
|
|
|||
|
|
@ -3769,7 +3769,7 @@ NoteDrag::finished (GdkEvent* ev, bool moved)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_region->note_dropped (_primary, total_dx(), - total_dy());
|
||||
_region->note_dropped (_primary, total_dx(), total_dy());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "ardour_ui.h"
|
||||
#include "actions.h"
|
||||
#include "canvas-note.h"
|
||||
#include "editor.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
|
|
@ -677,14 +678,16 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
case NoteItem:
|
||||
if (internal_editing()) {
|
||||
/* trim notes if we're in internal edit mode and near the ends of the note */
|
||||
_drags->set (new NoteResizeDrag (this, item), event);
|
||||
ArdourCanvas::CanvasNote* cn = dynamic_cast<ArdourCanvas::CanvasNote*> (item);
|
||||
if (cn->mouse_near_ends()) {
|
||||
_drags->set (new NoteResizeDrag (this, item), event);
|
||||
} else {
|
||||
_drags->set (new NoteDrag (this, item), event);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case StreamItem:
|
||||
cerr << "press on stream item, internal? " << internal_editing() << " MIDI ? "
|
||||
<< dynamic_cast<MidiTimeAxisView*>(clicked_axisview)
|
||||
<< endl;
|
||||
if (internal_editing()) {
|
||||
if (dynamic_cast<MidiTimeAxisView*> (clicked_axisview)) {
|
||||
_drags->set (new RegionCreateDrag (this, item, clicked_axisview), event);
|
||||
|
|
@ -718,7 +721,12 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||
switch (item_type) {
|
||||
case NoteItem:
|
||||
if (internal_editing()) {
|
||||
_drags->set (new NoteDrag (this, item), event);
|
||||
ArdourCanvas::CanvasNote* cn = dynamic_cast<ArdourCanvas::CanvasNote*> (item);
|
||||
if (cn->mouse_near_ends()) {
|
||||
_drags->set (new NoteResizeDrag (this, item), event);
|
||||
} else {
|
||||
_drags->set (new NoteDrag (this, item), event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ EditorRegions::EditorRegions (Editor* e)
|
|||
_display.append_column (_("G"), _columns.glued);
|
||||
_display.append_column (_("M"), _columns.muted);
|
||||
_display.append_column (_("O"), _columns.opaque);
|
||||
_display.append_column (_("Used"), _columns.used);
|
||||
_display.append_column (_("Path"), _columns.path);
|
||||
// _display.append_column (_("Used"), _columns.used);
|
||||
// _display.append_column (_("Path"), _columns.path);
|
||||
_display.set_headers_visible (true);
|
||||
//_display.set_grid_lines (TREE_VIEW_GRID_LINES_BOTH);
|
||||
|
||||
|
|
@ -461,10 +461,6 @@ EditorRegions::selection_changed ()
|
|||
// they could have clicked on a row that is just a placeholder, like "Hidden"
|
||||
if (region) {
|
||||
|
||||
cerr << "Selected region has use count "
|
||||
<< _session->playlists->region_use_count (region)
|
||||
<< endl;
|
||||
|
||||
if (region->automatic()) {
|
||||
|
||||
_display.get_selection()->unselect(*i);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "canvas-hit.h"
|
||||
#include "canvas-note.h"
|
||||
#include "canvas-program-change.h"
|
||||
#include "editor.h"
|
||||
#include "ghostregion.h"
|
||||
#include "gui_thread.h"
|
||||
#include "keyboard.h"
|
||||
|
|
@ -2646,6 +2647,10 @@ MidiRegionView::change_channel(uint8_t channel)
|
|||
void
|
||||
MidiRegionView::note_entered(ArdourCanvas::CanvasNoteEvent* ev)
|
||||
{
|
||||
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
|
||||
|
||||
pre_enter_cursor = editor->get_canvas_cursor ();
|
||||
|
||||
if (_mouse_state == SelectTouchDragging) {
|
||||
note_selected (ev, true);
|
||||
}
|
||||
|
|
@ -2656,17 +2661,28 @@ MidiRegionView::note_entered(ArdourCanvas::CanvasNoteEvent* ev)
|
|||
void
|
||||
MidiRegionView::note_left (ArdourCanvas::CanvasNoteEvent* note)
|
||||
{
|
||||
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
|
||||
|
||||
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
|
||||
(*i)->hide_velocity ();
|
||||
}
|
||||
|
||||
trackview.editor().hide_verbose_canvas_cursor ();
|
||||
editor->hide_verbose_canvas_cursor ();
|
||||
editor->set_canvas_cursor (pre_enter_cursor);
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::note_motion (float fraction)
|
||||
MidiRegionView::note_mouse_position (float x_fraction, float y_fraction)
|
||||
{
|
||||
cerr << "Now at " << fraction << " within note\n";
|
||||
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
|
||||
|
||||
if (x_fraction > 0.0 && x_fraction < 0.25) {
|
||||
editor->set_canvas_cursor (editor->left_side_trim_cursor);
|
||||
} else if (x_fraction >= 0.75 && x_fraction < 1.0) {
|
||||
editor->set_canvas_cursor (editor->right_side_trim_cursor);
|
||||
} else {
|
||||
editor->set_canvas_cursor (pre_enter_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -190,9 +190,11 @@ class MidiRegionView : public RegionView
|
|||
void apply_diff_as_subcommand();
|
||||
void abort_command();
|
||||
|
||||
Gdk::Cursor* pre_enter_cursor;
|
||||
|
||||
void note_entered(ArdourCanvas::CanvasNoteEvent* ev);
|
||||
void note_left(ArdourCanvas::CanvasNoteEvent* ev);
|
||||
void note_motion (float fraction);
|
||||
void note_mouse_position (float xfraction, float yfraction);
|
||||
void unique_select(ArdourCanvas::CanvasNoteEvent* ev);
|
||||
void note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add, bool extend=false);
|
||||
void note_deselected(ArdourCanvas::CanvasNoteEvent* ev);
|
||||
|
|
@ -432,7 +434,6 @@ class MidiRegionView : public RegionView
|
|||
void get_events (Events& e, Evoral::Sequence<Evoral::MusicalTime>::NoteOperator op, uint8_t val, int chan_mask = 0);
|
||||
|
||||
void display_program_changes_on_channel (uint8_t);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ MidiStreamView::setup_rec_box ()
|
|||
(RegionFactory::create (sources, plist, false)));
|
||||
|
||||
assert(region);
|
||||
region->block_property_changes ();
|
||||
region->suspend_property_changes ();
|
||||
region->set_position (_trackview.session()->transport_frame(), this);
|
||||
rec_regions.push_back (make_pair(region, (RegionView*)0));
|
||||
|
||||
|
|
|
|||
|
|
@ -1310,7 +1310,7 @@ Region::send_change (const PropertyChange& what_changed)
|
|||
|
||||
Stateful::send_change (what_changed);
|
||||
|
||||
if (!_no_property_changes) {
|
||||
if (!Stateful::frozen()) {
|
||||
|
||||
/* Try and send a shared_pointer unless this is part of the constructor.
|
||||
If so, do nothing.
|
||||
|
|
|
|||
|
|
@ -86,10 +86,9 @@ class Stateful {
|
|||
|
||||
virtual void suspend_property_changes ();
|
||||
virtual void resume_property_changes ();
|
||||
|
||||
virtual bool frozen() const { return _frozen; }
|
||||
|
||||
void unlock_property_changes () { _no_property_changes = false; }
|
||||
void block_property_changes () { _no_property_changes = true; }
|
||||
|
||||
protected:
|
||||
|
||||
void add_instant_xml (XMLNode&, const sys::path& directory_path);
|
||||
|
|
@ -108,7 +107,6 @@ class Stateful {
|
|||
XMLNode *_instant_xml;
|
||||
PBD::ID _id;
|
||||
int32_t _frozen;
|
||||
bool _no_property_changes;
|
||||
PBD::PropertyChange _pending_changed;
|
||||
Glib::Mutex _lock;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ int Stateful::loading_state_version = 0;
|
|||
|
||||
Stateful::Stateful ()
|
||||
: _frozen (0)
|
||||
, _no_property_changes (false)
|
||||
, _properties (new OwnedPropertyList)
|
||||
{
|
||||
_extra_xml = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue