Indicate arrangement section selection on canvas
This commit is contained in:
parent
b243b93072
commit
e81b2353cc
@ -122,6 +122,7 @@
|
||||
#include "editor_regions.h"
|
||||
#include "editor_route_groups.h"
|
||||
#include "editor_routes.h"
|
||||
#include "editor_section_box.h"
|
||||
#include "editor_sections.h"
|
||||
#include "editor_snapshots.h"
|
||||
#include "editor_sources.h"
|
||||
@ -410,6 +411,7 @@ Editor::Editor ()
|
||||
, _last_region_menu_was_main (false)
|
||||
, _track_selection_change_without_scroll (false)
|
||||
, _editor_track_selection_change_without_scroll (false)
|
||||
, _section_box (0)
|
||||
, _playhead_cursor (0)
|
||||
, _snapped_cursor (0)
|
||||
, cd_marker_bar_drag_rect (0)
|
||||
@ -924,6 +926,7 @@ Editor::~Editor()
|
||||
delete selection;
|
||||
delete cut_buffer;
|
||||
delete _cursors;
|
||||
delete _section_box;
|
||||
|
||||
LuaInstance::destroy_instance ();
|
||||
|
||||
@ -1110,6 +1113,7 @@ Editor::control_scroll (float fraction)
|
||||
/* move visuals, we'll catch up with it later */
|
||||
|
||||
_playhead_cursor->set_position (*_control_scroll_target);
|
||||
update_section_box ();
|
||||
UpdateAllTransportClocks (*_control_scroll_target);
|
||||
|
||||
if (*_control_scroll_target > (current_page_samples() / 2)) {
|
||||
@ -1265,6 +1269,8 @@ Editor::map_position_change (samplepos_t sample)
|
||||
if (!_session->locate_initiated()) {
|
||||
_playhead_cursor->set_position (sample);
|
||||
}
|
||||
|
||||
update_section_box ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1584,6 +1590,41 @@ Editor::popup_xfade_out_context_menu (int button, int32_t time, ArdourCanvas::It
|
||||
xfade_out_context_menu.popup (button, time);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::popup_section_box_menu (int button, int32_t time)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
section_box_menu.set_name ("ArdourContextMenu");
|
||||
MenuList& items (section_box_menu.items());
|
||||
items.clear ();
|
||||
|
||||
items.push_back (MenuElem (_("Copy/Paste Range Section to Edit Point"), sigc::bind (sigc::mem_fun (*this, &Editor::cut_copy_section), CopyPasteSection)));
|
||||
items.push_back (MenuElem (_("Cut/Paste Range Section to Edit Point"), sigc::bind (sigc::mem_fun (*this, &Editor::cut_copy_section), CutPasteSection)));
|
||||
items.push_back (MenuElem (_("Delete Range Section"), sigc::bind (sigc::mem_fun (*this, &Editor::cut_copy_section), DeleteSection)));
|
||||
#if 0
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Delete all markers in Section"), sigc::bind (sigc::mem_fun (*this, &Editor::cut_copy_section), DeleteSection)));
|
||||
#endif
|
||||
|
||||
timepos_t start, end;
|
||||
if (get_selection_extents (start, end)) {
|
||||
/* add some items from build_marker_menu () */
|
||||
Location* l = _session->locations ()->mark_at (start);
|
||||
assert (l);
|
||||
LocationMarkers* lm = find_location_markers (l);
|
||||
assert (lm && lm->start);
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Move Playhead to Marker"), sigc::bind (sigc::mem_fun(*_session, &Session::request_locate), start.samples (), false, MustStop, TRS_UI)));
|
||||
items.push_back (MenuElem (_("Rename..."), sigc::bind (sigc::mem_fun(*this, &Editor::rename_marker), lm->start)));
|
||||
}
|
||||
|
||||
items.push_back (SeparatorElem());
|
||||
add_selection_context_items (items, true);
|
||||
|
||||
section_box_menu.popup (button, time);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection)
|
||||
{
|
||||
@ -2481,6 +2522,7 @@ Editor::set_state (const XMLNode& node, int version)
|
||||
}
|
||||
|
||||
update_selection_markers ();
|
||||
update_section_box ();
|
||||
|
||||
node.get_property ("mixer-width", editor_mixer_strip_width);
|
||||
|
||||
@ -5019,6 +5061,7 @@ Editor::on_samples_per_pixel_changed ()
|
||||
refresh_location_display();
|
||||
_summary->set_overlays_dirty ();
|
||||
|
||||
update_section_box ();
|
||||
update_marker_labels ();
|
||||
|
||||
instant_save ();
|
||||
@ -5703,6 +5746,7 @@ Editor::located ()
|
||||
if (_follow_playhead && !_pending_initial_locate) {
|
||||
reset_x_origin_to_follow_playhead ();
|
||||
}
|
||||
update_section_box ();
|
||||
}
|
||||
|
||||
_pending_locate_request = false;
|
||||
@ -6472,6 +6516,8 @@ Editor::super_rapid_screen_update ()
|
||||
_playhead_cursor->set_position (sample);
|
||||
}
|
||||
|
||||
update_section_box ();
|
||||
|
||||
if (_session->requested_return_sample() >= 0) {
|
||||
_last_update_time = 0;
|
||||
return;
|
||||
|
@ -145,6 +145,7 @@ class QuantizeDialog;
|
||||
class RegionPeakCursor;
|
||||
class RhythmFerret;
|
||||
class RulerDialog;
|
||||
class SectionBox;
|
||||
class Selection;
|
||||
class SelectionPropertiesBox;
|
||||
class SoundFileOmega;
|
||||
@ -733,6 +734,7 @@ private:
|
||||
void toggle_marker_lines ();
|
||||
void set_marker_line_visibility (bool);
|
||||
void update_selection_markers ();
|
||||
void update_section_box ();
|
||||
|
||||
void jump_forward_to_mark ();
|
||||
void jump_backward_to_mark ();
|
||||
@ -852,12 +854,14 @@ private:
|
||||
void collect_new_region_view (RegionView*);
|
||||
void collect_and_select_new_region_view (RegionView*);
|
||||
|
||||
Gtk::Menu section_box_menu;
|
||||
Gtk::Menu track_context_menu;
|
||||
Gtk::Menu track_region_context_menu;
|
||||
Gtk::Menu track_selection_context_menu;
|
||||
|
||||
GdkEvent context_click_event;
|
||||
|
||||
void popup_section_box_menu (int, int);
|
||||
void popup_track_context_menu (int, int, ItemType, bool);
|
||||
Gtk::Menu* build_track_context_menu ();
|
||||
Gtk::Menu* build_track_bus_context_menu ();
|
||||
@ -1795,6 +1799,7 @@ private:
|
||||
|
||||
/* non-public event handlers */
|
||||
|
||||
bool canvas_section_box_event (GdkEvent* event);
|
||||
bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*);
|
||||
bool track_canvas_scroll (GdkEventScroll* event);
|
||||
|
||||
@ -2099,6 +2104,8 @@ private:
|
||||
|
||||
bool audio_region_selection_covers (samplepos_t where);
|
||||
|
||||
SectionBox* _section_box;
|
||||
|
||||
/* playhead and edit cursor */
|
||||
|
||||
EditorCursor* _playhead_cursor;
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "editor_drag.h"
|
||||
#include "region_view.h"
|
||||
#include "editor_group_tabs.h"
|
||||
#include "editor_section_box.h"
|
||||
#include "editor_summary.h"
|
||||
#include "video_timeline.h"
|
||||
#include "keyboard.h"
|
||||
@ -143,13 +144,6 @@ Editor::initialize_canvas ()
|
||||
_time_markers_group = new ArdourCanvas::Container (h_scroll_group);
|
||||
CANVAS_DEBUG_NAME (_time_markers_group, "time bars");
|
||||
|
||||
/* group above rulers, to show selection triangles */
|
||||
_selection_marker_group = new ArdourCanvas::Container (h_scroll_group);
|
||||
CANVAS_DEBUG_NAME (_selection_marker_group, "Canvas Selection Ruler");
|
||||
_selection_marker->start = new SelectionMarker (*this, *_selection_marker_group, "play head", ArdourMarker::SelectionStart);
|
||||
_selection_marker->end = new SelectionMarker (*this, *_selection_marker_group, "play head", ArdourMarker::SelectionEnd);
|
||||
_selection_marker_group->raise_to_top ();
|
||||
|
||||
/* Note that because of ascending-y-axis coordinates, this order is
|
||||
* bottom-to-top. But further note that the actual order is set in
|
||||
* ::update_ruler_visibility()
|
||||
@ -279,6 +273,17 @@ Editor::initialize_canvas ()
|
||||
_canvas_grid_zone->Event.connect (sigc::mem_fun (*this, &Editor::canvas_grid_zone_event));
|
||||
_canvas_grid_zone->set_ignore_events (true);
|
||||
|
||||
/* and now the timeline-selection rectangle which is controlled by the markers */
|
||||
_section_box = new SectionBox (*this, cursor_scroll_group);
|
||||
_section_box->Event.connect (sigc::mem_fun (*this, &Editor::canvas_section_box_event));
|
||||
|
||||
/* group above rulers, to show selection triangles */
|
||||
_selection_marker_group = new ArdourCanvas::Container (cursor_scroll_group);
|
||||
CANVAS_DEBUG_NAME (_selection_marker_group, "Canvas Selection Ruler");
|
||||
_selection_marker->start = new SelectionMarker (*this, *_selection_marker_group, "selection", ArdourMarker::SelectionStart);
|
||||
_selection_marker->end = new SelectionMarker (*this, *_selection_marker_group, "selection", ArdourMarker::SelectionEnd);
|
||||
_selection_marker_group->raise_to_top ();
|
||||
|
||||
/* these signals will initially be delivered to the canvas itself, but if they end up remaining unhandled,
|
||||
* they are passed to Editor-level handlers.
|
||||
*/
|
||||
@ -1063,6 +1068,9 @@ Editor::color_handler()
|
||||
bbt_ruler->set_fill_color (base);
|
||||
bbt_ruler->set_outline_color (text);
|
||||
|
||||
_section_box->set_fill_color (UIConfiguration::instance().color_mod ("selection", "selection rect"));
|
||||
_section_box->set_outline_color (UIConfiguration::instance().color ("selection"));
|
||||
|
||||
_playhead_cursor->set_color (UIConfiguration::instance().color ("play head"));
|
||||
|
||||
meter_bar->set_fill_color (UIConfiguration::instance().color_mod ("meter bar", "marker bar"));
|
||||
|
@ -1188,7 +1188,7 @@ Editor::section_rect_event (GdkEvent* ev, Location* loc, ArdourCanvas::Rectangle
|
||||
break;
|
||||
}
|
||||
/* and show section context menu */
|
||||
//popup_section_box_menu (ev->button.button, ev->button.time);
|
||||
popup_section_box_menu (ev->button.button, ev->button.time);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -1204,6 +1204,32 @@ Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
|
||||
return typed_event (item, event, PlayheadCursorItem);
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::canvas_section_box_event (GdkEvent *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case GDK_BUTTON_PRESS:
|
||||
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)
|
||||
&& event->button.button == 1) {
|
||||
_drags->set (new CursorDrag (this, *_playhead_cursor, false), event);
|
||||
}
|
||||
/*fallthrough*/
|
||||
case GDK_2BUTTON_PRESS:
|
||||
/*fallthrough*/
|
||||
case GDK_3BUTTON_PRESS:
|
||||
return !Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
|
||||
case GDK_BUTTON_RELEASE:
|
||||
if (Keyboard::is_context_menu_event (&event->button)) {
|
||||
popup_section_box_menu (event->button.button, event->button.time);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
|
||||
{
|
||||
|
54
gtk2_ardour/editor_section_box.cc
Normal file
54
gtk2_ardour/editor_section_box.cc
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Robin Gareus <robin@gareus.org>
|
||||
* Copyright (C) 2023 Ben Loftis <ben@harrisonaudio.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "editor.h"
|
||||
#include "editor_section_box.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
|
||||
SectionBox::SectionBox (Editor& ed, ArdourCanvas::Item* parent)
|
||||
: ArdourCanvas::Rectangle (parent)
|
||||
, _editor (ed)
|
||||
{
|
||||
set (ArdourCanvas::Rect (0, 0, 0, ArdourCanvas::COORD_MAX));
|
||||
set_ignore_events (false);
|
||||
|
||||
set_outline_what (ArdourCanvas::Rectangle::What (Rectangle::LEFT | Rectangle::RIGHT));
|
||||
set_outline (true);
|
||||
set_fill (true);
|
||||
|
||||
hide ();
|
||||
}
|
||||
|
||||
void
|
||||
SectionBox::set_position (samplepos_t sample_start, samplepos_t sample_end)
|
||||
{
|
||||
double const new_start = _editor.sample_to_pixel_unrounded (sample_start);
|
||||
double const new_end = _editor.sample_to_pixel_unrounded (sample_end);
|
||||
|
||||
if (rint (new_start) != rint (x0())) {
|
||||
set_x0 (new_start + 0.5); // accommodate the 1/2 pixel "line" offset in cairo
|
||||
}
|
||||
|
||||
if (rint (new_end) != rint (x1())) {
|
||||
set_x1 (new_end + 0.5); // accommodate the 1/2 pixel "line" offset in cairo
|
||||
}
|
||||
}
|
41
gtk2_ardour/editor_section_box.h
Normal file
41
gtk2_ardour/editor_section_box.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Robin Gareus <robin@gareus.org>
|
||||
* Copyright (C) 2023 Ben Loftis <ben@harrisonaudio.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __gtk_ardour_section_box_h__
|
||||
#define __gtk_ardour_section_box_h__
|
||||
|
||||
#include "ardour/types.h"
|
||||
|
||||
#include "canvas/rectangle.h"
|
||||
#include "canvas/types.h"
|
||||
|
||||
class Editor;
|
||||
|
||||
class SectionBox : public ArdourCanvas::Rectangle
|
||||
{
|
||||
public:
|
||||
SectionBox (Editor&, ArdourCanvas::Item*);
|
||||
|
||||
void set_position (samplepos_t, samplepos_t);
|
||||
|
||||
private:
|
||||
Editor& _editor;
|
||||
};
|
||||
|
||||
#endif // __gtk_ardour_editor_cursors_h__
|
@ -39,6 +39,7 @@
|
||||
#include "editor.h"
|
||||
#include "editor_drag.h"
|
||||
#include "editor_routes.h"
|
||||
#include "editor_section_box.h"
|
||||
#include "editor_sources.h"
|
||||
#include "actions.h"
|
||||
#include "audio_time_axis.h"
|
||||
@ -1264,6 +1265,17 @@ Editor::presentation_info_changed (PropertyChange const & what_changed)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::update_section_box ()
|
||||
{
|
||||
if (selection->tracks.size() == 0 && selection->regions.size () == 0 && selection->time.length() != 0) {
|
||||
_section_box->set_position (selection->time.start_time().samples(), selection->time.end_time().samples());
|
||||
_section_box->show ();
|
||||
} else {
|
||||
_section_box->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::track_selection_changed ()
|
||||
{
|
||||
@ -1275,6 +1287,7 @@ Editor::track_selection_changed ()
|
||||
play_solo_selection(false);
|
||||
|
||||
update_selection_markers ();
|
||||
update_section_box ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1294,6 +1307,8 @@ Editor::time_selection_changed ()
|
||||
}
|
||||
|
||||
update_selection_markers ();
|
||||
update_section_box ();
|
||||
|
||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
||||
(*i)->show_selection (selection->time);
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ gtk2_ardour_sources = [
|
||||
'editor_cursors.cc',
|
||||
'editor_drag.cc',
|
||||
'editor_route_groups.cc',
|
||||
'editor_section_box.cc',
|
||||
'editor_export_audio.cc',
|
||||
'editor_group_tabs.cc',
|
||||
'editor_keys.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user