## SwingOSC – Java-based GUI classes

This class is meant as an emulation of the Knob class by blackrain. last mod: 03-feb-08 sciss
Also refer to JSCView and JSCUserView.

different behaviour
modifiers | drag-n-drop uses control modifier (as in all dnd ops). for vert mode, use shift key

# JKnob

`JKnob` is a gui control with round, horizontal or vertical action.

## Instantiation

    	JKnob.new( <parent>, <bounds> )

## Instance methods

- `value`, `value_( <val> )` – sets or gets the control's value.
- `valueAction_( <val> )` – sets the knob's `value` and performs the `action` function.
- `action_( <func> )` – sets a user defined action hook function. this gets called when the `value` is changed by the user or by calling `valueAction`. the function is called with arguments (`view`, `x`, `y`, `modifiers`).
- `mouseOverAction_( <func> )` – sets a user defined action hook function for mouse over events. this gets called with arguments (`view`, `x`, `y`). Note: `acceptsMouseOver` must be set to `true` in the parent window (see JSCWindow) for the hook to to work.
- `color` – Array of Colors: `[ <centerColor>, <valueColor>, <rangeColor>, <dialColor> ]`.
- `canFocus_( <state> )` – enables/disables focus gain for the control
- `mode_( <val> )` – knob's tracking mode. can be `\round`, `\horiz` or `\vert`. defaults to `\round`.
- `centered_( <bool> )` – Boolean. the knob's center scale, `0.5` is zero in the `value` scale. eg. as in a pan control. defaults to `false`.
- `step_( <val> )` – step in which the `value` is incremented/decremented while draging in `\horiz` and `\vert` `mode`s. defaults to `0.01`.
- `keystep_( <val> )` – step in which the `value` is incremented/decremented with the keyboard. defaults to `0.01`.
- `visible_( <bool> )` – Boolean; set knob's visibility `true`/`false`.
- `enabled_( <bool> )` – Boolean; enable/disable the knob.
- `refresh` – redraws the knob.
- `canFocus_( <val> )` – enable/disable the knob's capability to gain focus.
- `canReceiveDragHandler_( <f> )` – Function. customize drag methods see example.
- `receiveDragHandler_( <f> )` – Function. customize drag methods see example.
- `beginDragAction_( <f> )` – Function. customize drag methods see example.

## Behavior

- The Knob's default tracking mode is `\round`.
- Pressing the Shift key and drag places the knob temporarily into `\vert` tracking mode.
- Pressing the Option key and drag places the knob temporarily into `\horiz` tracking mode.
- Pressing the Control key drags out the knob's value. like for other views.
- In `\round` mode, draging farther from the knob's center increases the control's precision.

## Default Keyboard Mappings

Keys work like on JSCSlider when the Knob gains focus:

`csr up/right` or `]` | increment `value` by `keystep`
`csr down/left` or `[` | decrement `value` by `keystep`
`x` | set value to `1.0`
`c` | set value to `0.5`
`n` | set value to `0.0`

## Examples

    (
    var window, size = 32; // try different sizes - from 15 to 200 or more!
    window = JSCWindow.new("Knob", Rect(300,300,270,100)).front;
    k = JKnob.new(window, Rect(20, 10, size, size));
    k.action_({|v,x,y,m| ["action func", v.value].postln; });
    //k.color[1] = Color.gray(alpha:0);
    )
    k.value
    k.value = 0.25
    k.valueAction = 0.125

    // modes
    k.mode = \vert;
    k.mode = \horiz;
    k.mode = \round; // default

    k.visible
    k.visible = false
    k.visible = true
    k.enabled_(false)
    k.enabled_(true)
    k.canFocus = false
    k.canFocus = true

    // centered mode - a pan control
    (
    var window, spec;
    spec = ControlSpec(-1, 1, default: 0);
    window = JSCWindow.new("Pan Knob", Rect(350,400,270,70)).front;
    k = JKnob.new(window, Rect(20,10,28,28));
    k.action_({|v,x,y,m| spec.map(v.value).postln; })
    // .mode_(\horiz)
    	.centered_(true)
    	.value_(spec.unmap(0)); // 0.5
    //k.color[1] = Color.gray(alpha:0);
    )

    k.centered
    k.centered = false
    k.centered = true

    k.refresh

    // mouseOverAction
    (
    var size = 28;
    w = JSCWindow.new("Knobs", Rect(250,500,270,70));
    w.acceptsMouseOver=true; // true in parent window!
    w.view.decorator = FlowLayout(w.view.bounds);
    h = JSCStaticText(w, 150 @ 20);
    w.view.decorator.nextLine;
    k = Array(8);
    8.do({|item, i|
    	var knob;
    	knob = JKnob.new(w, size @ size)
    	// .canFocus_(false)
    		.action_({|v,x,y,m| h.string = "val: " ++ v.value.asString; })
    		.mouseOverAction_({|v,x,y| h.string = "val: " ++ v.value.asString; });

    	knob.color[0] = [Color.blue(0.7, 0.4), Color.red(0.7, 0.7), Color.green(0.3, 0.6),
    		Color.black.alpha_(0.3)].choose;
    	k = k.add(knob);
    });
    w.front
    )
    k[4].value

    // drag and drop
    // in SwingOSC : ctrl+press+move initiated drag!
    (
    var w, txt, size = 36;
    w = JSCWindow.new("knobs", Rect(400,400,250,100)).front;
    w.acceptsMouseOver=true;
    w.view.decorator = FlowLayout(w.view.bounds).gap_(10 @ 10).margin_(10 @10);
    txt = JSCStaticText(w, 200 @ 14);
    w.view.decorator.nextLine;

    k = JKnob(w, size @ size);
    k.action = {arg v,x,y;  v.value.postln; txt.string_("value: " ++ v.value); };
    k.mouseOverAction = {|v| txt.string_("value: " ++ v.value); };

    j = JKnob(w, size @ size);
    j.action = {arg v,x,y;  j.value.postln; txt.string_("value: " ++ v.value); };
    j.mouseOverAction = { txt.string_("value: " ++ j.value); };

    n = JSCNumberBox(w, 100 @ 20);
    //n.setProperty(\boxColor,Color.grey(alpha:0.0));
    n.value = 0.0;
    )

    // customize drag and drop methods
    k.canReceiveDragHandler
    k.canReceiveDragHandler = false; // don't accept drops

    k.canReceiveDragHandler = { JSCView.currentDrag.isFloat }; // accept only if drag is float

    k.receiveDragHandler = { ("value droped in: " ++ JSCView.currentDrag).postln }

    k.receiveDragHandler = { k.valueAction = JSCView.currentDrag.clip(0.0, 1.0); }

    k.beginDragAction = { ("drag out -> " ++ k.value).postln; }

    k.beginDragAction = { k.value.asFloat; }