Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
Paul Davis | 911f94ecaa | |
Paul Davis | b5c77a5c51 | |
Paul Davis | 518b7fa280 | |
Paul Davis | 6370ddc984 | |
Paul Davis | 7afea7ec2b | |
Paul Davis | afa5cb0d3d | |
Paul Davis | d8c9c1328c | |
Paul Davis | 10ccc140c8 | |
Paul Davis | d386028598 |
|
@ -275,8 +275,6 @@ public:
|
||||||
|
|
||||||
void reset_focus (Gtk::Widget*);
|
void reset_focus (Gtk::Widget*);
|
||||||
|
|
||||||
static PublicEditor* _instance;
|
|
||||||
|
|
||||||
/** Emitted frequently with the audible sample, false, and the edit point as
|
/** Emitted frequently with the audible sample, false, and the edit point as
|
||||||
* parameters respectively.
|
* parameters respectively.
|
||||||
*
|
*
|
||||||
|
|
|
@ -473,6 +473,7 @@ Editor::Editor ()
|
||||||
, quantize_dialog (0)
|
, quantize_dialog (0)
|
||||||
, _main_menu_disabler (0)
|
, _main_menu_disabler (0)
|
||||||
, domain_bounce_info (nullptr)
|
, domain_bounce_info (nullptr)
|
||||||
|
, track_drag (nullptr)
|
||||||
{
|
{
|
||||||
/* we are a singleton */
|
/* we are a singleton */
|
||||||
|
|
||||||
|
@ -4282,6 +4283,11 @@ Editor::override_visible_track_count ()
|
||||||
bool
|
bool
|
||||||
Editor::edit_controls_button_event (GdkEventButton* ev)
|
Editor::edit_controls_button_event (GdkEventButton* ev)
|
||||||
{
|
{
|
||||||
|
if (ev->type == GDK_BUTTON_RELEASE && track_dragging()) {
|
||||||
|
end_track_drag ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ev->type == GDK_2BUTTON_PRESS && ev->button == 1) || (ev->type == GDK_BUTTON_RELEASE && Keyboard::is_context_menu_event (ev))) {
|
if ((ev->type == GDK_2BUTTON_PRESS && ev->button == 1) || (ev->type == GDK_BUTTON_RELEASE && Keyboard::is_context_menu_event (ev))) {
|
||||||
ARDOUR_UI::instance()->add_route ();
|
ARDOUR_UI::instance()->add_route ();
|
||||||
} else if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS) {
|
} else if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS) {
|
||||||
|
@ -6170,6 +6176,67 @@ struct TrackViewStripableSorter
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const int track_drag_spacer_height = 25;
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::maybe_place_drag_spacer ()
|
||||||
|
{
|
||||||
|
/* Build a map of track<->visual order */
|
||||||
|
|
||||||
|
std::map<TimeAxisView*,int> visual_order;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
for (auto & tv : track_views) {
|
||||||
|
if (!tv->marked_for_display () || (tv == track_drag->track)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
visual_order[tv] = n;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & tv : track_views) {
|
||||||
|
|
||||||
|
if (!tv->marked_for_display () || (tv == track_drag->track)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the track the mouse pointer is within, and if
|
||||||
|
* we're in the upper or lower half of it (depending on
|
||||||
|
* drag direction, move the spacer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (track_drag->current >= tv->y_position() && track_drag->current < (tv->y_position() + tv->effective_height())) {
|
||||||
|
|
||||||
|
if (track_drag->bump_track == tv) {
|
||||||
|
/* already bumped for this track */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track_drag->direction < 0) {
|
||||||
|
|
||||||
|
/* dragging up */
|
||||||
|
|
||||||
|
if (track_drag->current < (tv->y_position() + (tv->effective_height() / 2))) {
|
||||||
|
/* in top half of this track, move spacer */
|
||||||
|
track_drag->spacer_order = visual_order[tv];
|
||||||
|
track_drag->bump_track = tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (track_drag->direction > 0) {
|
||||||
|
|
||||||
|
/* dragging down */
|
||||||
|
|
||||||
|
if (track_drag->current > (tv->y_position() + (tv->effective_height() / 2))) {
|
||||||
|
track_drag->spacer_order = visual_order[tv] + 1;
|
||||||
|
track_drag->bump_track = tv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Editor::redisplay_track_views ()
|
Editor::redisplay_track_views ()
|
||||||
{
|
{
|
||||||
|
@ -6186,24 +6253,56 @@ Editor::redisplay_track_views ()
|
||||||
|
|
||||||
track_views.sort (TrackViewStripableSorter ());
|
track_views.sort (TrackViewStripableSorter ());
|
||||||
|
|
||||||
uint32_t position;
|
if (track_drag && track_drag->spacer) {
|
||||||
TrackViewList::const_iterator i;
|
maybe_place_drag_spacer ();
|
||||||
|
}
|
||||||
|
|
||||||
/* n will be the count of tracks plus children (updated by TimeAxisView::show_at),
|
/* n will be the count of tracks plus children (updated by TimeAxisView::show_at),
|
||||||
* so we will use that to know where to put things.
|
* so we will use that to know where to put things.
|
||||||
*/
|
*/
|
||||||
int n;
|
int n = 0;
|
||||||
for (n = 0, position = 0, i = track_views.begin(); i != track_views.end(); ++i) {
|
uint32_t position = 0;
|
||||||
TimeAxisView *tv = (*i);
|
|
||||||
|
for (auto & tv : track_views) {
|
||||||
|
|
||||||
|
int xtra = 0;
|
||||||
|
|
||||||
if (tv->marked_for_display ()) {
|
if (tv->marked_for_display ()) {
|
||||||
position += tv->show_at (position, n, &edit_controls_vbox);
|
|
||||||
|
if (track_drag) {
|
||||||
|
|
||||||
|
if (tv == track_drag->track) {
|
||||||
|
tv->hide ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tv->stripable()->presentation_info().order() > track_drag->spacer_order) {
|
||||||
|
xtra = track_drag_spacer_height;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
position += tv->show_at (position + xtra, n, &edit_controls_vbox);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tv->hide ();
|
tv->hide ();
|
||||||
}
|
}
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (track_drag) {
|
||||||
|
|
||||||
|
if (!track_drag->spacer) {
|
||||||
|
track_drag->spacer = manage (new Gtk::EventBox);
|
||||||
|
track_drag->spacer->set_size_request (-1, track_drag_spacer_height);
|
||||||
|
track_drag->spacer->show ();
|
||||||
|
edit_controls_vbox.pack_start (*track_drag->spacer, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
edit_controls_vbox.reorder_child (*track_drag->spacer, track_drag->spacer_order);
|
||||||
|
}
|
||||||
|
|
||||||
reset_controls_layout_height (position);
|
reset_controls_layout_height (position);
|
||||||
reset_controls_layout_width ();
|
reset_controls_layout_width ();
|
||||||
_full_canvas_height = position;
|
_full_canvas_height = position;
|
||||||
|
@ -7002,3 +7101,105 @@ Editor::default_time_domain () const
|
||||||
}
|
}
|
||||||
return BeatTime;
|
return BeatTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::start_track_drag (TimeAxisView& tav, int y, Gtk::Widget& w)
|
||||||
|
{
|
||||||
|
/* Find the visual order of this track */
|
||||||
|
int nth = 0;
|
||||||
|
|
||||||
|
for (auto const & tv : track_views) {
|
||||||
|
if (!tv->marked_for_display()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tv == &tav) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++nth;
|
||||||
|
}
|
||||||
|
|
||||||
|
track_drag = new TrackDrag (dynamic_cast<RouteTimeAxisView*> (&tav));
|
||||||
|
|
||||||
|
/* Create a useful dragging cursor from the first track's name */
|
||||||
|
|
||||||
|
Pango::FontDescription fd (UIConfiguration::instance().get_LargerBoldFont());
|
||||||
|
Gtkmm2ext::Color c (UIConfiguration::instance().color ("midi meter color0"));
|
||||||
|
Gdk::Color color (Gtkmm2ext::gdk_color_from_rgb (c));
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gtkmm2ext::pixbuf_from_string (track_drag->track->route()->name(), fd, 0, 0, color);
|
||||||
|
|
||||||
|
track_drag->drag_cursor = gdk_cursor_new_from_pixbuf (gdk_display_get_default(), pixbuf->gobj(), 0, 0);
|
||||||
|
track_drag->predrag_cursor = gdk_window_get_cursor (edit_controls_vbox.get_window()->gobj());
|
||||||
|
|
||||||
|
gdk_window_set_cursor (edit_controls_vbox.get_toplevel()->get_window()->gobj(), track_drag->drag_cursor);
|
||||||
|
|
||||||
|
|
||||||
|
int xo, yo;
|
||||||
|
w.translate_coordinates (edit_controls_vbox, 0, y, xo, yo);
|
||||||
|
|
||||||
|
track_drag->have_predrag_cursor = true;
|
||||||
|
track_drag->bump_track = nullptr;
|
||||||
|
track_drag->spacer_order = nth;
|
||||||
|
track_drag->previous = yo;
|
||||||
|
track_drag->start = yo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::mid_track_drag (GdkEventMotion* ev, Gtk::Widget& w)
|
||||||
|
{
|
||||||
|
int xo, yo;
|
||||||
|
w.translate_coordinates (edit_controls_vbox, ev->x, ev->y, xo, yo);
|
||||||
|
|
||||||
|
track_drag->current = yo;
|
||||||
|
|
||||||
|
if (track_drag->current > track_drag->previous) {
|
||||||
|
if (track_drag->direction != 1) {
|
||||||
|
track_drag->bump_track = nullptr;
|
||||||
|
track_drag->direction = 1;
|
||||||
|
}
|
||||||
|
} else if (track_drag->current < track_drag->previous) {
|
||||||
|
if (track_drag->direction != -1) {
|
||||||
|
track_drag->bump_track = nullptr;
|
||||||
|
track_drag->direction = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track_drag->current == track_drag->previous) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
redisplay_track_views ();
|
||||||
|
track_drag->previous = yo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::end_track_drag ()
|
||||||
|
{
|
||||||
|
if (track_drag->have_predrag_cursor) {
|
||||||
|
gdk_window_set_cursor (edit_controls_vbox.get_window()->gobj(), track_drag->predrag_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (track_drag->spacer) {
|
||||||
|
edit_controls_vbox.remove (*track_drag->spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete track_drag;
|
||||||
|
track_drag = nullptr;
|
||||||
|
|
||||||
|
redisplay_track_views ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::get_layout_relative_coordinates (Gtk::Widget& src, int x, int y, int &xo, int &yo)
|
||||||
|
{
|
||||||
|
gtk_widget_translate_coordinates (src.gobj(), GTK_WIDGET (controls_layout.gobj()),
|
||||||
|
x, y, &xo, &yo);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Editor::track_dragging() const
|
||||||
|
{
|
||||||
|
return (bool) track_drag;
|
||||||
|
}
|
||||||
|
|
|
@ -1409,6 +1409,12 @@ private:
|
||||||
void insert_patch_change (bool from_context);
|
void insert_patch_change (bool from_context);
|
||||||
void fork_selected_regions ();
|
void fork_selected_regions ();
|
||||||
void fork_regions_from_unselected ();
|
void fork_regions_from_unselected ();
|
||||||
|
void start_track_drag (TimeAxisView&, int y, Gtk::Widget& w);
|
||||||
|
void mid_track_drag (GdkEventMotion*, Gtk::Widget& e);
|
||||||
|
void end_track_drag ();
|
||||||
|
void maybe_place_drag_spacer ();
|
||||||
|
void get_layout_relative_coordinates (Gtk::Widget&, int x, int y, int &xo, int &yo);
|
||||||
|
bool track_dragging() const;
|
||||||
|
|
||||||
void do_insert_time ();
|
void do_insert_time ();
|
||||||
void insert_time (Temporal::timepos_t const &, Temporal::timecnt_t const &, Editing::InsertTimeOption, bool, bool, bool, bool);
|
void insert_time (Temporal::timepos_t const &, Temporal::timecnt_t const &, Editing::InsertTimeOption, bool, bool, bool, bool);
|
||||||
|
@ -2593,6 +2599,37 @@ private:
|
||||||
friend class Drag;
|
friend class Drag;
|
||||||
friend class RegionCutDrag;
|
friend class RegionCutDrag;
|
||||||
friend class RegionDrag;
|
friend class RegionDrag;
|
||||||
|
|
||||||
|
struct TrackDrag {
|
||||||
|
RouteTimeAxisView* track;
|
||||||
|
Gtk::EventBox* spacer;
|
||||||
|
GdkCursor* drag_cursor;
|
||||||
|
GdkCursor* predrag_cursor;
|
||||||
|
TimeAxisView* bump_track;
|
||||||
|
int spacer_order;
|
||||||
|
double start;
|
||||||
|
double current;
|
||||||
|
double previous;
|
||||||
|
bool have_predrag_cursor;
|
||||||
|
int direction;
|
||||||
|
|
||||||
|
TrackDrag (RouteTimeAxisView* rtav)
|
||||||
|
: track (rtav)
|
||||||
|
, spacer (nullptr)
|
||||||
|
, drag_cursor (nullptr)
|
||||||
|
, predrag_cursor (nullptr)
|
||||||
|
, bump_track (nullptr)
|
||||||
|
, spacer_order (-1)
|
||||||
|
, start (-1.)
|
||||||
|
, current (0.)
|
||||||
|
, previous (0.)
|
||||||
|
, have_predrag_cursor (false)
|
||||||
|
, direction (0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};
|
||||||
|
TrackDrag* track_drag;
|
||||||
|
|
||||||
friend class RegionMoveDrag;
|
friend class RegionMoveDrag;
|
||||||
friend class TrimDrag;
|
friend class TrimDrag;
|
||||||
friend class MappingTwistDrag;
|
friend class MappingTwistDrag;
|
||||||
|
|
|
@ -588,6 +588,12 @@ public:
|
||||||
|
|
||||||
virtual void set_tempo_curve_range (double& max, double& min) const = 0;
|
virtual void set_tempo_curve_range (double& max, double& min) const = 0;
|
||||||
|
|
||||||
|
virtual void start_track_drag (TimeAxisView&, int y, Gtk::Widget&) = 0;
|
||||||
|
virtual void mid_track_drag (GdkEventMotion*, Gtk::Widget&) = 0;
|
||||||
|
virtual void end_track_drag () = 0;
|
||||||
|
virtual void get_layout_relative_coordinates (Gtk::Widget&, int x, int y, int &xo, int &yo) = 0;
|
||||||
|
virtual bool track_dragging() const = 0;
|
||||||
|
|
||||||
/// Singleton instance, set up by Editor::Editor()
|
/// Singleton instance, set up by Editor::Editor()
|
||||||
|
|
||||||
static PublicEditor* _instance;
|
static PublicEditor* _instance;
|
||||||
|
|
|
@ -438,7 +438,13 @@ TimeAxisView::controls_ebox_button_press (GdkEventButton* event)
|
||||||
_ebox_release_can_act = true;
|
_ebox_release_can_act = true;
|
||||||
|
|
||||||
if (maybe_set_cursor (event->y) > 0) {
|
if (maybe_set_cursor (event->y) > 0) {
|
||||||
|
|
||||||
_resize_drag_start = event->y_root;
|
_resize_drag_start = event->y_root;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (event->button == 1) {
|
||||||
|
_editor.start_track_drag (*this, event->y, controls_ebox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -453,6 +459,12 @@ TimeAxisView::idle_resize (int32_t h)
|
||||||
bool
|
bool
|
||||||
TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
|
TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
|
||||||
{
|
{
|
||||||
|
if (_editor.track_dragging()) {
|
||||||
|
_editor.mid_track_drag (ev, controls_ebox);
|
||||||
|
gdk_event_request_motions (ev);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_resize_drag_start >= 0) {
|
if (_resize_drag_start >= 0) {
|
||||||
|
|
||||||
/* (ab)use the DragManager to do autoscrolling - basically we
|
/* (ab)use the DragManager to do autoscrolling - basically we
|
||||||
|
@ -468,13 +480,15 @@ TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
|
||||||
_editor.add_to_idle_resize (this, delta);
|
_editor.add_to_idle_resize (this, delta);
|
||||||
_resize_drag_start = ev->y_root;
|
_resize_drag_start = ev->y_root;
|
||||||
_did_resize = true;
|
_did_resize = true;
|
||||||
|
gdk_event_request_motions (ev);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
/* not dragging but ... */
|
/* not dragging but ... */
|
||||||
maybe_set_cursor (ev->y);
|
maybe_set_cursor (ev->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_event_request_motions(ev);
|
gdk_event_request_motions (ev);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -518,6 +532,10 @@ TimeAxisView::maybe_set_cursor (int y)
|
||||||
bool
|
bool
|
||||||
TimeAxisView::controls_ebox_button_release (GdkEventButton* ev)
|
TimeAxisView::controls_ebox_button_release (GdkEventButton* ev)
|
||||||
{
|
{
|
||||||
|
if (_editor.track_dragging()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_resize_drag_start >= 0) {
|
if (_resize_drag_start >= 0) {
|
||||||
if (_have_preresize_cursor) {
|
if (_have_preresize_cursor) {
|
||||||
gdk_window_set_cursor (controls_ebox.get_window()->gobj(), _preresize_cursor);
|
gdk_window_set_cursor (controls_ebox.get_window()->gobj(), _preresize_cursor);
|
||||||
|
|
|
@ -194,10 +194,10 @@ Gtkmm2ext::pixbuf_from_string(const string& name, const Pango::FontDescription&
|
||||||
int width, height;
|
int width, height;
|
||||||
pixel_size (name, font, width, height);
|
pixel_size (name, font, width, height);
|
||||||
if (clip_width <= 0) {
|
if (clip_width <= 0) {
|
||||||
clip_width = width - clip_width;
|
clip_width = width - clip_width; /* this is an addition because clip_width is negative */
|
||||||
}
|
}
|
||||||
if (clip_height <= 0) {
|
if (clip_height <= 0) {
|
||||||
clip_height = height - clip_height;
|
clip_height = height - clip_height; /* this is an addition because clip_height is negative */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue