// title: Color Picker, pretty version // author: Dindoléon // description: // See https://sccode.org/1-5fa . Hue slider now updated when changing saturation. Strange bug causing the sliders colors to vary when window is resized, please comment if you figure out how to fix it... // code: ( var win = Window( "Color Picker", Rect( 0, 300, 600, 300 ) ); var picker1; var picker2; var picker3; ~get_color_picker = { var color = Color( 1, 0, 0 ); var hsv = [ 0, 1, 1 ]; var color_picker_view = UserView(); // Main View var h_slider = UserView(); var h_slider_position = 0; var sv_slider = UserView(); var helper = UserView(); var binded_function = nil; var margin; // Slider half dead zone // HSV to Color function var hsv_to_color = { | hsv | var color = Color( 0, 0, 0 ); var h = hsv[0]; var s = hsv[1]; var v = hsv[2]; var c = s * v; var x = c * ( 1 - ( ( h/60.0 )%2.0 -1 ).abs ); var m = v - c; if( ( h >= 0 ) && ( h < 60 ), { color.red = c; color.green = x; color.blue = 0; } ); if( ( h >= 60 ) && ( h < 120 ), { color.red = x; color.green = c; color.blue = 0; } ); if( ( h >= 120 ) && ( h < 180 ), { color.red = 0; color.green = c; color.blue = x; } ); if( ( h >= 180 ) && ( h < 240 ), { color.red = 0; color.green = x; color.blue = c; } ); if( ( h >= 240 ) && ( h < 300 ), { color.red = x; color.green = 0; color.blue = c; } ); if( ( h >= 300 ) && ( h < 360 ), { color.red = c; color.green = 0; color.blue = x; } ); color.red = color.red + m; color.green = color.green + m; color.blue = color.blue + m; color; }; // Resizing adjustments color_picker_view.onResize = { | view | margin = ( view.bounds.width * 0.05 ); h_slider.refresh; sv_slider.refresh; }; // Hue Slider setup h_slider.background_( Color.black ); h_slider.drawFunc_( { | view | Pen.width = 1; ( view.bounds.height - ( margin * 2 ) ).do( { | index | Pen.strokeColor_( hsv_to_color.value( [ index.linlin( 0, ( view.bounds.height - ( margin * 2 ) ), 0, 360 ), hsv[1], hsv[2] ]; ); ); Pen.moveTo( Point( margin, index + margin ) ); Pen.lineTo( Point( view.bounds.width - margin, index + margin ) ); Pen.stroke; } ); Pen.addRect( Rect( margin / 2, margin / 2 + ( view.bounds.height - ( margin * 2 ) * h_slider_position ) + margin, view.bounds.width - margin, margin ) ); Pen.fillAxialGradient( Point( 0, margin / 2 + ( view.bounds.height - ( margin * 2 ) * h_slider_position ) + margin ), Point( 0, margin / 2 + ( view.bounds.height - ( margin * 2 ) * h_slider_position ) + ( margin * 2 ) ), Color( 0, 0, 0, 1 ), Color( 0, 0, 0, 0 ) ); Pen.addRect( Rect( margin / 2, margin / 2 + ( view.bounds.height - ( margin * 2 ) * h_slider_position ) - margin, view.bounds.width - margin, margin ) ); Pen.fillAxialGradient( Point( 0, margin / 2 + ( view.bounds.height - ( margin * 2 ) * h_slider_position ) - margin ), Point( 0, margin / 2 + ( view.bounds.height - ( margin * 2 ) * h_slider_position ) ), Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 1 ) ); Pen.fillColor_( color ); Pen.fillRect( Rect( margin / 2, margin / 2 + ( view.bounds.height - ( margin * 2 ) * h_slider_position ), view.bounds.width - margin, margin ) ) } ); h_slider.mouseDownAction_( { | view, x, y | if( y >= margin, { if( y <= ( view.bounds.height - margin ), { h_slider_position = y.linlin( margin, view.bounds.height - margin, 0, 1 ); y = y.linlin( margin, view.bounds.height - margin, 0, 360 ); hsv[0] = y; color = hsv_to_color.value( hsv ); if( binded_function != nil, { binded_function.value( color ) } ); h_slider.refresh; helper.refresh; sv_slider.refresh; } ) } ) } ); h_slider.mouseMoveAction_( h_slider.mouseDownAction ); // Saturation Slider setup sv_slider.background_( Color.black ); sv_slider.drawFunc_( { | view | ( view.bounds.width - ( margin * 2 ) ).do( { | index_x | Pen.addRect( Rect( margin + index_x, margin, 1, view.bounds.height - ( margin * 2 ) ) ); Pen.fillAxialGradient( Point( 0, margin ), Point( 0, view.bounds.height - ( margin * 2 ) ), Color.black, hsv_to_color.value( [ hsv[0], index_x.linlin( 0, view.bounds.width, 0, 1 ), 1 ] ) ); } ); Pen.addWedge( Point( view.bounds.width - ( margin * 2 ) * hsv[1] + margin, view.bounds.height - ( margin * 2 ) * hsv[2] + margin, ), margin * 2, 0, 360 ); Pen.fillRadialGradient( Point( view.bounds.width - ( margin * 2 ) * hsv[1] + margin, view.bounds.height - ( margin * 2 ) * hsv[2] + margin, ), Point( view.bounds.width - ( margin * 2 ) * hsv[1] + margin, view.bounds.height - ( margin * 2 ) * hsv[2] + margin, ), margin, margin * 1.5, Color( 0, 0, 0, 1 ), Color( 0, 0, 0, 0 ) ); Pen.fillColor_( color ); Pen.addWedge( Point( view.bounds.width - ( margin * 2 ) * hsv[1] + margin, view.bounds.height - ( margin * 2 ) * hsv[2] + margin, ), margin, 0, 360 ); Pen.fill; } ); sv_slider.mouseDownAction_( { | view, x, y | case { x < margin } { hsv[1] = 0 } { x > ( view.bounds.width + margin ) } { hsv[1] = 1 } { ( ( x >= margin ) && ( x <= ( view.bounds.width - margin ) ) ) } { hsv[1] = x.linlin( margin, view.bounds.width - margin, 0, 1 ); }; case { y < margin } { hsv[2] = 0 } { y > ( view.bounds.height + margin ) } { hsv[2] = 1 } { ( ( y >= margin ) && ( y <= ( view.bounds.height - margin ) ) ) } { hsv[2] = y.linlin( margin, view.bounds.height - margin, 0, 1 ); }; color = hsv_to_color.value( hsv ); if( binded_function != nil, { binded_function.value( color ) } ); helper.refresh; sv_slider.refresh; h_slider.refresh; } ); sv_slider.mouseMoveAction_( sv_slider.mouseDownAction ); helper.drawFunc_( { | view | Pen.fillColor_( color ); Pen.fillRect( Rect( 0, 0, view.bounds.width, view.bounds.height ) ) } ); // Background Color color_picker_view.background_( Color.black ); color_picker_view.layout_( VLayout( [ helper, stretch:1 ], [ HLayout( [ h_slider, stretch: 1 ], [ sv_slider, stretch: 2 ] ), stretch:2 ] ); ); color_picker_view.addUniqueMethod( \bindFunction, { | object, function | binded_function = function } ); color_picker_view }; picker1 = ~get_color_picker.value(); picker2 = ~get_color_picker.value(); picker3 = ~get_color_picker.value(); win.layout_( HLayout( picker1, picker2, picker3 ) ); win.background_( Color( 0.2, 0.2, 0.2 ) ); win.front )