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));
}
, _note(note)
, _selected(false)
, _valid (true)
+ , _mouse_x_fraction (-1.0)
+ , _mouse_y_fraction (-1.0)
{
}
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)
{
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;
break;
case GDK_BUTTON_RELEASE:
+ set_mouse_fractions (ev);
if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) {
return true;
}
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
/// 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;
bool _own_note;
bool _selected;
bool _valid;
+ float _mouse_x_fraction;
+ float _mouse_y_fraction;
+
+ void set_mouse_fractions (GdkEvent*);
};
} // namespace Gnome
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);
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;
{
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)
}
}
} else {
- _region->note_dropped (_primary, total_dx(), - total_dy());
+ _region->note_dropped (_primary, total_dx(), total_dy());
}
}
#include "ardour_ui.h"
#include "actions.h"
+#include "canvas-note.h"
#include "editor.h"
#include "time_axis_view.h"
#include "audio_time_axis.h"
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);
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;
_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);
// 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);
#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"
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);
}
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
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);
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);
-
};
(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));
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.
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);
XMLNode *_instant_xml;
PBD::ID _id;
int32_t _frozen;
- bool _no_property_changes;
PBD::PropertyChange _pending_changed;
Glib::Mutex _lock;
Stateful::Stateful ()
: _frozen (0)
- , _no_property_changes (false)
, _properties (new OwnedPropertyList)
{
_extra_xml = 0;