trigger_ui: separate buttons+icons for launch and follow modes
This commit is contained in:
parent
e112a86af2
commit
9837adb4c4
@ -66,14 +66,16 @@ TriggerEntry::TriggerEntry (Item* item, ARDOUR::Trigger& t)
|
||||
set_outline (false);
|
||||
|
||||
play_button = new ArdourCanvas::Rectangle (this);
|
||||
play_button->set_outline (true);
|
||||
play_button->set_outline (false);
|
||||
play_button->set_fill (true);
|
||||
play_button->name = string_compose ("playbutton %1", _trigger.index ());
|
||||
play_button->show ();
|
||||
|
||||
play_shape = new ArdourCanvas::Polygon (play_button);
|
||||
play_shape->name = string_compose ("playshape %1", _trigger.index ());
|
||||
play_shape->show ();
|
||||
follow_button = new ArdourCanvas::Rectangle (this);
|
||||
follow_button->set_outline (false);
|
||||
follow_button->set_fill (true);
|
||||
follow_button->name = ("slot_selector_button");
|
||||
follow_button->show ();
|
||||
|
||||
name_button = new ArdourCanvas::Rectangle (this);
|
||||
name_button->set_outline (true);
|
||||
@ -143,12 +145,12 @@ TriggerEntry::_size_allocate (ArdourCanvas::Rect const& alloc)
|
||||
const Distance height = _rect.height ();
|
||||
|
||||
play_button->set (ArdourCanvas::Rect (0, 0, height, height));
|
||||
name_button->set (ArdourCanvas::Rect (height, 0, width, height));
|
||||
name_button->set (ArdourCanvas::Rect (height, 0, width-height, height));
|
||||
follow_button->set (ArdourCanvas::Rect (width-height, 0, width, height));
|
||||
|
||||
const double scale = UIConfiguration::instance ().get_ui_scale ();
|
||||
_poly_margin = 2. * scale;
|
||||
_poly_size = height - 2 * _poly_margin;
|
||||
shape_play_button ();
|
||||
|
||||
float tleft = height; // make room for the play button
|
||||
|
||||
@ -161,7 +163,7 @@ TriggerEntry::_size_allocate (ArdourCanvas::Rect const& alloc)
|
||||
}
|
||||
|
||||
void
|
||||
draw_follow_icon (Cairo::RefPtr<Cairo::Context> context, Trigger::FollowAction icon, float size, float scale)
|
||||
TriggerEntry::draw_follow_icon (Cairo::RefPtr<Cairo::Context> context, Trigger::FollowAction icon, float size, float scale) const
|
||||
{
|
||||
context->set_line_width (1 * scale);
|
||||
|
||||
@ -229,6 +231,84 @@ draw_follow_icon (Cairo::RefPtr<Cairo::Context> context, Trigger::FollowAction i
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TriggerEntry::draw_launch_icon (Cairo::RefPtr<Cairo::Context> context, float size, float scale) const
|
||||
{
|
||||
context->set_line_width (1 * scale);
|
||||
|
||||
if (_trigger.active()) {
|
||||
if (_trigger.launch_style()==Trigger::Toggle) {
|
||||
//clicking again will Stop this clip
|
||||
set_source_rgba (context, UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
context->move_to (_poly_margin, _poly_margin);
|
||||
context->rel_line_to (_poly_size, 0);
|
||||
context->rel_line_to (0, _poly_size);
|
||||
context->rel_line_to (-_poly_size, 0);
|
||||
context->rel_line_to (0, -_poly_size);
|
||||
context->fill ();
|
||||
return; //done
|
||||
} else {
|
||||
//actively playing; draw a filled play triangle
|
||||
set_source_rgba (context, UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
context->move_to (_poly_margin, _poly_margin);
|
||||
context->line_to (_poly_margin, _poly_size);
|
||||
context->line_to (_poly_size, 0.5 + _poly_size / 2.);
|
||||
context->fill ();
|
||||
return; //done
|
||||
}
|
||||
}
|
||||
|
||||
set_source_rgba (context, UIConfiguration::instance ().color ("neutral:midground"));
|
||||
|
||||
if (!_trigger.region ()) {
|
||||
//no content in this slot, it is only a Stop button
|
||||
context->move_to (_poly_margin, _poly_margin);
|
||||
context->rel_line_to (_poly_size, 0);
|
||||
context->rel_line_to (0, _poly_size);
|
||||
context->rel_line_to (-_poly_size, 0);
|
||||
context->rel_line_to (0, -_poly_size);
|
||||
context->stroke ();
|
||||
return; //done
|
||||
}
|
||||
|
||||
switch (_trigger.launch_style()) {
|
||||
case Trigger::Toggle:
|
||||
case Trigger::OneShot:
|
||||
context->move_to (_poly_margin, _poly_margin);
|
||||
context->line_to (_poly_margin, _poly_size);
|
||||
context->line_to (_poly_size, 0.5 + _poly_size / 2.);
|
||||
context->line_to (_poly_margin, _poly_margin);
|
||||
context->stroke ();
|
||||
break;
|
||||
case Trigger::Gate: //diamond shape
|
||||
context->move_to ( _poly_size/2, _poly_margin );
|
||||
context->rel_line_to ( _poly_size/2, _poly_size/2);
|
||||
context->rel_line_to ( -_poly_size/2, _poly_size/2);
|
||||
context->rel_line_to ( -_poly_size/2, -_poly_size/2);
|
||||
context->rel_line_to ( _poly_size/2, -_poly_size/2);
|
||||
context->stroke ();
|
||||
break;
|
||||
case Trigger::Repeat: //'stutter' shape
|
||||
context->set_line_width (1 * scale);
|
||||
context->move_to ( _poly_margin, _poly_margin );
|
||||
context->rel_line_to ( 0, _poly_size);
|
||||
|
||||
context->move_to ( _poly_margin + scale*3, _poly_margin + scale*2 );
|
||||
context->rel_line_to ( 0, _poly_size - scale*4);
|
||||
|
||||
context->move_to ( _poly_margin + scale*6, _poly_margin + scale*4 );
|
||||
context->rel_line_to ( 0, _poly_size - scale*8);
|
||||
|
||||
context->stroke ();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
context->set_line_width (1);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerEntry::render (ArdourCanvas::Rect const& area, Cairo::RefPtr<Cairo::Context> context) const
|
||||
{
|
||||
@ -288,6 +368,15 @@ TriggerEntry::render (ArdourCanvas::Rect const& area, Cairo::RefPtr<Cairo::Conte
|
||||
context->set_identity_matrix ();
|
||||
}
|
||||
|
||||
/* launch icon */
|
||||
{
|
||||
context->set_identity_matrix ();
|
||||
context->translate (self.x0, self.y0 - 0.5);
|
||||
context->translate (0, 0); // left side of the widget
|
||||
draw_launch_icon (context, height, scale);
|
||||
context->set_identity_matrix ();
|
||||
}
|
||||
|
||||
/* follow-action icon */
|
||||
if (_trigger.region ()) {
|
||||
context->set_identity_matrix ();
|
||||
@ -299,65 +388,27 @@ TriggerEntry::render (ArdourCanvas::Rect const& area, Cairo::RefPtr<Cairo::Conte
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriggerEntry::shape_play_button ()
|
||||
{
|
||||
Points p;
|
||||
|
||||
if (!_trigger.region ()) {
|
||||
/* no region, so must be a stop button, drawn as a square */
|
||||
p.push_back (Duple (_poly_margin, _poly_margin));
|
||||
p.push_back (Duple (_poly_margin, _poly_size));
|
||||
p.push_back (Duple (_poly_size, _poly_size));
|
||||
p.push_back (Duple (_poly_size, _poly_margin));
|
||||
} else {
|
||||
/* region exists; draw triangle to show that we can trigger */
|
||||
p.push_back (Duple (_poly_margin, _poly_margin));
|
||||
p.push_back (Duple (_poly_margin, _poly_size));
|
||||
p.push_back (Duple (_poly_size, 0.5 + _poly_size / 2.));
|
||||
}
|
||||
|
||||
play_shape->set (p);
|
||||
|
||||
if (_trigger.active ()) {
|
||||
play_shape->set_outline (false);
|
||||
play_shape->set_fill (true);
|
||||
} else {
|
||||
play_shape->set_outline (true);
|
||||
play_shape->set_fill (false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriggerEntry::prop_change (PropertyChange const& change)
|
||||
{
|
||||
bool need_pb = false;
|
||||
|
||||
if (change.contains (ARDOUR::Properties::name)) {
|
||||
if (_trigger.region ()) {
|
||||
name_text->set (short_version (_trigger.name (), 16));
|
||||
} else {
|
||||
name_text->set ("");
|
||||
}
|
||||
|
||||
need_pb = true;
|
||||
}
|
||||
|
||||
if (change.contains (ARDOUR::Properties::running)) {
|
||||
need_pb = true;
|
||||
}
|
||||
|
||||
PropertyChange interesting_stuff;
|
||||
interesting_stuff.add (ARDOUR::Properties::name);
|
||||
interesting_stuff.add (ARDOUR::Properties::launch_style);
|
||||
interesting_stuff.add (ARDOUR::Properties::follow_action0);
|
||||
interesting_stuff.add (ARDOUR::Properties::isolated);
|
||||
interesting_stuff.add (ARDOUR::Properties::running);
|
||||
|
||||
if (change.contains (interesting_stuff)) {
|
||||
redraw ();
|
||||
}
|
||||
|
||||
if (need_pb) {
|
||||
shape_play_button ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -365,28 +416,20 @@ TriggerEntry::set_default_colors ()
|
||||
{
|
||||
set_fill_color (UIConfiguration::instance ().color ("theme:bg"));
|
||||
play_button->set_fill_color (UIConfiguration::instance ().color ("theme:bg"));
|
||||
play_button->set_outline_color (UIConfiguration::instance ().color ("theme:bg"));
|
||||
name_button->set_fill_color (UIConfiguration::instance ().color ("theme:bg"));
|
||||
name_button->set_outline_color (UIConfiguration::instance ().color ("theme:bg"));
|
||||
follow_button->set_fill_color (UIConfiguration::instance ().color ("theme:bg"));
|
||||
if ((_trigger.index () / 2) % 2 == 0) {
|
||||
set_fill_color (HSV (fill_color ()).darker (0.15).color ());
|
||||
play_button->set_fill_color (HSV (fill_color ()).darker (0.15).color ());
|
||||
play_button->set_outline_color (HSV (fill_color ()).darker (0.15).color ());
|
||||
name_button->set_fill_color (HSV (fill_color ()).darker (0.15).color ());
|
||||
name_button->set_outline_color (HSV (fill_color ()).darker (0.15).color ());
|
||||
follow_button->set_fill_color (HSV (fill_color ()).darker (0.15).color ());
|
||||
}
|
||||
|
||||
name_text->set_color (UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
name_text->set_fill_color (UIConfiguration::instance ().color ("neutral:midground"));
|
||||
|
||||
if (_trigger.region ()) {
|
||||
play_shape->set_outline_color (UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
play_shape->set_fill_color (UIConfiguration::instance ().color ("neutral:foreground"));
|
||||
} else {
|
||||
play_shape->set_outline_color (UIConfiguration::instance ().color ("neutral:midground"));
|
||||
play_shape->set_fill_color (UIConfiguration::instance ().color ("neutral:midground"));
|
||||
}
|
||||
|
||||
/*preserve selection border*/
|
||||
if (PublicEditor::instance ().get_selection ().selected (this)) {
|
||||
name_button->set_outline_color (UIConfiguration::instance ().color ("alert:red"));
|
||||
@ -502,8 +545,9 @@ TriggerBoxUI::build ()
|
||||
|
||||
_slots.push_back (te);
|
||||
|
||||
te->play_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::play_button_event), n));
|
||||
te->name_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::text_button_event), n));
|
||||
te->play_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::play_button_event), n)); //ToDo: just trigger stuff
|
||||
te->name_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::name_button_event), n));
|
||||
te->follow_button->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::follow_button_event), n)); //ToDo: just follow stuff
|
||||
#if 0
|
||||
te->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::event), n));
|
||||
#endif
|
||||
@ -532,13 +576,17 @@ TriggerBoxUI::_size_allocate (ArdourCanvas::Rect const& alloc)
|
||||
}
|
||||
|
||||
bool
|
||||
TriggerBoxUI::text_button_event (GdkEvent* ev, uint64_t n)
|
||||
TriggerBoxUI::name_button_event (GdkEvent* ev, uint64_t n)
|
||||
{
|
||||
switch (ev->type) {
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
_slots[n]->set_default_colors ();
|
||||
_slots[n]->name_text->set_color (UIConfiguration::instance ().color ("neutral:foregroundest"));
|
||||
_slots[n]->name_button->set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
_slots[n]->name_button->set_outline_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
_slots[n]->follow_button->set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
_slots[n]->play_button->set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
}
|
||||
break;
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
@ -552,6 +600,8 @@ TriggerBoxUI::text_button_event (GdkEvent* ev, uint64_t n)
|
||||
/* a side-effect of selection-change is that the slot's color is reset. retain the "entered-color" here: */
|
||||
_slots[n]->name_text->set_color (UIConfiguration::instance ().color ("neutral:foregroundest"));
|
||||
_slots[n]->name_button->set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
_slots[n]->name_button->set_outline_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
_slots[n]->follow_button->set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
}
|
||||
break;
|
||||
case GDK_2BUTTON_PRESS:
|
||||
@ -577,7 +627,7 @@ bool
|
||||
TriggerBoxUI::play_button_event (GdkEvent* ev, uint64_t n)
|
||||
{
|
||||
if (!_triggerbox.trigger (n)->region ()) {
|
||||
/* this is a stop button */
|
||||
/* empty slot; this is just a stop button */
|
||||
switch (ev->type) {
|
||||
case GDK_BUTTON_PRESS:
|
||||
if (ev->button.button == 1) {
|
||||
@ -585,21 +635,9 @@ TriggerBoxUI::play_button_event (GdkEvent* ev, uint64_t n)
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
_slots[n]->play_shape->set_outline_color (UIConfiguration::instance ().color ("neutral:foregroundest"));
|
||||
}
|
||||
break;
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
_slots[n]->set_default_colors ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ev->type) {
|
||||
@ -620,15 +658,17 @@ TriggerBoxUI::play_button_event (GdkEvent* ev, uint64_t n)
|
||||
_slots[n]->trigger ().unbang ();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
context_menu (n);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
_slots[n]->set_default_colors ();
|
||||
_slots[n]->play_button->set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
_slots[n]->play_shape->set_fill_color (UIConfiguration::instance ().color ("neutral:foregroundest"));
|
||||
_slots[n]->play_shape->set_outline_color (UIConfiguration::instance ().color ("neutral:foregroundest"));
|
||||
}
|
||||
break;
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
@ -642,6 +682,37 @@ TriggerBoxUI::play_button_event (GdkEvent* ev, uint64_t n)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TriggerBoxUI::follow_button_event (GdkEvent* ev, uint64_t n)
|
||||
{
|
||||
switch (ev->type) {
|
||||
case GDK_BUTTON_RELEASE:
|
||||
switch (ev->button.button) {
|
||||
case 3:
|
||||
context_menu (n);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
_slots[n]->set_default_colors ();
|
||||
_slots[n]->follow_button->set_fill_color (HSV (fill_color ()).lighter (0.15).color ());
|
||||
}
|
||||
break;
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
|
||||
_slots[n]->set_default_colors ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TriggerBoxUI::context_menu (uint64_t n)
|
||||
{
|
||||
@ -918,7 +989,7 @@ TriggerBoxUI::drag_motion (Glib::RefPtr<Gdk::DragContext> const& context, int, i
|
||||
ev.detail = GDK_NOTIFY_ANCESTOR;
|
||||
for (size_t i = 0; i < _slots.size (); ++i) {
|
||||
ev.type = (i == n) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY;
|
||||
text_button_event ((GdkEvent*)&ev, i);
|
||||
name_button_event ((GdkEvent*)&ev, i);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
@ -934,7 +1005,7 @@ TriggerBoxUI::drag_leave (Glib::RefPtr<Gdk::DragContext> const&, guint)
|
||||
ev.type = GDK_LEAVE_NOTIFY;
|
||||
ev.detail = GDK_NOTIFY_ANCESTOR;
|
||||
for (size_t i = 0; i < _slots.size (); ++i) {
|
||||
text_button_event ((GdkEvent*)&ev, i);
|
||||
name_button_event ((GdkEvent*)&ev, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +57,13 @@ public:
|
||||
}
|
||||
|
||||
ArdourCanvas::Rectangle* play_button;
|
||||
ArdourCanvas::Polygon* play_shape;
|
||||
|
||||
ArdourCanvas::Rectangle* name_button;
|
||||
ArdourCanvas::Rectangle* follow_button;
|
||||
ArdourCanvas::Text* name_text;
|
||||
|
||||
void draw_launch_icon (Cairo::RefPtr<Cairo::Context> context, float size, float scale) const;
|
||||
void draw_follow_icon (Cairo::RefPtr<Cairo::Context> context, ARDOUR::Trigger::FollowAction icon, float size, float scale) const;
|
||||
|
||||
void render (ArdourCanvas::Rect const& area, Cairo::RefPtr<Cairo::Context> context) const;
|
||||
|
||||
void _size_allocate (ArdourCanvas::Rect const&);
|
||||
@ -78,7 +80,6 @@ private:
|
||||
|
||||
PBD::ScopedConnection trigger_prop_connection;
|
||||
void prop_change (PBD::PropertyChange const& change);
|
||||
void shape_play_button ();
|
||||
|
||||
PBD::ScopedConnection owner_prop_connection;
|
||||
void owner_prop_change (PBD::PropertyChange const&);
|
||||
@ -121,7 +122,8 @@ private:
|
||||
static void register_actions ();
|
||||
|
||||
bool play_button_event (GdkEvent*, uint64_t);
|
||||
bool text_button_event (GdkEvent*, uint64_t);
|
||||
bool name_button_event (GdkEvent*, uint64_t);
|
||||
bool follow_button_event (GdkEvent*, uint64_t);
|
||||
|
||||
void choose_sample (uint64_t n);
|
||||
void sample_chosen (int r, uint64_t n);
|
||||
|
Loading…
Reference in New Issue
Block a user