2021-07-21 18:44:41 -04:00
/*
* Copyright ( C ) 2021 Paul Davis < paul @ linuxaudiosystems . 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 .
*/
2021-12-13 16:51:16 -05:00
# include <vector>
2021-08-05 14:11:19 -04:00
# include <gtkmm/filechooserdialog.h>
2021-08-05 17:04:02 -04:00
# include <gtkmm/menu.h>
# include <gtkmm/menuitem.h>
2021-08-05 14:11:19 -04:00
# include <gtkmm/stock.h>
2021-07-27 22:39:55 -04:00
# include "pbd/compose.h"
2021-07-28 00:40:35 -04:00
# include "pbd/convert.h"
2021-12-17 18:17:58 -05:00
# include "pbd/unwind.h"
2021-07-27 22:39:55 -04:00
2021-07-28 00:40:35 -04:00
# include "ardour/region.h"
2021-07-21 19:22:09 -04:00
# include "ardour/triggerbox.h"
2021-07-27 22:39:55 -04:00
# include "canvas/polygon.h"
# include "canvas/text.h"
2021-11-01 14:10:15 -04:00
# include "gtkmm2ext/actions.h"
2021-10-17 19:58:08 -04:00
# include "gtkmm2ext/colors.h"
2021-07-21 19:22:09 -04:00
# include "gtkmm2ext/utils.h"
2021-08-05 17:04:02 -04:00
# include "ardour_ui.h"
2021-08-05 18:20:56 -04:00
# include "gui_thread.h"
2021-08-05 17:04:02 -04:00
# include "public_editor.h"
2021-10-24 11:25:49 -04:00
# include "region_view.h"
# include "selection.h"
2021-10-04 01:47:47 -04:00
# include "timers.h"
2021-12-17 10:32:52 -05:00
# include "trigger_ui.h"
# include "triggerbox_ui.h"
2021-07-28 00:40:35 -04:00
# include "ui_config.h"
2021-08-05 17:04:02 -04:00
# include "utils.h"
2021-07-21 18:44:41 -04:00
2021-09-27 10:28:10 -04:00
# include "pbd/i18n.h"
2021-07-21 18:44:41 -04:00
using namespace ARDOUR ;
using namespace ArdourCanvas ;
2021-07-21 19:22:09 -04:00
using namespace Gtkmm2ext ;
2021-07-28 00:40:35 -04:00
using namespace PBD ;
2021-07-21 18:44:41 -04:00
2021-12-21 15:38:22 -05:00
TriggerEntry : : TriggerEntry ( Item * item , TriggerReference tr )
2021-12-05 11:56:42 -05:00
: ArdourCanvas : : Rectangle ( item )
2021-12-21 15:38:22 -05:00
, tref ( tr )
2021-07-21 18:44:41 -04:00
{
2021-12-17 10:32:52 -05:00
set_layout_sensitive ( true ) ; // why???
2021-07-28 00:40:35 -04:00
2021-12-21 15:38:22 -05:00
name = string_compose ( " trigger %1 " , tref . slot ) ;
2021-10-19 16:41:05 -04:00
2021-12-05 11:56:42 -05:00
set_outline ( false ) ;
2021-07-21 18:44:41 -04:00
2021-08-13 19:08:23 -04:00
play_button = new ArdourCanvas : : Rectangle ( this ) ;
2021-12-21 14:31:37 -05:00
play_button - > set_outline ( false ) ;
2021-12-17 10:32:52 -05:00
play_button - > set_fill ( true ) ;
2021-12-21 15:38:22 -05:00
play_button - > name = string_compose ( " playbutton %1 " , tref . slot ) ;
2021-12-05 11:56:42 -05:00
play_button - > show ( ) ;
2021-07-21 19:22:09 -04:00
2021-12-21 14:31:37 -05:00
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 ( ) ;
2021-12-05 11:56:42 -05:00
name_button = new ArdourCanvas : : Rectangle ( this ) ;
name_button - > set_outline ( true ) ;
2021-12-17 10:32:52 -05:00
name_button - > set_fill ( true ) ;
2021-12-05 11:56:42 -05:00
name_button - > name = ( " slot_selector_button " ) ;
name_button - > show ( ) ;
name_text = new Text ( name_button ) ;
name_text - > set_ignore_events ( false ) ;
2021-12-17 10:32:52 -05:00
name_text - > show ( ) ;
2021-12-05 11:56:42 -05:00
/* watch for change in theme */
2021-12-17 10:32:52 -05:00
UIConfiguration : : instance ( ) . ParameterChanged . connect ( sigc : : mem_fun ( * this , & TriggerEntry : : ui_parameter_changed ) ) ;
set_default_colors ( ) ;
2021-08-05 18:20:56 -04:00
2021-12-21 15:38:22 -05:00
trigger ( ) - > PropertyChanged . connect ( trigger_prop_connection , MISSING_INVALIDATOR , boost : : bind ( & TriggerEntry : : prop_change , this , _1 ) , gui_context ( ) ) ;
2021-12-21 19:36:48 -05:00
tref . box . TriggerSwapped . connect ( trigger_swap_connection , MISSING_INVALIDATOR , boost : : bind ( & TriggerEntry : : trigger_swap , this , _1 ) , gui_context ( ) ) ;
2021-12-21 15:38:22 -05:00
dynamic_cast < Stripable * > ( tref . box . owner ( ) ) - > presentation_info ( ) . Change . connect ( owner_prop_connection , MISSING_INVALIDATOR , boost : : bind ( & TriggerEntry : : owner_prop_change , this , _1 ) , gui_context ( ) ) ;
2021-08-05 18:20:56 -04:00
2021-08-07 20:55:05 -04:00
PropertyChange changed ;
changed . add ( ARDOUR : : Properties : : name ) ;
changed . add ( ARDOUR : : Properties : : running ) ;
prop_change ( changed ) ;
2021-12-05 11:56:42 -05:00
2021-12-17 10:32:52 -05:00
selection_change ( ) ;
2021-07-27 22:39:55 -04:00
}
2021-07-27 19:08:31 -04:00
2021-07-27 22:39:55 -04:00
TriggerEntry : : ~ TriggerEntry ( )
{
2021-07-21 19:22:09 -04:00
}
2021-12-21 19:36:48 -05:00
void
TriggerEntry : : trigger_swap ( uint32_t n )
{
if ( n ! = tref . slot ) {
/* some other slot in the same box got swapped. we don't care */
return ;
}
trigger_prop_connection . disconnect ( ) ;
trigger ( ) - > PropertyChanged . connect ( trigger_prop_connection , MISSING_INVALIDATOR , boost : : bind ( & TriggerEntry : : prop_change , this , _1 ) , gui_context ( ) ) ;
prop_change ( Properties : : name ) ;
}
2021-10-17 19:58:08 -04:00
void
2021-12-17 10:32:52 -05:00
TriggerEntry : : owner_prop_change ( PropertyChange const & pc )
2021-10-17 19:58:08 -04:00
{
if ( pc . contains ( Properties : : color ) ) {
owner_color_changed ( ) ;
}
}
void
TriggerEntry : : owner_color_changed ( )
{
2021-12-17 10:32:52 -05:00
// TODO
2021-10-17 19:58:08 -04:00
}
2021-11-10 19:51:04 -05:00
void
TriggerEntry : : selection_change ( )
{
2021-12-17 10:32:52 -05:00
if ( PublicEditor : : instance ( ) . get_selection ( ) . selected ( this ) ) {
name_button - > set_outline_color ( UIConfiguration : : instance ( ) . color ( " alert:red " ) ) ;
2021-11-10 19:51:04 -05:00
} else {
2021-12-17 10:32:52 -05:00
set_default_colors ( ) ;
2021-11-10 19:51:04 -05:00
}
2021-10-07 09:47:55 -04:00
}
2021-10-04 01:47:47 -04:00
void
TriggerEntry : : maybe_update ( )
{
2021-12-17 10:32:52 -05:00
// what here?
2021-10-04 01:47:47 -04:00
}
2021-08-07 20:55:05 -04:00
void
2021-12-17 10:32:52 -05:00
TriggerEntry : : _size_allocate ( ArdourCanvas : : Rect const & alloc )
2021-10-03 18:46:39 -04:00
{
Rectangle : : _size_allocate ( alloc ) ;
2021-12-17 10:32:52 -05:00
const Distance width = _rect . width ( ) ;
const Distance height = _rect . height ( ) ;
2021-10-03 18:46:39 -04:00
2021-12-05 11:56:42 -05:00
play_button - > set ( ArdourCanvas : : Rect ( 0 , 0 , height , height ) ) ;
2021-12-21 14:31:37 -05:00
name_button - > set ( ArdourCanvas : : Rect ( height , 0 , width - height , height ) ) ;
follow_button - > set ( ArdourCanvas : : Rect ( width - height , 0 , width , height ) ) ;
2021-10-03 18:46:39 -04:00
2021-12-17 10:32:52 -05:00
const double scale = UIConfiguration : : instance ( ) . get_ui_scale ( ) ;
2021-12-17 18:17:58 -05:00
_poly_margin = 2. * scale ;
_poly_size = height - 2 * _poly_margin ;
2021-10-03 18:46:39 -04:00
2021-12-17 10:32:52 -05:00
float tleft = height ; // make room for the play button
2021-12-05 11:56:42 -05:00
2021-12-17 10:32:52 -05:00
name_text - > size_allocate ( ArdourCanvas : : Rect ( 0 , 0 , width , height ) ) ;
name_text - > set_position ( Duple ( tleft + _poly_margin , _poly_margin - 0.5 ) ) ;
name_text - > clamp_width ( width - height - height ) ;
2021-10-17 19:58:34 -04:00
2021-12-17 10:32:52 -05:00
/* font scale may have changed. uiconfig 'embeds' the ui-scale in the font */
name_text - > set_font_description ( UIConfiguration : : instance ( ) . get_NormalFont ( ) ) ;
2021-12-05 11:56:42 -05:00
}
2021-12-17 10:32:52 -05:00
void
2021-12-21 14:31:37 -05:00
TriggerEntry : : draw_follow_icon ( Cairo : : RefPtr < Cairo : : Context > context , Trigger : : FollowAction icon , float size , float scale ) const
2021-12-17 10:32:52 -05:00
{
context - > set_line_width ( 1 * scale ) ;
2021-12-14 21:35:28 -05:00
switch ( icon ) {
case Trigger : : Stop :
2021-12-17 10:32:52 -05:00
context - > rectangle ( 6 * scale , 6 * scale , size - 12 * scale , size - 12 * scale ) ;
context - > stroke ( ) ;
break ;
2021-12-14 21:35:28 -05:00
case Trigger : : Again :
2021-12-17 10:32:52 -05:00
context - > arc ( size / 2 , size / 2 , size * 0.20 , 60. * ( M_PI / 180.0 ) , 2 * M_PI ) ;
context - > stroke ( ) ;
context - > arc ( size / 2 + size * 0.2 , size / 2 , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
break ;
2021-12-14 21:35:28 -05:00
case Trigger : : NextTrigger :
2021-12-17 10:32:52 -05:00
context - > move_to ( size / 2 , 3 * scale ) ;
context - > line_to ( size / 2 , size - 5 * scale ) ;
context - > stroke ( ) ;
context - > arc ( size / 2 , size - 5 * scale , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
break ;
2021-12-14 21:35:28 -05:00
case Trigger : : PrevTrigger :
2021-12-17 10:32:52 -05:00
context - > move_to ( size / 2 , 5 * scale ) ;
context - > line_to ( size / 2 , size - 3 * scale ) ;
context - > stroke ( ) ;
context - > arc ( size / 2 , 5 * scale , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
break ;
2021-12-14 21:35:28 -05:00
case Trigger : : QueuedTrigger : {
Glib : : RefPtr < Pango : : Layout > layout = Pango : : Layout : : create ( context ) ;
2021-12-17 10:32:52 -05:00
layout - > set_font_description ( UIConfiguration : : instance ( ) . get_SmallMonospaceFont ( ) ) ;
2021-12-14 21:35:28 -05:00
layout - > set_text ( icon = = Trigger : : AnyTrigger ? " & " : " @ " ) ;
2021-12-17 10:32:52 -05:00
int tw , th ;
layout - > get_pixel_size ( tw , th ) ;
context - > move_to ( size / 2 , size / 2 ) ;
context - > rel_move_to ( - tw / 2 , - th / 2 ) ;
2021-12-14 21:35:28 -05:00
layout - > show_in_cairo_context ( context ) ;
} break ;
case Trigger : : AnyTrigger : {
2021-12-17 10:32:52 -05:00
context - > move_to ( size / 2 , 3 * scale ) ;
context - > line_to ( size / 2 , size - 3 * scale ) ;
context - > move_to ( size / 2 , size / 2 ) ;
context - > line_to ( size / 2 - 3 * scale , size / 2 ) ;
context - > stroke ( ) ;
context - > arc ( size / 2 , 4 * scale , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
context - > arc ( size / 2 , size - 3 * scale , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
context - > arc ( size / 2 - 3 * scale , size / 2 , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
2021-12-14 21:35:28 -05:00
} break ;
case Trigger : : OtherTrigger : {
2021-12-17 10:32:52 -05:00
context - > move_to ( size / 2 , 3 * scale ) ;
context - > line_to ( size / 2 , 7 * scale ) ;
context - > move_to ( size / 2 , size - 7 * scale ) ;
context - > line_to ( size / 2 , size - 3 * scale ) ;
context - > stroke ( ) ;
context - > arc ( size / 2 , 3 * scale , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
context - > arc ( size / 2 , size - 3 * scale , 1.5 * scale , 0 , 2 * M_PI ) ; // arrow head
context - > fill ( ) ;
2021-12-14 21:35:28 -05:00
} break ;
2021-12-23 23:29:37 -05:00
case Trigger : : None :
2021-12-14 21:35:28 -05:00
default :
2021-12-17 10:32:52 -05:00
break ;
2021-12-14 21:35:28 -05:00
}
}
2021-12-21 14:31:37 -05:00
void
2021-12-21 15:55:08 -05:00
TriggerEntry : : draw_launch_icon ( Cairo : : RefPtr < Cairo : : Context > context , float sz , float scale ) const
2021-12-21 14:31:37 -05:00
{
context - > set_line_width ( 1 * scale ) ;
2021-12-21 15:55:08 -05:00
float margin = 4 * scale ;
float size = sz - 2 * margin ;
2021-12-21 19:55:48 -05:00
if ( trigger ( ) - > active ( ) ) {
if ( trigger ( ) - > launch_style ( ) = = Trigger : : Toggle ) {
2021-12-21 14:31:37 -05:00
//clicking again will Stop this clip
set_source_rgba ( context , UIConfiguration : : instance ( ) . color ( " neutral:foreground " ) ) ;
2021-12-21 15:55:08 -05:00
context - > move_to ( margin , margin ) ;
context - > rel_line_to ( size , 0 ) ;
context - > rel_line_to ( 0 , size ) ;
context - > rel_line_to ( - size , 0 ) ;
context - > rel_line_to ( 0 , - size ) ;
2021-12-21 14:31:37 -05:00
context - > fill ( ) ;
return ; //done
} else {
//actively playing; draw a filled play triangle
set_source_rgba ( context , UIConfiguration : : instance ( ) . color ( " neutral:foreground " ) ) ;
2021-12-21 15:55:08 -05:00
context - > move_to ( margin , margin ) ;
context - > rel_line_to ( 0 , size ) ;
context - > rel_line_to ( size , - size / 2 ) ;
2021-12-21 14:31:37 -05:00
context - > fill ( ) ;
return ; //done
}
}
set_source_rgba ( context , UIConfiguration : : instance ( ) . color ( " neutral:midground " ) ) ;
2021-12-21 19:55:48 -05:00
if ( ! trigger ( ) - > region ( ) ) {
2021-12-21 14:31:37 -05:00
//no content in this slot, it is only a Stop button
2021-12-21 15:55:08 -05:00
context - > move_to ( margin , margin ) ;
context - > rel_line_to ( size , 0 ) ;
context - > rel_line_to ( 0 , size ) ;
context - > rel_line_to ( - size , 0 ) ;
context - > rel_line_to ( 0 , - size ) ;
2021-12-21 14:31:37 -05:00
context - > stroke ( ) ;
return ; //done
}
2021-12-21 19:55:48 -05:00
switch ( trigger ( ) - > launch_style ( ) ) {
2021-12-21 14:31:37 -05:00
case Trigger : : Toggle :
case Trigger : : OneShot :
2021-12-21 15:55:08 -05:00
context - > move_to ( margin , margin ) ;
context - > rel_line_to ( 0 , size ) ;
context - > rel_line_to ( size , - size / 2 ) ;
context - > line_to ( margin , margin ) ;
2021-12-21 14:31:37 -05:00
context - > stroke ( ) ;
break ;
case Trigger : : Gate : //diamond shape
2021-12-21 15:55:08 -05:00
context - > move_to ( margin + size / 2 , margin ) ;
context - > rel_line_to ( size / 2 , size / 2 ) ;
context - > rel_line_to ( - size / 2 , size / 2 ) ;
context - > rel_line_to ( - size / 2 , - size / 2 ) ;
context - > rel_line_to ( size / 2 , - size / 2 ) ;
2021-12-21 14:31:37 -05:00
context - > stroke ( ) ;
break ;
case Trigger : : Repeat : //'stutter' shape
2021-12-22 13:29:28 -05:00
set_source_rgba ( context , HSV ( UIConfiguration : : instance ( ) . color ( " neutral:midground " ) ) . lighter ( 0.25 ) . color ( ) ) ; //stutter shape needs to be brighter to maintain balance
2021-12-21 14:31:37 -05:00
context - > set_line_width ( 1 * scale ) ;
2021-12-21 15:55:08 -05:00
context - > move_to ( margin , margin ) ;
context - > rel_line_to ( 0 , size ) ;
2021-12-21 14:31:37 -05:00
2021-12-21 15:55:08 -05:00
context - > move_to ( margin + scale * 3 , margin + scale * 2 ) ;
context - > rel_line_to ( 0 , size - scale * 4 ) ;
2021-12-21 14:31:37 -05:00
2021-12-21 15:55:08 -05:00
context - > move_to ( margin + scale * 6 , margin + scale * 3 ) ;
context - > rel_line_to ( 0 , size - scale * 6 ) ;
2021-12-21 14:31:37 -05:00
context - > stroke ( ) ;
break ;
default :
break ;
}
context - > set_line_width ( 1 ) ;
}
2021-12-05 11:56:42 -05:00
void
2021-12-17 10:32:52 -05:00
TriggerEntry : : render ( ArdourCanvas : : Rect const & area , Cairo : : RefPtr < Cairo : : Context > context ) const
2021-12-05 11:56:42 -05:00
{
2021-12-17 10:32:52 -05:00
Rectangle : : render ( area , context ) ;
2021-12-12 12:20:11 -05:00
/* Note that item_to_window() already takes _position into account (as
part of item_to_canvas ( )
*/
2021-12-17 10:32:52 -05:00
ArdourCanvas : : Rect self ( item_to_window ( _rect ) ) ;
2021-12-15 11:32:58 -05:00
const ArdourCanvas : : Rect draw = self . intersection ( area ) ;
2021-12-12 12:20:11 -05:00
if ( ! draw ) {
return ;
}
2021-12-17 10:32:52 -05:00
float width = _rect . width ( ) ;
float height = _rect . height ( ) ;
2021-12-12 12:20:11 -05:00
2021-12-17 10:32:52 -05:00
const double scale = UIConfiguration : : instance ( ) . get_ui_scale ( ) ;
2021-12-12 12:20:11 -05:00
if ( _fill & & ! _transparent ) {
setup_fill_context ( context ) ;
2021-12-17 10:32:52 -05:00
context - > rectangle ( draw . x0 , draw . y0 , draw . width ( ) , draw . height ( ) ) ;
2021-12-12 12:20:11 -05:00
context - > fill ( ) ;
}
render_children ( area , context ) ;
2021-12-21 15:38:22 -05:00
if ( trigger ( ) - > scene_isolated ( ) ) {
2021-12-17 18:17:58 -05:00
/* left shadow */
context - > set_identity_matrix ( ) ;
context - > translate ( self . x0 , self . y0 - 0.5 ) ;
Cairo : : RefPtr < Cairo : : LinearGradient > l_shadow = Cairo : : LinearGradient : : create ( 0 , 0 , scale * 12 , 0 ) ;
l_shadow - > add_color_stop_rgba ( 0.0 , 0.0 , 0.0 , 0.0 , 0.8 ) ;
l_shadow - > add_color_stop_rgba ( 1.0 , 0.0 , 0.0 , 0.0 , 0.0 ) ;
2021-12-17 10:45:34 -05:00
context - > set_source ( l_shadow ) ;
2021-12-17 18:17:58 -05:00
context - > rectangle ( 0 , 0 , scale * 12 , height ) ;
2021-12-17 10:45:34 -05:00
context - > fill ( ) ;
2021-12-17 18:17:58 -05:00
context - > set_identity_matrix ( ) ;
2021-12-17 10:45:34 -05:00
}
2021-12-21 15:38:22 -05:00
if ( tref . slot = = 1 ) {
2021-12-17 18:17:58 -05:00
/* drop-shadow at top */
Cairo : : RefPtr < Cairo : : LinearGradient > drop_shadow_pattern = Cairo : : LinearGradient : : create ( 0.0 , 0.0 , 0.0 , 6 * scale ) ;
drop_shadow_pattern - > add_color_stop_rgba ( 0 , 0 , 0 , 0 , 0.7 ) ;
drop_shadow_pattern - > add_color_stop_rgba ( 1 , 0 , 0 , 0 , 0.0 ) ;
2021-12-17 09:18:06 -05:00
context - > set_source ( drop_shadow_pattern ) ;
2021-12-17 10:32:52 -05:00
context - > rectangle ( 0 , 0 , width , 6 * scale ) ;
2021-12-12 12:20:11 -05:00
context - > fill ( ) ;
2021-12-21 15:38:22 -05:00
} else if ( tref . slot % 2 = = 0 ) {
2021-12-17 10:32:52 -05:00
/* line at top */
context - > set_identity_matrix ( ) ;
context - > translate ( self . x0 , self . y0 - 0.5 ) ;
set_source_rgba ( context , rgba_to_color ( 0 , 0 , 0 , 1 ) ) ;
context - > rectangle ( 0 , 0 , width , 1 ) ;
2021-12-12 12:20:11 -05:00
context - > fill ( ) ;
2021-12-17 10:32:52 -05:00
context - > set_identity_matrix ( ) ;
2021-12-12 12:20:11 -05:00
}
2021-12-21 14:31:37 -05:00
/* 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 ( ) ;
}
2021-12-17 10:32:52 -05:00
/* follow-action icon */
2021-12-21 15:38:22 -05:00
if ( trigger ( ) - > region ( ) ) {
2021-12-17 10:32:52 -05:00
context - > set_identity_matrix ( ) ;
context - > translate ( self . x0 , self . y0 - 0.5 ) ;
context - > translate ( width - height , 0 ) ; // right side of the widget
set_source_rgba ( context , UIConfiguration : : instance ( ) . color ( " neutral:midground " ) ) ;
2021-12-21 15:38:22 -05:00
draw_follow_icon ( context , trigger ( ) - > follow_action ( 0 ) , height , scale ) ;
2021-12-17 10:32:52 -05:00
context - > set_identity_matrix ( ) ;
2021-12-14 21:35:28 -05:00
}
2021-10-03 18:46:39 -04:00
}
2021-08-05 18:20:56 -04:00
void
2021-12-17 10:32:52 -05:00
TriggerEntry : : prop_change ( PropertyChange const & change )
2021-08-05 18:20:56 -04:00
{
if ( change . contains ( ARDOUR : : Properties : : name ) ) {
2021-12-21 15:38:22 -05:00
if ( trigger ( ) - > region ( ) ) {
name_text - > set ( short_version ( trigger ( ) - > name ( ) , 16 ) ) ;
2021-08-05 18:20:56 -04:00
} else {
2021-08-07 20:55:05 -04:00
name_text - > set ( " " ) ;
}
}
2021-12-17 18:17:58 -05:00
PropertyChange interesting_stuff ;
2021-12-21 14:31:37 -05:00
interesting_stuff . add ( ARDOUR : : Properties : : name ) ;
interesting_stuff . add ( ARDOUR : : Properties : : launch_style ) ;
2021-12-17 18:17:58 -05:00
interesting_stuff . add ( ARDOUR : : Properties : : follow_action0 ) ;
interesting_stuff . add ( ARDOUR : : Properties : : isolated ) ;
2021-12-21 14:31:37 -05:00
interesting_stuff . add ( ARDOUR : : Properties : : running ) ;
2021-12-14 21:35:28 -05:00
2021-12-17 18:17:58 -05:00
if ( change . contains ( interesting_stuff ) ) {
redraw ( ) ;
2021-12-17 10:45:34 -05:00
}
2021-08-05 18:20:56 -04:00
}
2021-12-05 11:56:42 -05:00
void
TriggerEntry : : set_default_colors ( )
{
2021-12-17 10:32:52 -05:00
set_fill_color ( UIConfiguration : : instance ( ) . color ( " theme:bg " ) ) ;
play_button - > set_fill_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 " ) ) ;
2021-12-21 14:31:37 -05:00
follow_button - > set_fill_color ( UIConfiguration : : instance ( ) . color ( " theme:bg " ) ) ;
2021-12-21 15:38:22 -05:00
if ( ( tref . slot / 2 ) % 2 = = 0 ) {
2021-12-17 10:32:52 -05:00
set_fill_color ( HSV ( fill_color ( ) ) . darker ( 0.15 ) . color ( ) ) ;
play_button - > set_fill_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 ( ) ) ;
2021-12-21 14:31:37 -05:00
follow_button - > set_fill_color ( HSV ( fill_color ( ) ) . darker ( 0.15 ) . color ( ) ) ;
2021-12-17 10:32:52 -05:00
}
name_text - > set_color ( UIConfiguration : : instance ( ) . color ( " neutral:foreground " ) ) ;
name_text - > set_fill_color ( UIConfiguration : : instance ( ) . color ( " neutral:midground " ) ) ;
2021-12-05 11:56:42 -05:00
/*preserve selection border*/
2021-12-17 10:32:52 -05:00
if ( PublicEditor : : instance ( ) . get_selection ( ) . selected ( this ) ) {
name_button - > set_outline_color ( UIConfiguration : : instance ( ) . color ( " alert:red " ) ) ;
2021-12-05 11:56:42 -05:00
}
}
void
TriggerEntry : : ui_parameter_changed ( std : : string const & p )
{
if ( p = = " color-file " ) {
2021-12-17 10:32:52 -05:00
set_default_colors ( ) ;
2021-12-05 11:56:42 -05:00
}
}
2021-12-17 10:32:52 -05:00
Gtkmm2ext : : Bindings * TriggerBoxUI : : bindings = 0 ;
2021-11-01 14:10:15 -04:00
Glib : : RefPtr < Gtk : : ActionGroup > TriggerBoxUI : : trigger_actions ;
2021-07-21 19:22:09 -04:00
TriggerBoxUI : : TriggerBoxUI ( ArdourCanvas : : Item * parent , TriggerBox & tb )
2021-12-05 11:56:42 -05:00
: Rectangle ( parent )
2021-07-21 19:22:09 -04:00
, _triggerbox ( tb )
2021-12-17 10:32:52 -05:00
, _file_chooser ( 0 )
2021-12-21 15:14:03 -05:00
, _launch_context_menu ( 0 )
, _follow_context_menu ( 0 )
2021-08-07 17:18:59 -04:00
, _context_menu ( 0 )
2021-12-17 10:45:34 -05:00
, _ignore_menu_action ( false )
2021-07-21 18:44:41 -04:00
{
2021-12-17 10:32:52 -05:00
set_layout_sensitive ( true ) ; // why???
2021-12-05 11:56:42 -05:00
2021-12-17 10:32:52 -05:00
set_fill_color ( UIConfiguration : : instance ( ) . color ( X_ ( " theme:bg " ) ) ) ;
2021-08-31 16:50:55 -04:00
set_fill ( true ) ;
2021-07-21 19:22:09 -04:00
build ( ) ;
2021-11-10 19:51:04 -05:00
2021-12-17 10:32:52 -05:00
_selection_connection = PublicEditor : : instance ( ) . get_selection ( ) . TriggersChanged . connect ( sigc : : mem_fun ( * this , & TriggerBoxUI : : selection_changed ) ) ;
2021-12-13 16:51:16 -05:00
std : : vector < Gtk : : TargetEntry > target_table ;
target_table . push_back ( Gtk : : TargetEntry ( " regions " ) ) ;
target_table . push_back ( Gtk : : TargetEntry ( " text/uri-list " ) ) ;
target_table . push_back ( Gtk : : TargetEntry ( " text/plain " ) ) ;
target_table . push_back ( Gtk : : TargetEntry ( " application/x-rootwin-drop " ) ) ;
2021-12-17 10:32:52 -05:00
GtkCanvas * gtkcanvas = static_cast < GtkCanvas * > ( canvas ( ) ) ;
2021-12-13 16:51:16 -05:00
assert ( gtkcanvas ) ;
gtkcanvas - > drag_dest_set ( target_table ) ;
2021-12-17 10:32:52 -05:00
gtkcanvas - > signal_drag_motion ( ) . connect ( sigc : : mem_fun ( * this , & TriggerBoxUI : : drag_motion ) ) ;
gtkcanvas - > signal_drag_leave ( ) . connect ( sigc : : mem_fun ( * this , & TriggerBoxUI : : drag_leave ) ) ;
gtkcanvas - > signal_drag_data_received ( ) . connect ( sigc : : mem_fun ( * this , & TriggerBoxUI : : drag_data_received ) ) ;
2021-07-21 18:44:41 -04:00
}
TriggerBoxUI : : ~ TriggerBoxUI ( )
{
2021-12-17 11:53:54 -05:00
/* sigc connection's are not scoped (i.e. they do not disconnect the
functor from the signal when they are destroyed ) .
*/
2021-12-17 11:10:36 -05:00
_selection_connection . disconnect ( ) ;
2021-12-17 11:53:54 -05:00
_update_connection . disconnect ( ) ;
2021-11-10 19:51:04 -05:00
}
void
TriggerBoxUI : : selection_changed ( )
{
2021-12-17 10:32:52 -05:00
for ( auto & slot : _slots ) {
2021-11-10 19:51:04 -05:00
slot - > selection_change ( ) ;
}
2021-07-21 18:44:41 -04:00
}
2021-07-21 19:22:09 -04:00
2021-11-01 14:10:15 -04:00
void
TriggerBoxUI : : setup_actions_and_bindings ( )
{
load_bindings ( ) ;
register_actions ( ) ;
}
void
TriggerBoxUI : : load_bindings ( )
{
bindings = Bindings : : get_bindings ( X_ ( " Triggers " ) ) ;
}
void
TriggerBoxUI : : register_actions ( )
{
trigger_actions = ActionManager : : create_action_group ( bindings , X_ ( " Triggers " ) ) ;
2021-11-03 20:44:31 -04:00
for ( int32_t n = 0 ; n < TriggerBox : : default_triggers_per_box ; + + n ) {
2021-12-17 10:32:52 -05:00
const std : : string action_name = string_compose ( " trigger-scene-%1 " , n ) ;
2021-11-03 20:44:31 -04:00
const std : : string display_name = string_compose ( _ ( " Scene %1 " ) , n ) ;
2021-12-17 10:32:52 -05:00
ActionManager : : register_toggle_action ( trigger_actions , action_name . c_str ( ) , display_name . c_str ( ) , sigc : : bind ( sigc : : ptr_fun ( TriggerBoxUI : : trigger_scene ) , n ) ) ;
2021-11-03 20:44:31 -04:00
}
2021-11-01 14:10:15 -04:00
}
void
TriggerBoxUI : : trigger_scene ( int32_t n )
{
TriggerBox : : scene_bang ( n ) ;
}
2021-07-21 19:22:09 -04:00
void
TriggerBoxUI : : build ( )
{
2021-12-21 15:38:22 -05:00
TriggerPtr t ;
2021-09-10 15:12:40 -04:00
uint64_t n = 0 ;
2021-07-21 19:22:09 -04:00
2021-07-22 12:33:47 -04:00
// clear_items (true);
2021-07-21 19:22:09 -04:00
2021-07-27 22:39:55 -04:00
_slots . clear ( ) ;
2021-07-21 19:22:09 -04:00
while ( true ) {
t = _triggerbox . trigger ( n ) ;
if ( ! t ) {
break ;
}
2021-12-21 15:38:22 -05:00
TriggerEntry * te = new TriggerEntry ( this , TriggerReference ( _triggerbox , n ) ) ;
2021-07-27 22:39:55 -04:00
_slots . push_back ( te ) ;
2021-12-21 14:31:37 -05:00
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
2021-12-17 10:32:52 -05:00
#if 0
te - > Event . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : event ) , n ) ) ;
# endif
2021-07-27 22:39:55 -04:00
2021-07-27 19:08:31 -04:00
+ + n ;
2021-07-21 19:22:09 -04:00
}
}
2021-12-05 11:56:42 -05:00
void
2021-12-17 10:32:52 -05:00
TriggerBoxUI : : _size_allocate ( ArdourCanvas : : Rect const & alloc )
2021-08-05 14:11:19 -04:00
{
2021-12-05 11:56:42 -05:00
Rectangle : : _size_allocate ( alloc ) ;
2021-12-17 10:32:52 -05:00
const float width = alloc . width ( ) ;
const float height = alloc . height ( ) ;
2021-12-05 11:56:42 -05:00
2021-12-17 10:32:52 -05:00
const float slot_h = height / TriggerBox : : default_triggers_per_box ; // TODO
2021-12-05 11:56:42 -05:00
float ypos = 0 ;
2021-12-17 10:32:52 -05:00
for ( auto & slot : _slots ) {
slot - > size_allocate ( ArdourCanvas : : Rect ( 0 , 0 , width , slot_h ) ) ;
2021-12-05 11:56:42 -05:00
slot - > set_position ( Duple ( 0 , ypos ) ) ;
ypos + = slot_h ;
2021-12-17 10:32:52 -05:00
slot - > show ( ) ;
2021-12-05 11:56:42 -05:00
}
2021-08-05 14:11:19 -04:00
}
2021-08-05 17:04:02 -04:00
bool
2021-12-21 14:31:37 -05:00
TriggerBoxUI : : name_button_event ( GdkEvent * ev , uint64_t n )
2021-08-05 17:04:02 -04:00
{
switch ( ev - > type ) {
2021-12-17 10:32:52 -05:00
case GDK_ENTER_NOTIFY :
if ( ev - > crossing . detail ! = GDK_NOTIFY_INFERIOR ) {
2021-12-21 14:31:37 -05:00
_slots [ n ] - > set_default_colors ( ) ;
2021-12-17 10:32:52 -05:00
_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 ( ) ) ;
2021-12-21 14:31:37 -05:00
_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 ( ) ) ;
2021-12-21 15:55:08 -05:00
/*preserve selection border*/
if ( PublicEditor : : instance ( ) . get_selection ( ) . selected ( _slots [ n ] ) ) {
_slots [ n ] - > name_button - > set_outline_color ( UIConfiguration : : instance ( ) . color ( " alert:red " ) ) ;
}
2021-12-17 10:32:52 -05:00
}
break ;
case GDK_LEAVE_NOTIFY :
if ( ev - > crossing . detail ! = GDK_NOTIFY_INFERIOR ) {
_slots [ n ] - > set_default_colors ( ) ;
}
break ;
case GDK_BUTTON_PRESS :
2021-12-21 16:20:05 -05:00
PublicEditor : : instance ( ) . get_selection ( ) . set ( _slots [ 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 ( UIConfiguration : : instance ( ) . color ( " alert:red " ) ) ;
_slots [ n ] - > follow_button - > set_fill_color ( HSV ( fill_color ( ) ) . lighter ( 0.15 ) . color ( ) ) ;
2021-12-17 10:32:52 -05:00
break ;
case GDK_2BUTTON_PRESS :
edit_trigger ( n ) ;
2021-08-05 17:04:02 -04:00
return true ;
2021-12-17 10:32:52 -05:00
case GDK_BUTTON_RELEASE :
switch ( ev - > button . button ) {
case 3 :
context_menu ( n ) ;
return true ;
default :
break ;
}
break ;
2021-08-05 17:04:02 -04:00
default :
break ;
}
return false ;
}
2021-07-27 22:39:55 -04:00
bool
2021-12-17 10:32:52 -05:00
TriggerBoxUI : : play_button_event ( GdkEvent * ev , uint64_t n )
2021-07-27 22:39:55 -04:00
{
2021-12-17 10:32:52 -05:00
if ( ! _triggerbox . trigger ( n ) - > region ( ) ) {
2021-12-21 14:31:37 -05:00
/* empty slot; this is just a stop button */
2021-08-06 23:27:38 -04:00
switch ( ev - > type ) {
2021-12-17 10:32:52 -05:00
case GDK_BUTTON_PRESS :
if ( ev - > button . button = = 1 ) {
2021-12-22 19:27:19 -05:00
_triggerbox . stop_all_immediately ( ) ;
2021-12-17 10:32:52 -05:00
return true ;
}
2021-12-17 18:17:58 -05:00
break ;
2021-12-17 10:32:52 -05:00
default :
break ;
2021-08-06 23:27:38 -04:00
}
}
2021-07-27 22:39:55 -04:00
switch ( ev - > type ) {
2021-12-17 10:32:52 -05:00
case GDK_BUTTON_PRESS :
switch ( ev - > button . button ) {
case 1 :
2021-12-21 15:38:22 -05:00
_slots [ n ] - > trigger ( ) - > bang ( ) ;
2021-12-17 10:32:52 -05:00
return true ;
default :
break ;
}
2021-08-05 17:04:02 -04:00
break ;
2021-12-17 10:32:52 -05:00
case GDK_BUTTON_RELEASE :
switch ( ev - > button . button ) {
case 1 :
2021-12-21 15:38:22 -05:00
if ( _slots [ n ] - > trigger ( ) - > launch_style ( ) = = Trigger : : Gate | |
_slots [ n ] - > trigger ( ) - > launch_style ( ) = = Trigger : : Repeat ) {
_slots [ n ] - > trigger ( ) - > unbang ( ) ;
2021-12-17 10:32:52 -05:00
}
break ;
2021-12-21 14:31:37 -05:00
case 3 :
2021-12-21 15:14:03 -05:00
launch_context_menu ( n ) ;
2021-12-21 14:31:37 -05:00
return true ;
2021-12-17 10:32:52 -05:00
default :
break ;
}
break ;
case GDK_ENTER_NOTIFY :
if ( ev - > crossing . detail ! = GDK_NOTIFY_INFERIOR ) {
2021-12-21 14:31:37 -05:00
_slots [ n ] - > set_default_colors ( ) ;
2021-12-17 10:32:52 -05:00
_slots [ n ] - > play_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 ( ) ;
2021-08-05 17:04:02 -04:00
}
break ;
default :
break ;
2021-07-27 22:39:55 -04:00
}
return false ;
}
2021-12-21 14:31:37 -05:00
bool
TriggerBoxUI : : follow_button_event ( GdkEvent * ev , uint64_t n )
{
switch ( ev - > type ) {
case GDK_BUTTON_RELEASE :
switch ( ev - > button . button ) {
case 3 :
2021-12-21 15:14:03 -05:00
follow_context_menu ( n ) ;
2021-12-21 14:31:37 -05:00
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 ;
}
2021-08-05 17:04:02 -04:00
void
2021-09-10 15:12:40 -04:00
TriggerBoxUI : : context_menu ( uint64_t n )
2021-08-05 17:04:02 -04:00
{
using namespace Gtk ;
using namespace Gtk : : Menu_Helpers ;
using namespace Temporal ;
delete _context_menu ;
2021-12-17 10:32:52 -05:00
_context_menu = new Menu ;
MenuList & items = _context_menu - > items ( ) ;
2021-08-05 17:04:02 -04:00
_context_menu - > set_name ( " ArdourContextMenu " ) ;
2021-12-21 15:14:03 -05:00
Menu * load_menu = manage ( new Menu ) ;
MenuList & loitems ( load_menu - > items ( ) ) ;
loitems . push_back ( MenuElem ( _ ( " from file " ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : choose_sample ) , n ) ) ) ;
loitems . push_back ( MenuElem ( _ ( " from selection " ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_from_selection ) , n ) ) ) ;
items . push_back ( MenuElem ( _ ( " Load... " ) , * load_menu ) ) ;
2021-12-23 23:29:37 -05:00
# if DOUBLE_CLICK_IS_NOT_OBVIOUS_ENOUGH
2021-12-21 15:14:03 -05:00
items . push_back ( MenuElem ( _ ( " Edit... " ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : edit_trigger ) , n ) ) ) ;
2021-12-23 23:29:37 -05:00
# endif
items . push_back ( SeparatorElem ( ) ) ;
items . push_back ( MenuElem ( _ ( " Clear " ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : clear_trigger ) , n ) ) ) ;
2021-12-21 15:14:03 -05:00
_context_menu - > popup ( 1 , gtk_get_current_event_time ( ) ) ;
}
void
TriggerBoxUI : : launch_context_menu ( uint64_t n )
{
using namespace Gtk ;
using namespace Gtk : : Menu_Helpers ;
using namespace Temporal ;
delete _launch_context_menu ;
_launch_context_menu = new Menu ;
MenuList & items = _launch_context_menu - > items ( ) ;
_launch_context_menu - > set_name ( " ArdourContextMenu " ) ;
2021-08-05 17:04:02 -04:00
2021-10-17 11:54:40 -04:00
RadioMenuItem : : Group lagroup ;
RadioMenuItem : : Group qgroup ;
2021-12-17 10:32:52 -05:00
Menu * launch_menu = manage ( new Menu ) ;
MenuList & litems = launch_menu - > items ( ) ;
2021-08-05 17:04:02 -04:00
2021-12-23 23:17:06 -05:00
litems . push_back ( RadioMenuElem ( lagroup , TriggerUI : : launch_style_to_string ( Trigger : : OneShot ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_launch_style ) , n , Trigger : : OneShot ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > launch_style ( ) = = Trigger : : OneShot ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & litems . back ( ) ) - > set_active ( true ) ;
}
2021-12-23 23:17:06 -05:00
litems . push_back ( RadioMenuElem ( lagroup , TriggerUI : : launch_style_to_string ( Trigger : : Gate ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_launch_style ) , n , Trigger : : Gate ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > launch_style ( ) = = Trigger : : Gate ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & litems . back ( ) ) - > set_active ( true ) ;
}
2021-12-23 23:17:06 -05:00
litems . push_back ( RadioMenuElem ( lagroup , TriggerUI : : launch_style_to_string ( Trigger : : Toggle ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_launch_style ) , n , Trigger : : Toggle ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > launch_style ( ) = = Trigger : : Toggle ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & litems . back ( ) ) - > set_active ( true ) ;
}
2021-12-23 23:17:06 -05:00
litems . push_back ( RadioMenuElem ( lagroup , TriggerUI : : launch_style_to_string ( Trigger : : Repeat ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_launch_style ) , n , Trigger : : Repeat ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > launch_style ( ) = = Trigger : : Repeat ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & litems . back ( ) ) - > set_active ( true ) ;
}
2021-12-17 10:32:52 -05:00
Menu * quant_menu = manage ( new Menu ) ;
MenuList & qitems = quant_menu - > items ( ) ;
bool success ;
2021-08-05 17:04:02 -04:00
BBT_Offset b ;
2021-12-23 23:29:37 -05:00
# if TRIGGER_PAGE_GLOBAL_QUANTIZATION_IS_IMPLEMENTED
Beats grid_beats ( PublicEditor : : instance ( ) . get_grid_type_as_beats ( success , timepos_t ( 0 ) ) ) ;
2021-08-05 17:04:02 -04:00
if ( success ) {
2021-12-17 10:32:52 -05:00
b = BBT_Offset ( 0 , grid_beats . get_beats ( ) , grid_beats . get_ticks ( ) ) ;
2021-12-21 15:14:03 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , _ ( " Main Grid " ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-08-06 12:24:37 -04:00
/* can't mark this active because the current trigger quant setting may just a specific setting below */
/* XXX HOW TO GET THIS TO FOLLOW GRID CHANGES (which are GUI only) */
2021-08-05 17:04:02 -04:00
}
2021-12-23 23:29:37 -05:00
# endif
2021-08-05 17:04:02 -04:00
b = BBT_Offset ( 1 , 0 , 0 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
2021-08-06 12:24:37 -04:00
b = BBT_Offset ( 0 , 4 , 0 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-08-06 12:24:37 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
b = BBT_Offset ( 0 , 2 , 0 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-08-06 12:24:37 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
2021-08-05 17:04:02 -04:00
b = BBT_Offset ( 0 , 1 , 0 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-17 10:32:52 -05:00
b = BBT_Offset ( 0 , 0 , ticks_per_beat / 2 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-17 10:32:52 -05:00
b = BBT_Offset ( 0 , 0 , ticks_per_beat / 4 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-08-05 17:04:02 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-17 10:32:52 -05:00
b = BBT_Offset ( 0 , 0 , ticks_per_beat / 8 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-10-17 19:58:48 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-17 10:32:52 -05:00
b = BBT_Offset ( 0 , 0 , ticks_per_beat / 16 ) ;
2021-12-23 23:17:06 -05:00
qitems . push_back ( RadioMenuElem ( qgroup , TriggerUI : : quantize_length_to_string ( b ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_quantization ) , n , b ) ) ) ;
2021-12-17 10:32:52 -05:00
if ( _triggerbox . trigger ( n ) - > quantization ( ) = = b ) {
2021-10-17 19:58:48 -04:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & qitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-17 10:32:52 -05:00
Menu * load_menu = manage ( new Menu ) ;
MenuList & loitems ( load_menu - > items ( ) ) ;
2021-10-17 19:58:48 -04:00
2021-08-05 17:04:02 -04:00
items . push_back ( MenuElem ( _ ( " Launch Style... " ) , * launch_menu ) ) ;
items . push_back ( MenuElem ( _ ( " Quantization... " ) , * quant_menu ) ) ;
2021-12-17 10:45:34 -05:00
items . push_back ( CheckMenuElem ( _ ( " Cue Isolate " ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : toggle_trigger_isolated ) , n ) ) ) ;
2021-12-17 18:17:58 -05:00
if ( _triggerbox . trigger ( n ) - > scene_isolated ( ) ) {
PBD : : Unwinder < bool > uw ( _ignore_menu_action , true ) ;
2021-12-17 10:45:34 -05:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & items . back ( ) ) - > set_active ( true ) ;
}
2021-12-21 15:14:03 -05:00
_launch_context_menu - > popup ( 1 , gtk_get_current_event_time ( ) ) ;
2021-08-05 17:04:02 -04:00
}
2021-12-21 15:14:03 -05:00
void
TriggerBoxUI : : follow_context_menu ( uint64_t n )
{
using namespace Gtk ;
using namespace Gtk : : Menu_Helpers ;
using namespace Temporal ;
delete _follow_context_menu ;
_follow_context_menu = new Menu ;
MenuList & items = _follow_context_menu - > items ( ) ;
_follow_context_menu - > set_name ( " ArdourContextMenu " ) ;
Menu * follow_menu = manage ( new Menu ) ;
MenuList & fitems = follow_menu - > items ( ) ;
RadioMenuItem : : Group fagroup ;
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : None ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : None ) ) ) ;
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : None ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : Stop ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : Stop ) ) ) ;
2021-12-21 15:14:03 -05:00
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : Stop ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : Again ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : Again ) ) ) ;
2021-12-21 15:14:03 -05:00
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : Again ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
# if QUEUED_SLOTS_IMPLEMENTED
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : QueuedTrigger ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : QueuedTrigger ) ) ) ;
2021-12-21 15:14:03 -05:00
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : QueuedTrigger ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
# endif
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : PrevTrigger ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : PrevTrigger ) ) ) ;
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : PrevTrigger ) {
2021-12-21 15:14:03 -05:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : NextTrigger ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : NextTrigger ) ) ) ;
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : NextTrigger ) {
2021-12-21 15:14:03 -05:00
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
#if 0
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : FirstTrigger ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : FirstTrigger ) ) ) ;
2021-12-21 15:14:03 -05:00
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : FirstTrigger ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : LastTrigger ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : LastTrigger ) ) ) ;
2021-12-21 15:14:03 -05:00
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : LastTrigger ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
# endif
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : AnyTrigger ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : AnyTrigger ) ) ) ;
2021-12-21 15:14:03 -05:00
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : AnyTrigger ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
2021-12-23 23:17:06 -05:00
fitems . push_back ( RadioMenuElem ( fagroup , TriggerUI : : follow_action_to_string ( Trigger : : OtherTrigger ) , sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : set_follow_action ) , n , Trigger : : OtherTrigger ) ) ) ;
2021-12-21 15:14:03 -05:00
if ( _triggerbox . trigger ( n ) - > follow_action ( 0 ) = = Trigger : : OtherTrigger ) {
dynamic_cast < Gtk : : CheckMenuItem * > ( & fitems . back ( ) ) - > set_active ( true ) ;
}
items . push_back ( MenuElem ( _ ( " Follow Action... " ) , * follow_menu ) ) ;
_follow_context_menu - > popup ( 1 , gtk_get_current_event_time ( ) ) ;
}
2021-12-17 10:45:34 -05:00
void
TriggerBoxUI : : toggle_trigger_isolated ( uint64_t n )
{
if ( _ignore_menu_action ) {
return ;
}
2021-12-21 15:38:22 -05:00
TriggerPtr trigger = _triggerbox . trigger ( n ) ;
2021-12-17 18:17:58 -05:00
trigger - > set_scene_isolated ( ! trigger - > scene_isolated ( ) ) ;
2021-12-17 10:45:34 -05:00
}
void
TriggerBoxUI : : clear_trigger ( uint64_t n )
{
2021-12-21 15:38:22 -05:00
TriggerPtr trigger = _triggerbox . trigger ( n ) ;
2021-12-22 00:35:59 -05:00
trigger - > set_region ( boost : : shared_ptr < Region > ( ) ) ;
2021-12-17 10:45:34 -05:00
}
2021-09-07 01:21:22 -04:00
void
2021-09-10 15:12:40 -04:00
TriggerBoxUI : : edit_trigger ( uint64_t n )
2021-09-07 01:21:22 -04:00
{
2021-12-21 15:38:22 -05:00
TriggerPtr trigger = _triggerbox . trigger ( n ) ;
2021-12-17 10:32:52 -05:00
TriggerWindow * tw = static_cast < TriggerWindow * > ( trigger - > ui ( ) ) ;
2021-09-10 15:05:19 -04:00
if ( ! tw ) {
2021-11-29 20:21:04 -05:00
tw = new TriggerWindow ( _triggerbox . trigger ( n ) ) ;
2021-09-10 15:05:19 -04:00
trigger - > set_ui ( tw ) ;
}
2021-09-07 01:21:22 -04:00
tw - > present ( ) ;
}
2021-08-05 17:04:02 -04:00
void
2021-09-10 15:12:40 -04:00
TriggerBoxUI : : set_follow_action ( uint64_t n , Trigger : : FollowAction fa )
2021-08-05 17:04:02 -04:00
{
2021-08-12 00:54:31 -04:00
_triggerbox . trigger ( n ) - > set_follow_action ( fa , 0 ) ;
2021-08-05 17:04:02 -04:00
}
void
2021-09-10 15:12:40 -04:00
TriggerBoxUI : : set_launch_style ( uint64_t n , Trigger : : LaunchStyle ls )
2021-08-05 17:04:02 -04:00
{
_triggerbox . trigger ( n ) - > set_launch_style ( ls ) ;
}
void
2021-12-17 10:32:52 -05:00
TriggerBoxUI : : set_quantization ( uint64_t n , Temporal : : BBT_Offset const & q )
2021-08-05 17:04:02 -04:00
{
_triggerbox . trigger ( n ) - > set_quantization ( q ) ;
}
2021-08-05 14:11:19 -04:00
void
2021-09-10 15:12:40 -04:00
TriggerBoxUI : : choose_sample ( uint64_t n )
2021-08-05 14:11:19 -04:00
{
2021-12-17 10:32:52 -05:00
if ( ! _file_chooser ) {
_file_chooser = new Gtk : : FileChooserDialog ( _ ( " Select sample " ) , Gtk : : FILE_CHOOSER_ACTION_OPEN ) ;
_file_chooser - > add_button ( Gtk : : Stock : : CANCEL , Gtk : : RESPONSE_CANCEL ) ;
_file_chooser - > add_button ( Gtk : : Stock : : OK , Gtk : : RESPONSE_OK ) ;
_file_chooser - > set_select_multiple ( true ) ;
2021-08-05 14:11:19 -04:00
}
2021-12-17 10:32:52 -05:00
_file_chooser_connection . disconnect ( ) ;
_file_chooser_connection = _file_chooser - > signal_response ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & TriggerBoxUI : : sample_chosen ) , n ) ) ;
2021-08-05 14:11:19 -04:00
2021-12-17 10:32:52 -05:00
_file_chooser - > present ( ) ;
2021-08-05 14:11:19 -04:00
}
void
2021-09-10 15:12:40 -04:00
TriggerBoxUI : : sample_chosen ( int response , uint64_t n )
2021-08-05 14:11:19 -04:00
{
2021-12-17 10:32:52 -05:00
_file_chooser - > hide ( ) ;
2021-08-05 14:11:19 -04:00
switch ( response ) {
2021-12-17 10:32:52 -05:00
case Gtk : : RESPONSE_OK :
break ;
default :
return ;
2021-08-05 14:11:19 -04:00
}
2021-12-17 10:32:52 -05:00
std : : list < std : : string > paths = _file_chooser - > get_filenames ( ) ;
2021-08-05 14:11:19 -04:00
2021-12-17 10:32:52 -05:00
for ( std : : list < std : : string > : : iterator s = paths . begin ( ) ; s ! = paths . end ( ) ; + + s ) {
2021-10-11 19:58:51 -04:00
/* this will do nothing if n is too large */
_triggerbox . set_from_path ( n , * s ) ;
+ + n ;
}
2021-08-05 14:11:19 -04:00
}
2021-12-13 18:45:16 -05:00
uint64_t
TriggerBoxUI : : slot_at_y ( int y ) const
2021-12-13 16:51:16 -05:00
{
2021-12-13 18:45:16 -05:00
uint64_t n = 0 ;
2021-12-13 17:05:03 -05:00
for ( auto & slot : _slots ) {
if ( slot - > height ( ) < y ) {
+ + n ;
y - = slot - > height ( ) ;
}
}
2021-12-13 18:45:16 -05:00
return n ;
}
bool
2021-12-17 10:32:52 -05:00
TriggerBoxUI : : drag_motion ( Glib : : RefPtr < Gdk : : DragContext > const & context , int , int y , guint time )
2021-12-13 18:45:16 -05:00
{
2021-12-17 10:32:52 -05:00
bool can_drop = true ;
uint64_t n = slot_at_y ( y ) ;
2021-12-13 18:45:16 -05:00
if ( n > = _slots . size ( ) ) {
assert ( 0 ) ;
can_drop = false ;
}
if ( can_drop ) {
2021-12-17 10:32:52 -05:00
context - > drag_status ( Gdk : : ACTION_COPY , time ) ;
2021-12-13 18:45:16 -05:00
/* prelight */
GdkEventCrossing ev ;
ev . detail = GDK_NOTIFY_ANCESTOR ;
for ( size_t i = 0 ; i < _slots . size ( ) ; + + i ) {
ev . type = ( i = = n ) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY ;
2021-12-21 14:31:37 -05:00
name_button_event ( ( GdkEvent * ) & ev , i ) ;
2021-12-13 18:45:16 -05:00
}
return true ;
} else {
context - > drag_status ( Gdk : : DragAction ( 0 ) , time ) ;
return false ;
}
}
void
2021-12-17 10:32:52 -05:00
TriggerBoxUI : : drag_leave ( Glib : : RefPtr < Gdk : : DragContext > const & , guint )
2021-12-13 18:45:16 -05:00
{
GdkEventCrossing ev ;
2021-12-17 10:32:52 -05:00
ev . type = GDK_LEAVE_NOTIFY ;
2021-12-13 18:45:16 -05:00
ev . detail = GDK_NOTIFY_ANCESTOR ;
for ( size_t i = 0 ; i < _slots . size ( ) ; + + i ) {
2021-12-21 14:31:37 -05:00
name_button_event ( ( GdkEvent * ) & ev , i ) ;
2021-12-13 18:45:16 -05:00
}
}
2021-12-13 17:05:03 -05:00
2021-12-13 18:45:16 -05:00
void
TriggerBoxUI : : drag_data_received ( Glib : : RefPtr < Gdk : : DragContext > const & context , int /*x*/ , int y , Gtk : : SelectionData const & data , guint /*info*/ , guint time )
{
uint64_t n = slot_at_y ( y ) ;
if ( n > = _slots . size ( ) ) {
context - > drag_finish ( false , false , time ) ;
return ;
}
2021-12-17 10:32:52 -05:00
if ( data . get_target ( ) = = X_ ( " regions " ) ) {
boost : : shared_ptr < Region > region = PublicEditor : : instance ( ) . get_dragged_region_from_sidebar ( ) ;
2021-12-13 16:51:16 -05:00
if ( region ) {
2021-12-13 17:05:03 -05:00
_triggerbox . set_from_selection ( n , region ) ;
2021-12-13 16:51:16 -05:00
context - > drag_finish ( true , false , time ) ;
2021-12-14 15:34:21 -05:00
} else {
context - > drag_finish ( false , false , time ) ;
2021-12-13 16:51:16 -05:00
}
return ;
}
std : : vector < std : : string > paths ;
if ( ARDOUR_UI_UTILS : : convert_drop_to_paths ( paths , data ) ) {
for ( std : : vector < std : : string > : : iterator s = paths . begin ( ) ; s ! = paths . end ( ) ; + + s ) {
/* this will do nothing if n is too large */
_triggerbox . set_from_path ( n , * s ) ;
+ + n ;
}
}
context - > drag_finish ( true , false , time ) ;
}
2021-10-24 11:25:49 -04:00
void
TriggerBoxUI : : set_from_selection ( uint64_t n )
{
2021-12-17 10:32:52 -05:00
Selection & selection ( PublicEditor : : instance ( ) . get_selection ( ) ) ;
2021-10-24 11:25:49 -04:00
RegionSelection rselection ( selection . regions ) ;
2021-12-17 10:32:52 -05:00
if ( rselection . empty ( ) ) {
2021-10-24 11:25:49 -04:00
/* XXX possible message about no selection ? */
return ;
}
2021-12-17 10:32:52 -05:00
for ( RegionSelection : : iterator r = rselection . begin ( ) ; r ! = rselection . end ( ) ; + + r ) {
_triggerbox . set_from_selection ( n , ( * r ) - > region ( ) ) ;
2021-10-24 11:25:49 -04:00
+ + n ;
}
}
2021-10-04 01:47:47 -04:00
void
TriggerBoxUI : : start_updating ( )
{
2021-12-17 10:32:52 -05:00
_update_connection = Timers : : rapid_connect ( sigc : : mem_fun ( * this , & TriggerBoxUI : : rapid_update ) ) ;
2021-10-04 01:47:47 -04:00
}
void
TriggerBoxUI : : stop_updating ( )
{
2021-12-17 10:32:52 -05:00
_update_connection . disconnect ( ) ;
2021-10-04 01:47:47 -04:00
}
void
TriggerBoxUI : : rapid_update ( )
{
2021-12-17 10:32:52 -05:00
for ( auto & slot : _slots ) {
2021-11-10 19:51:04 -05:00
slot - > maybe_update ( ) ;
2021-10-04 01:47:47 -04:00
}
}
2021-12-17 10:32:52 -05:00
TriggerBoxWidget : : TriggerBoxWidget ( float w , float h )
: FittedCanvasWidget ( w , h )
, ui ( 0 )
2021-07-21 19:22:09 -04:00
{
2021-12-17 10:32:52 -05:00
set_background_color ( UIConfiguration : : instance ( ) . color ( X_ ( " theme:bg " ) ) ) ;
2021-07-21 19:22:09 -04:00
}
2021-07-22 12:33:47 -04:00
2021-10-04 01:47:47 -04:00
void
2021-12-16 17:15:14 -05:00
TriggerBoxWidget : : set_triggerbox ( TriggerBox * tb )
2021-10-04 01:47:47 -04:00
{
2021-12-16 17:15:14 -05:00
if ( ui ) {
2021-12-17 10:32:52 -05:00
root ( ) - > remove ( ui ) ;
2021-12-16 17:15:14 -05:00
delete ui ;
ui = 0 ;
}
2021-10-04 01:47:47 -04:00
2021-12-16 17:15:14 -05:00
if ( ! tb ) {
return ;
}
2021-12-17 10:32:52 -05:00
ui = new TriggerBoxUI ( root ( ) , * tb ) ;
2021-12-16 20:55:05 -05:00
repeat_size_allocation ( ) ;
2021-12-16 17:15:14 -05:00
2021-12-17 10:32:52 -05:00
if ( is_mapped ( ) ) {
2021-12-16 17:15:14 -05:00
ui - > start_updating ( ) ;
}
2021-10-04 01:47:47 -04:00
}
2021-12-16 17:09:20 -05:00
void
TriggerBoxWidget : : on_map ( )
2021-07-22 12:33:47 -04:00
{
2021-12-16 17:09:20 -05:00
FittedCanvasWidget : : on_map ( ) ;
2021-08-05 17:04:02 -04:00
2021-12-16 17:09:20 -05:00
if ( ui ) {
ui - > start_updating ( ) ;
}
2021-08-05 17:04:02 -04:00
}
2021-12-16 17:09:20 -05:00
void
TriggerBoxWidget : : on_unmap ( )
2021-08-05 17:04:02 -04:00
{
2021-12-16 17:09:20 -05:00
FittedCanvasWidget : : on_unmap ( ) ;
if ( ui ) {
ui - > stop_updating ( ) ;
}
2021-08-05 17:04:02 -04:00
}