Implement TriggerStrip selection
This also changes TriggerBox Selection to act on release (like all other selection). Otherwise strip selection will de-select the TriggerBox on mouse-release.
This commit is contained in:
parent
fd3d17562c
commit
511ff3290f
@ -69,6 +69,7 @@ TriggerPage::TriggerPage ()
|
||||
, _cue_box (16, 16 * default_triggers_per_box)
|
||||
, _master_widget (16, 16)
|
||||
, _master (_master_widget.root ())
|
||||
, _selection (*this, *this)
|
||||
{
|
||||
load_bindings ();
|
||||
register_actions ();
|
||||
@ -266,6 +267,7 @@ TriggerPage::set_session (Session* s)
|
||||
_trigger_route_list.set_session (s);
|
||||
|
||||
if (!_session) {
|
||||
_selection.clear ();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -297,6 +299,10 @@ TriggerPage::set_session (Session* s)
|
||||
update_title ();
|
||||
start_updating ();
|
||||
selection_changed ();
|
||||
|
||||
PBD::PropertyChange sc;
|
||||
sc.add (Properties::selected);
|
||||
_selection.presentation_info_changed (sc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -312,6 +318,7 @@ TriggerPage::session_going_away ()
|
||||
delete (*i);
|
||||
}
|
||||
#endif
|
||||
_selection.clear ();
|
||||
_strips.clear ();
|
||||
|
||||
SessionHandlePtr::session_going_away ();
|
||||
@ -432,6 +439,7 @@ TriggerPage::add_routes (RouteList& rl)
|
||||
|
||||
(*r)->presentation_info ().PropertyChanged.connect (*this, invalidator (*this), boost::bind (&TriggerPage::stripable_property_changed, this, _1, boost::weak_ptr<Stripable> (*r)), gui_context ());
|
||||
(*r)->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&TriggerPage::stripable_property_changed, this, _1, boost::weak_ptr<Stripable> (*r)), gui_context ());
|
||||
ts->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &TriggerPage::strip_button_release_event), ts));
|
||||
}
|
||||
redisplay_track_list ();
|
||||
}
|
||||
@ -464,6 +472,7 @@ void
|
||||
TriggerPage::redisplay_track_list ()
|
||||
{
|
||||
_strips.sort (TriggerStripSorter ());
|
||||
PresentationInfo::ChangeSuspender cs;
|
||||
|
||||
for (list<TriggerStrip*>::iterator i = _strips.begin (); i != _strips.end (); ++i) {
|
||||
TriggerStrip* strip = *i;
|
||||
@ -472,6 +481,12 @@ TriggerPage::redisplay_track_list ()
|
||||
|
||||
bool hidden = s->presentation_info ().hidden ();
|
||||
|
||||
if (s->is_selected ()) {
|
||||
_selection.add (*i);
|
||||
} else {
|
||||
_selection.remove (*i);
|
||||
}
|
||||
|
||||
if (!(s)->presentation_info ().trigger_track ()) {
|
||||
hidden = true;
|
||||
}
|
||||
@ -492,6 +507,25 @@ TriggerPage::redisplay_track_list ()
|
||||
}
|
||||
}
|
||||
|
||||
AxisView*
|
||||
TriggerPage::axis_view_by_stripable (boost::shared_ptr<Stripable> s) const
|
||||
{
|
||||
for (list<TriggerStrip*>::const_iterator i = _strips.begin (); i != _strips.end (); ++i) {
|
||||
TriggerStrip* strip = *i;
|
||||
if (s == strip->stripable ()) {
|
||||
return strip;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
AxisView*
|
||||
TriggerPage::axis_view_by_control (boost::shared_ptr<AutomationControl> c) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TriggerPage::rec_state_clicked ()
|
||||
{
|
||||
@ -512,6 +546,9 @@ TriggerPage::parameter_changed (string const& p)
|
||||
void
|
||||
TriggerPage::pi_property_changed (PBD::PropertyChange const& what_changed)
|
||||
{
|
||||
if (what_changed.contains (Properties::selected)) {
|
||||
_selection.presentation_info_changed (what_changed);
|
||||
}
|
||||
if (what_changed.contains (ARDOUR::Properties::order)) {
|
||||
redisplay_track_list ();
|
||||
}
|
||||
@ -535,6 +572,87 @@ TriggerPage::stripable_property_changed (PBD::PropertyChange const& what_changed
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TriggerPage::strip_button_release_event (GdkEventButton *ev, TriggerStrip *strip)
|
||||
{
|
||||
if (ev->button != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_selection.selected (strip)) {
|
||||
/* primary-click: toggle selection state of strip */
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
_selection.remove (strip, true);
|
||||
} else if (_selection.axes.size() > 1) {
|
||||
/* de-select others */
|
||||
_selection.set (strip);
|
||||
}
|
||||
PublicEditor& pe = PublicEditor::instance();
|
||||
TimeAxisView* tav = pe.time_axis_view_from_stripable (strip->stripable());
|
||||
if (tav) {
|
||||
pe.set_selected_mixer_strip (*tav);
|
||||
}
|
||||
} else {
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
_selection.add (strip, true);
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::RangeSelectModifier)) {
|
||||
|
||||
/* extend selection */
|
||||
|
||||
vector<TriggerStrip*> tmp;
|
||||
bool accumulate = false;
|
||||
bool found_another = false;
|
||||
|
||||
_strips.sort (TriggerStripSorter ());
|
||||
|
||||
for (list<TriggerStrip*>::iterator i = _strips.begin (); i != _strips.end (); ++i) {
|
||||
TriggerStrip* ts = *i;
|
||||
|
||||
if (ts == strip) {
|
||||
/* hit clicked strip, start accumulating till we hit the first
|
||||
selected strip
|
||||
*/
|
||||
if (accumulate) {
|
||||
/* done */
|
||||
break;
|
||||
} else {
|
||||
accumulate = true;
|
||||
}
|
||||
} else if (_selection.selected (ts)) {
|
||||
/* hit selected strip. if currently accumulating others,
|
||||
we're done. if not accumulating others, start doing so.
|
||||
*/
|
||||
found_another = true;
|
||||
if (accumulate) {
|
||||
/* done */
|
||||
break;
|
||||
} else {
|
||||
accumulate = true;
|
||||
}
|
||||
} else {
|
||||
if (accumulate) {
|
||||
tmp.push_back (ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tmp.push_back (strip);
|
||||
|
||||
if (found_another) {
|
||||
PresentationInfo::ChangeSuspender cs;
|
||||
for (vector<TriggerStrip*>::iterator i = tmp.begin(); i != tmp.end(); ++i) {
|
||||
_selection.add (*i, true);
|
||||
}
|
||||
} else {
|
||||
_selection.set (strip); //user wants to start a range selection, but there aren't any others selected yet
|
||||
}
|
||||
} else {
|
||||
_selection.set (strip);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TriggerPage::no_strip_button_event (GdkEventButton* ev)
|
||||
{
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "midi_region_operations_box.h"
|
||||
#include "midi_region_properties_box.h"
|
||||
#include "midi_trigger_properties_box.h"
|
||||
#include "route_processor_selection.h"
|
||||
#include "slot_properties_box.h"
|
||||
#include "trigger_clip_picker.h"
|
||||
#include "trigger_region_list.h"
|
||||
@ -47,7 +48,7 @@
|
||||
|
||||
class TriggerStrip;
|
||||
|
||||
class TriggerPage : public ArdourWidgets::Tabbable, public ARDOUR::SessionHandlePtr, public PBD::ScopedConnectionList
|
||||
class TriggerPage : public ArdourWidgets::Tabbable, public ARDOUR::SessionHandlePtr, public PBD::ScopedConnectionList, public AxisViewProvider
|
||||
{
|
||||
public:
|
||||
TriggerPage ();
|
||||
@ -60,6 +61,8 @@ public:
|
||||
|
||||
Gtk::Window* use_own_window (bool and_fill_it);
|
||||
|
||||
RouteProcessorSelection& selection() { return _selection; }
|
||||
|
||||
private:
|
||||
void load_bindings ();
|
||||
void register_actions ();
|
||||
@ -80,6 +83,7 @@ private:
|
||||
|
||||
void add_sidebar_page (std::string const&, Gtk::Widget&);
|
||||
|
||||
bool strip_button_release_event (GdkEventButton*, TriggerStrip*);
|
||||
bool no_strip_button_event (GdkEventButton*);
|
||||
bool no_strip_drag_motion (Glib::RefPtr<Gdk::DragContext> const&, int, int, guint);
|
||||
void no_strip_drag_data_received (Glib::RefPtr<Gdk::DragContext> const&, int, int, Gtk::SelectionData const&, guint, guint);
|
||||
@ -87,6 +91,9 @@ private:
|
||||
bool idle_drop_paths (std::vector<std::string>);
|
||||
void drop_paths_part_two (std::vector<std::string>);
|
||||
|
||||
AxisView* axis_view_by_stripable (boost::shared_ptr<ARDOUR::Stripable>) const;
|
||||
AxisView* axis_view_by_control (boost::shared_ptr<ARDOUR::AutomationControl>) const;
|
||||
|
||||
void selection_changed ();
|
||||
PBD::ScopedConnectionList editor_connections;
|
||||
|
||||
@ -130,6 +137,7 @@ private:
|
||||
MidiClipEditorBox _midi_trim_box;
|
||||
#endif
|
||||
|
||||
RouteProcessorSelection _selection;
|
||||
std::list<TriggerStrip*> _strips;
|
||||
sigc::connection _fast_screen_update_connection;
|
||||
};
|
||||
|
@ -403,6 +403,22 @@ TriggerStrip::route_property_changed (const PropertyChange& what_changed)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriggerStrip::set_selected (bool yn)
|
||||
{
|
||||
AxisView::set_selected (yn);
|
||||
|
||||
if (selected()) {
|
||||
global_frame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT);
|
||||
global_frame.set_name ("MixerStripSelectedFrame");
|
||||
} else {
|
||||
global_frame.set_shadow_type (Gtk::SHADOW_IN);
|
||||
global_frame.set_name ("MixerStripFrame");
|
||||
}
|
||||
|
||||
global_frame.queue_draw ();
|
||||
}
|
||||
|
||||
void
|
||||
TriggerStrip::route_color_changed ()
|
||||
{
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
}
|
||||
|
||||
void set_session (ARDOUR::Session* s);
|
||||
void set_selected (bool yn);
|
||||
|
||||
void fast_update ();
|
||||
|
||||
|
@ -563,7 +563,6 @@ TriggerEntry::name_button_event (GdkEvent* ev)
|
||||
}
|
||||
break;
|
||||
case GDK_BUTTON_PRESS:
|
||||
PublicEditor::instance ().get_selection ().set (this);
|
||||
break;
|
||||
case GDK_2BUTTON_PRESS:
|
||||
#if SELECTION_PROPERTIES_BOX_TODO
|
||||
@ -573,8 +572,12 @@ TriggerEntry::name_button_event (GdkEvent* ev)
|
||||
case GDK_BUTTON_RELEASE:
|
||||
switch (ev->button.button) {
|
||||
case 3:
|
||||
PublicEditor::instance ().get_selection ().set (this);
|
||||
context_menu ();
|
||||
return true;
|
||||
case 1:
|
||||
PublicEditor::instance ().get_selection ().set (this);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user