#include <string>
#include <list>
-#include <libgnomecanvasmm.h>
-#include <libgnomecanvasmm/canvas.h>
-#include <libgnomecanvasmm/item.h>
#include "pbd/error.h"
#include "pbd/convert.h"
+#include "pbd/stacktrace.h"
#include <gtkmm2ext/doi.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/selector.h>
+#include "canvas/canvas.h"
+#include "canvas/rectangle.h"
+#include "canvas/debug.h"
+
#include "ardour_ui.h"
#include "ardour_dialog.h"
#include "global_signals.h"
#include "time_axis_view.h"
#include "region_view.h"
#include "ghostregion.h"
-#include "simplerect.h"
-#include "simpleline.h"
#include "selection.h"
#include "keyboard.h"
#include "rgb_macros.h"
using namespace Gtk;
using namespace Gdk;
using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
using namespace PBD;
using namespace Editing;
using namespace ArdourCanvas;
, display_menu (0)
, parent (rent)
, selection_group (0)
+ , _ghost_group (0)
, _hidden (false)
, in_destructor (false)
, _size_menu (0)
, _resize_drag_start (-1)
, _preresize_cursor (0)
, _have_preresize_cursor (false)
- , _ghost_group (0)
, _ebox_release_can_act (true)
{
if (extra_height == 0) {
compute_heights ();
}
- _canvas_background = new Group (*ed.get_background_group (), 0.0, 0.0);
- _canvas_display = new Group (*ed.get_trackview_group (), 0.0, 0.0);
+ _canvas_display = new ArdourCanvas::Container (ed.get_trackview_group (), ArdourCanvas::Duple (0.0, 0.0));
+ CANVAS_DEBUG_NAME (_canvas_display, "main for TAV");
_canvas_display->hide(); // reveal as needed
- selection_group = new Group (*_canvas_display);
+ selection_group = new ArdourCanvas::Container (_canvas_display);
+ CANVAS_DEBUG_NAME (selection_group, "selection for TAV");
selection_group->set_data (X_("timeselection"), (void *) 1);
selection_group->hide();
-
- _ghost_group = new Group (*_canvas_display);
+
+ _ghost_group = new ArdourCanvas::Container (_canvas_display);
+ CANVAS_DEBUG_NAME (_ghost_group, "ghost for TAV");
_ghost_group->lower_to_bottom();
_ghost_group->show();
controls_table.set_no_show_all ();
HSeparator* separator = manage (new HSeparator());
+ separator->set_name("TrackSeparator");
+ separator->set_size_request(-1, 1);
+ separator->show();
controls_vbox.pack_start (controls_table, false, false);
controls_vbox.show ();
controls_ebox.signal_leave_notify_event().connect (sigc::mem_fun (*this, &TimeAxisView::controls_ebox_leave));
controls_ebox.show ();
- time_axis_vbox.pack_end (*separator, false, false);
time_axis_vbox.pack_start (controls_ebox, true, true, 0);
+ time_axis_vbox.pack_end (*separator, false, false);
time_axis_vbox.show();
ColorsChanged.connect (sigc::mem_fun (*this, &TimeAxisView::color_handler));
delete selection_group;
selection_group = 0;
- delete _canvas_background;
- _canvas_background = 0;
-
delete _canvas_display;
_canvas_display = 0;
}
_canvas_display->hide ();
- _canvas_background->hide ();
if (control_parent) {
control_parent->remove (time_axis_vbox);
_order = nth;
if (_y_position != y) {
- _canvas_display->property_y () = y;
- _canvas_background->property_y () = y;
- /* silly canvas */
- _canvas_display->move (0.0, 0.0);
- _canvas_background->move (0.0, 0.0);
+ _canvas_display->set_y_position (y);
_y_position = y;
}
- _canvas_background->raise_to_top ();
_canvas_display->raise_to_top ();
-
- _canvas_background->show ();
_canvas_display->show ();
_hidden = false;
return _effective_height;
}
-void
-TimeAxisView::clip_to_viewport ()
-{
- if (marked_for_display()) {
- if (_y_position + _effective_height < _editor.get_trackview_group_vertical_offset () || _y_position > _editor.get_trackview_group_vertical_offset () + _canvas_display->get_canvas()->get_height()) {
- _canvas_background->hide ();
- _canvas_display->hide ();
- return;
- }
- _canvas_background->show ();
- _canvas_display->show ();
- }
- return;
-}
-
bool
TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
{
}
e.stepping_axis_view()->step_height (false);
return true;
- } else if (Keyboard::no_modifiers_active (ev->state)) {
- _editor.scroll_tracks_up_line();
- return true;
- }
+ }
break;
case GDK_SCROLL_DOWN:
}
e.stepping_axis_view()->step_height (true);
return true;
- } else if (Keyboard::no_modifiers_active (ev->state)) {
- _editor.scroll_tracks_down_line();
- return true;
- }
+ }
break;
default:
break;
}
- return false;
+ /* Just forward to the normal canvas scroll method. The coordinate
+ systems are different but since the canvas is always larger than the
+ track headers, and aligned with the trackview area, this will work.
+
+ In the not too distant future this layout is going away anyway and
+ headers will be on the canvas.
+ */
+ return _editor.canvas_scroll_event (ev, false);
}
bool
TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
{
if (_resize_drag_start >= 0) {
- /* (ab)use the DragManager to do autoscrolling; adjust the event coordinates
- into the world coordinate space that DragManager::motion_handler is expecting,
- and then fake a DragManager motion event so that when maybe_autoscroll
- asks DragManager for the current pointer position it will get the correct
- answers.
+
+ /* (ab)use the DragManager to do autoscrolling - basically we
+ * are pretending that the drag is taking place over the canvas
+ * (which perhaps in the glorious future, when track headers
+ * and the canvas are unified, will actually be true.)
*/
- int tx, ty;
- controls_ebox.translate_coordinates (*control_parent, ev->x, ev->y, tx, ty);
- ev->y = ty - _editor.get_trackview_group_vertical_offset();
- _editor.drags()->motion_handler ((GdkEvent *) ev, false);
- _editor.maybe_autoscroll (false, true, false, ev->y_root < _resize_drag_start);
- /* now do the actual TAV resize */
+ _editor.maybe_autoscroll (false, true, true);
+
+ /* now schedule the actual TAV resize */
int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
_editor.add_to_idle_resize (this, delta);
_resize_drag_start = ev->y_root;
maybe_set_cursor (ev->y);
}
+ gdk_event_request_motions(ev);
return true;
}
(*i)->set_height ();
}
- if (canvas_item_visible (selection_group)) {
+ if (selection_group->visible ()) {
/* resize the selection rect */
show_selection (_editor.get_selection().time);
}
+
+ _editor.override_visible_track_count ();
}
bool
}
if ((i != allviews.end()) && (*i != this) && !(*i)->hidden()) {
- _editor.ensure_time_axis_view_is_visible (**i);
+ _editor.ensure_time_axis_view_is_visible (**i, false);
(*i)->begin_name_edit ();
}
}
if ((i != allviews.end()) && (*i != this) && !(*i)->hidden()) {
- _editor.ensure_time_axis_view_is_visible (**i);
+ _editor.ensure_time_axis_view_is_visible (**i, false);
(*i)->begin_name_edit ();
}
}
}
void
-TimeAxisView::set_samples_per_unit (double spu)
+TimeAxisView::set_samples_per_pixel (double fpp)
{
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
- (*i)->set_samples_per_unit (spu);
+ (*i)->set_samples_per_pixel (fpp);
}
-
- AnalysisFeatureList::const_iterator i;
- list<ArdourCanvas::SimpleLine*>::iterator l;
}
void
(*i)->show_selection (ts);
}
- if (canvas_item_visible (selection_group)) {
+ if (selection_group->visible ()) {
while (!used_selection_rects.empty()) {
free_selection_rects.push_front (used_selection_rects.front());
used_selection_rects.pop_front();
rect = get_selection_rect ((*i).id);
- x1 = _editor.frame_to_unit (start);
- x2 = _editor.frame_to_unit (start + cnt - 1);
- y2 = current_height();
+ x1 = _editor.sample_to_pixel (start);
+ x2 = _editor.sample_to_pixel (start + cnt - 1);
+ y2 = current_height() - 1;
- rect->rect->property_x1() = x1;
- rect->rect->property_y1() = 1.0;
- rect->rect->property_x2() = x2;
- rect->rect->property_y2() = y2;
+ rect->rect->set (ArdourCanvas::Rect (x1, 0, x2, y2));
// trim boxes are at the top for selections
if (x2 > x1) {
- rect->start_trim->property_x1() = x1;
- rect->start_trim->property_y1() = 1.0;
- rect->start_trim->property_x2() = x1 + trim_handle_size;
- rect->start_trim->property_y2() = y2;
-
- rect->end_trim->property_x1() = x2 - trim_handle_size;
- rect->end_trim->property_y1() = 1.0;
- rect->end_trim->property_x2() = x2;
- rect->end_trim->property_y2() = y2;
+ rect->start_trim->set (ArdourCanvas::Rect (x1, 1, x1 + trim_handle_size, y2));
+ rect->end_trim->set (ArdourCanvas::Rect (x2 - trim_handle_size, 1, x2, y2));
rect->start_trim->show();
rect->end_trim->show();
void
TimeAxisView::hide_selection ()
{
- if (canvas_item_visible (selection_group)) {
+ if (selection_group->visible ()) {
while (!used_selection_rects.empty()) {
free_selection_rects.push_front (used_selection_rects.front());
used_selection_rects.pop_front();
rect = new SelectionRect;
- rect->rect = new SimpleRect (*selection_group);
- rect->rect->property_outline_what() = 0x0;
- rect->rect->property_x1() = 0.0;
- rect->rect->property_y1() = 0.0;
- rect->rect->property_x2() = 0.0;
- rect->rect->property_y2() = 0.0;
- rect->rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectionRect.get();
+ rect->rect = new ArdourCanvas::Rectangle (selection_group);
+ CANVAS_DEBUG_NAME (rect->rect, "selection rect");
+ rect->rect->set_outline (false);
+ rect->rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SelectionRect());
- rect->start_trim = new SimpleRect (*selection_group);
- rect->start_trim->property_outline_what() = 0x0;
- rect->start_trim->property_x1() = 0.0;
- rect->start_trim->property_x2() = 0.0;
+ rect->start_trim = new ArdourCanvas::Rectangle (selection_group);
+ CANVAS_DEBUG_NAME (rect->start_trim, "selection rect start trim");
+ rect->start_trim->set_outline (false);
+ rect->start_trim->set_fill (false);
- rect->end_trim = new SimpleRect (*selection_group);
- rect->end_trim->property_outline_what() = 0x0;
- rect->end_trim->property_x1() = 0.0;
- rect->end_trim->property_x2() = 0.0;
+ rect->end_trim = new ArdourCanvas::Rectangle (selection_group);
+ CANVAS_DEBUG_NAME (rect->end_trim, "selection rect end trim");
+ rect->end_trim->set_outline (false);
+ rect->end_trim->set_fill (false);
free_selection_rects.push_front (rect);
- rect->rect->signal_event().connect (sigc::bind (sigc::mem_fun (_editor, &PublicEditor::canvas_selection_rect_event), rect->rect, rect));
- rect->start_trim->signal_event().connect (sigc::bind (sigc::mem_fun (_editor, &PublicEditor::canvas_selection_start_trim_event), rect->rect, rect));
- rect->end_trim->signal_event().connect (sigc::bind (sigc::mem_fun (_editor, &PublicEditor::canvas_selection_end_trim_event), rect->rect, rect));
+ rect->rect->Event.connect (sigc::bind (sigc::mem_fun (_editor, &PublicEditor::canvas_selection_rect_event), rect->rect, rect));
+ rect->start_trim->Event.connect (sigc::bind (sigc::mem_fun (_editor, &PublicEditor::canvas_selection_start_trim_event), rect->rect, rect));
+ rect->end_trim->Event.connect (sigc::bind (sigc::mem_fun (_editor, &PublicEditor::canvas_selection_end_trim_event), rect->rect, rect));
}
rect = free_selection_rects.front();
for (list<SelectionRect*>::iterator i = used_selection_rects.begin(); i != used_selection_rects.end(); ++i) {
- (*i)->rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectionRect.get();
- (*i)->rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+ (*i)->rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SelectionRect());
+ (*i)->rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
- (*i)->start_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
- (*i)->start_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
-
- (*i)->end_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
- (*i)->end_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+ (*i)->start_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+ (*i)->start_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+
+ (*i)->end_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+ (*i)->end_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
}
-
+
for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
-
- (*i)->rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectionRect.get();
- (*i)->rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
-
- (*i)->start_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
- (*i)->start_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
-
- (*i)->end_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
- (*i)->end_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+
+ (*i)->rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SelectionRect());
+ (*i)->rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+
+ (*i)->start_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+ (*i)->start_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+
+ (*i)->end_trim->set_fill_color (ARDOUR_UI::config()->get_canvasvar_Selection());
+ (*i)->end_trim->set_outline_color (ARDOUR_UI::config()->get_canvasvar_Selection());
}
}
/** @return Pair: TimeAxisView, layer index.
- * TimeAxisView is non-0 if this object covers y, or one of its children does.
+ * TimeAxisView is non-0 if this object covers @param y, or one of its children
+ * does. @param y is an offset from the top of the trackview area.
+ *
* If the covering object is a child axis, then the child is returned.
* TimeAxisView is 0 otherwise.
+ *
* Layer index is the layer number (possibly fractional) if the TimeAxisView is valid
* and is in stacked or expanded * region display mode, otherwise 0.
*/
std::pair<TimeAxisView*, double>
-TimeAxisView::covers_y_position (double y)
+TimeAxisView::covers_y_position (double y) const
{
if (hidden()) {
return std::make_pair ((TimeAxisView *) 0, 0);
break;
}
- return std::make_pair (this, l);
+ return std::make_pair (const_cast<TimeAxisView*>(this), l);
}
for (Children::const_iterator i = children.begin(); i != children.end(); ++i) {
return std::make_pair ((TimeAxisView *) 0, 0);
}
+bool
+TimeAxisView::covered_by_y_range (double y0, double y1) const
+{
+ if (hidden()) {
+ return false;
+ }
+
+ /* if either the top or bottom of the axisview is in the vertical
+ * range, we cover it.
+ */
+
+ if ((y0 < _y_position && y1 < _y_position) ||
+ (y0 >= _y_position + height && y1 >= _y_position + height)) {
+ return false;
+ }
+
+ for (Children::const_iterator i = children.begin(); i != children.end(); ++i) {
+ if ((*i)->covered_by_y_range (y0, y1)) {
+ return true;
+ }
+ }
+
+ return true;
+}
uint32_t
TimeAxisView::preset_height (Height h)