// title: Switch // author: Dindoléon // description: // Demo of a custom switch button, allowing you to cycle between several states. Connect to a function using view.bindFunction( function ). Supports layout integration, colors customisation, states and current state reassignment. // code: ( var win = Window( "Switch", Rect( 0, 300, 200, 300 ) ); var switch; var demo_view = UserView(); var demo_string = "Hello World"; var demo_states = [ ["Never", Color.black, Color.white, Color.red ], ["Gonna", Color.black, Color.white, Color.green ] ].asList; ~get_switch = { | input_states, default_state, font, has_inside_margin | var switch = UserView(); var states = input_states; var current_state = default_state; var border_color2_ratio = 0.5; var binded_function = nil; switch.drawFunc = { | view | var margin = view.bounds.height * 0.01; if( margin < 4, { margin = 4 } ); Pen.fillColor_( states[current_state][2] ); Pen.fillRect( Rect( 0, 0, view.bounds.width, view.bounds.height ) ); Pen.fillColor_( Color( states[current_state][2].red * border_color2_ratio, states[current_state][2].green * border_color2_ratio, states[current_state][2].blue * border_color2_ratio ) ); Pen.fillRect( Rect( margin / 2, margin / 2, view.bounds.width - margin, view.bounds.height - margin ) ); if( has_inside_margin, { Pen.fillColor_( Color.black ); Pen.fillRect( Rect( margin, margin, view.bounds.width - ( margin * 2 ), view.bounds.height - ( margin * 2 ) ) ); margin = margin * 2; } ); Pen.fillColor_( states[current_state][3] ); Pen.fillRect( Rect( margin, margin, view.bounds.width - ( margin * 2 ), view.bounds.height - ( margin * 2 ) ) ); Pen.stringCenteredIn( states[current_state][0], Rect( 0, 0, view.bounds.width, view.bounds.height, ), font, states[current_state][1] ); }; switch.mouseDownAction = { current_state = current_state + 1; if( current_state == states.size, { current_state = 0 } ); if( binded_function != nil, { binded_function.value( current_state ) } ); switch.refresh }; switch.addUniqueMethod( \bindFunction, { | object, function | binded_function = function } ); switch.addUniqueMethod( \updateStates, { | object, new_states | states = new_states; if( current_state >= states.size, { current_state = 0 } ); switch.refresh; } ); switch.addUniqueMethod( \setState, { | object, new_state | if( ( ( new_state >= 0 ) && ( new_state <= states.size ) ), { current_state = new_state; switch.refresh; } ); } ); switch.addUniqueMethod( \valueState, { | object, new_state | if( ( ( new_state >= 0 ) && ( new_state <= states.size ) ), { current_state = new_state; if( binded_function != nil, { binded_function.value( current_state ) } ); switch.refresh; } ); } ); switch }; demo_states.add( ["Give", Color.black, Color.white, Color.blue ] ); demo_view.drawFunc = { | view | Pen.stringCenteredIn( demo_string, Rect( 0, 0, view.bounds.width, view.bounds.height ) ) }; demo_states.add( ["You", Color.black, Color.white, Color.cyan ] ); switch = ~get_switch.value( demo_states, 0, Font.default, true ); demo_states.add( ["Up", Color.black, Color.white, Color.magenta ] ); switch.updateStates( demo_states ); switch.bindFunction( { | index | demo_string = demo_states[ index ][0]; demo_view.refresh; } ); switch.valueState( 0 ); win.layout_( VLayout( demo_view, switch ) ); win.front )