desc: RCInflator (Oxford Edition)
author: RCJacH
version: 1.0
about: With additions by users sai'ke and BethHarmon
       GUI by argee

desc:RCInflator GUI

// argee revisions to original code:
// removed assignments to 'curve'(slider3) and 'clip'(slider4) in slider definitions and moved them to doslidercode function
// this is to allow interchange of values between visible slider and graphical knobs
// made original sliders invisible by adding '-' in front of name
// added visible generic slider for keyboard input of values

slider1:0<-6, 12, 0.01>-Input (dB)
slider2:0<0, 100, 0.1>-Effect (%)
slider3:0<-50, 50, 0.1>-Curve
slider4:<0,1,1{Off,On}>-Clip
slider5:0<-12, 0, 0.01>-Output (dB)
slider6:0<-50,100,0.01>Value for last touched knob

@init

//ADJUST THESE VALUES TO CHANGE THE COLOR OF THE INTERFACE - VALUES BETWEEN 0 AND 1
//=================================================================================
  backred = 0.5;
  backgreen = 0.3;
  backblue = 0.2;
  backalpha = 0.4;
//==================

// GRAPHICS AND MOUSE HANDLING FUNCTIONS FOR KNOBS
//======================================================

function TestCtrl_at_Mouse(ctrlnum,minX, maxX, minY, maxY)
(
  mouse_x > minX && mouse_x < maxX && mouse_y > minY && mouse_y < maxY ?
  (ctrlnum):(
    knobdrag == 1 ? (mouse_on;): mouse_on < 20 ? 0;
  );
);

function arc_knob(x,y,r,deg0,degf,rotation,arc_w,slideval,dec,ctrlnum,unit, hilite, inc, minval, maxval, defval)
local(i,density,l,rad0,radf)
(   
    knobdrag == 0 ? mouse_on = TestCtrl_at_Mouse(ctrlnum,x-r,x+r,y-r,y+r);

//  shadow effect below knob
    gfx_a=0.65;
    gfx_r=gfx_g=gfx_b=0;
    gfx_arc(x,y+1,r-2, 1.83, 4.45);
//    gfx_a=0.4;
    gfx_arc(x,y+2,r-2, 1.83, 4.45);
    gfx_a=0.3;
    gfx_arc(x,y+3,r-2, 1.83, 4.45);
    gfx_a=0.2;
    gfx_arc(x,y+4,r-2, 1.83, 4.45);

//  background filled black circle
    gfx_a=1;
    gfx_r=gfx_g=gfx_b=0.3;
//    gfx_circle(x,y,r,1,1);

//  dark grey knob background circle with highlights
    gfx_a=1;
    gfx_r=gfx_g=gfx_b=0.3;
    gfx_circle(x,y,r-2,1,0);
    
    gfx_a=1;
    gfx_r=gfx_g=gfx_b=0.7;
//    gfx_arc(x,y,r-2, -1.3, 1.3);
//    gfx_a=1;
    gfx_arc(x,y,r-2, -0.75, 0.75);

    gfx_a=1;
//  radial indicator lines
    radf=((degf+rotation)*100)*(17.4532925)/100000;
    gfx_r=gfx_g=gfx_b=0.8;
    i=radf;
    loop(24,
        gfx_x=x; gfx_y=y;
        gfx_lineto(gfx_x+(r-4)*sin(i),gfx_y-(r-4)*cos(i),1);
        i+=0.2618;
    );

//  inner knob light gray circle with white highlight arc at top
    gfx_x=x;gfx_y=y;
    hilite == 1? (mouse_on == ctrlnum ? gfx_r=gfx_b=gfx_g=1:(gfx_r=gfx_g=gfx_b=0.8));
    hilite == 2? (mouse_on == ctrlnum ? gfx_r=gfx_b=gfx_g=1:(gfx_r=0.5;gfx_g=0.8;gfx_b=1));
    gfx_circle(x,y,r-10,1,1);
    gfx_r=gfx_g=gfx_b=0;
    gfx_r=1;gfx_g=1;gfx_b=1;

//  shadow effect on lower part of knob
    gfx_a=0.3;
    gfx_r=gfx_g=gfx_b=0;

//  knob position indicator small black circle
    gfx_a=1;
    gfx_r=gfx_g=gfx_b=0;
    gfx_circle(x+(r-15)*sin(radf),y-(r-15)*cos(radf),3,1,1);

//  knob value text with units
    gfx_setfont(1,"Arial",16,0);
    hilite == 1? (mouse_on == ctrlnum ? gfx_r=gfx_b=gfx_g=1:(gfx_r=gfx_g=gfx_b=0.75));
    hilite == 2? (mouse_on == ctrlnum ? gfx_r=gfx_b=gfx_g=1:(gfx_r=0.5;gfx_g=0.8;gfx_b=1));

    gfx_x=x+r*.75+5;gfx_y=y-r;
    dec == 4 ? str = sprintf(#, "%.4f", slideval);
    dec == 3 ? str = sprintf(#, "%.3f", slideval);
    dec == 2 ? str = sprintf(#, "%.2f", slideval);
    dec == 1 ? str = sprintf(#, "%.1f", slideval);
    dec == 0 ? str = sprintf(#, "%.0f", slideval);
    gfx_drawstr(str);

    gfx_x=x+r*.75+15;gfx_y=y-r+16;
    gfx_drawstr(unit);

//  reset font and size for knob name text
    gfx_setfont(1,"Arial",16,0);
    gfx_x=x; gfx_y=y+r+4;

    mouse_on == ctrlnum ? (
      mouse_cap == 5 ? inc*=0.1;
      mouse_cap == 17? inc*=3;
      mouse_cap > 0 && mouse_cap != 2 ? (
        mouseclick = ctrlnum;
        mouse_y > saveY+2 ? slideval = Max(minval,slideval-inc);
        mouse_y < saveY-2 ? slideval = Min(maxval,slideval+inc);
        knobdrag = 1;
      );
      mouse_cap == 0 ? (
        mouse_wheel < 0? (slideval = Max(minval,slideval-inc);mouseclick = ctrlnum ;slider6 = slideval);
        mouse_wheel > 0? (slideval = Min(maxval,slideval+inc);mouseclick = ctrlnum ;slider6 = slideval);
        mouse_wheel = 0;
        knobdrag = 0;
      );
    mouse_cap == 2 ? (slideval = defval;slider6 = slideval);
    );
  
    slideval;
);

//END OF GRAPHICS AND MOUSE HANDLING FUNCTIONS FOR KNOBS

//CODE ORIGINALLY IN @slider, MOVED HERE SO IT CAN ALSO BE CALLED FROM @gfx
function do_slidercode()(

slider6 != saveSL6 ? (
  mouseclick == 1 ? slider1 = max(min(slider6,12),-6);
  mouseclick == 2 ? slider2 = max(min(slider6,100),0);
  mouseclick == 3 ? slider3 = max(min(slider6,50),-50);
  mouseclick == 5 ? slider5 = max(min(slider6,0),-12);
  saveSL6 = slider6;
  );


in_db = exp(0.11512925464970229 * slider1);
wet = slider2 * 0.01;
dry = 1.0 - wet;
out_db = exp(0.11512925464970229 * slider5);
clip = slider4;  //added assignment to clip here, removed from slider definition

curvepct = 0.01 * slider3; //used slider3 value directly, assignment to 'curve' removed from slider definition
// 1 + (curve + 50) / 100
curveA = 1.5 + curvepct;
// - curve / 50
curveB = -(curvepct + curvepct);
// (curve - 50) / 100
curveC = curvepct - 0.5;
// 1 / 16 - curve / 400 + curve ^ 2 / (4 * 10 ^ 4)
curveD = 0.0625 - curve * 0.0025 + (curve * curve) * 0.000025;

);

@gfx 550 150
gfx_a=1;

//Graphics for the Main Background

//gfx_gradrect(x,y,w,h, r,g,b,a[, drdx, dgdx, dbdx, dadx, drdy, dgdy, dbdy, dady])
gfx_gradrect(0,30,550,120,backred,backgreen,backblue,backalpha,0,0,0,0,0,0,0,-0.0018);
gfx_gradrect(0,30,550,5,0,0,0,0.4,0,0,0,0,0,0,0,-0.25);

gfx_x=0;gfx_y=0;

//  Banner text
gfx_setfont(1,"Calibri",32,'b');
gfx_x=10;gfx_y=-2;
gfx_r=1;gfx_g=1;gfx_b=1; gfx_drawstr("RC ");

gfx_r=backred*1.2;gfx_g=backgreen*1.2;gfx_b=backblue*1.2;
gfx_drawstr("Inflator");

gfx_setfont(1,"Calibri",22,'b');
gfx_x+=300;gfx_y=+4;
gfx_r=backred*0.7;gfx_g=backgreen*0.7;gfx_b=backblue*0.7;
gfx_drawstr("Oxford Edition");

//End of Main Background graphics

//Knobs - call to arc_knob function - mouse handling and graphics - then draw knob name text
//function arc_knob(x,y,r,deg0,degf,rotation,arc_w,slideval,dec,ctrlnum,unit, hilite, inc, minval, maxval, defval)

slider1 = new.arc_knob(60,83,38,0,slider1*15,-40,6,slider1,3,1,"dB",1,0.2,-6,12,0); gfx_x-=13; gfx_drawstr("Input");
slider2 = new.arc_knob(180,85,38,0,slider2*2.85,-140,6,slider2,1,2,"%",1,2,0,100,0); gfx_x-=22; gfx_drawstr("Effect %");
slider3 = new.arc_knob(300,85,38,0,slider3*2.85,0,6,slider3,1,3,"",1,1,-50,50,0); gfx_x-=15; gfx_drawstr("Curve");
slider5 = new.arc_knob(470,85,38,0,slider5*22,120,6,slider5,3,5,"dB",1,0.1,-12,0,0); gfx_x-=18; gfx_drawstr("Output");


//Clip Toggle Button - Mouse Handling and Graphics
knobdrag == 0 ? mouse_on = TestCtrl_at_Mouse(4,380,400,65,105);

mouse_on == 4 ? (
  mouseclick = 0;
  mouse_cap > 0 ? (
    done == 0 ? (
      slider4 = slider4 == 0 ? 1 : 0;
      done = 1;
      );
  ):
  done = 0
);

gfx_r=gfx_g=gfx_b=0;
gfx_rect(380,65,20,40);
gfx_gradrect(382,86 - slider4 * 18,16,16,0.7 + slider4,0.7 + slider4,0.7 + slider4,0.8,0,0,0,0,0,0,0,-0.03);

gfx_x = 378; gfx_y = 127;
gfx_r = gfx_g=gfx_b = 0.8;
gfx_drawstr("Clip");

gfx_setfont(1,"Arial",12,0);

gfx_x = 383; gfx_y = 52;
gfx_drawstr("On");

gfx_x = 382; gfx_y = 107;
gfx_drawstr("Off");

// End of CLip Toggle Button

//Update visible slider value to current knob value
mouse_on == 1 ? (slider6 = slider1);
mouse_on == 2 ? (slider6 = slider2);
mouse_on == 3 ? (slider6 = slider3);
mouse_on == 5 ? (slider6 = slider5);

do_slidercode();

saveX = mouse_x;
saveY = mouse_y;

@slider
do_slidercode();

@sample
function apply_waveshaper(in)
local(s0, s0_2, s0_3, out)
global(curveA, curveB, curveC, curveD,
       clip, dry, in_db, out_db, wet)
(
  in *= in_db;
  s0 = abs(in);
  clip ? (
    s0 = s0 > 1.0 ? 1.0 : s0;
  );
  s0_2 = s0 * s0;
  s0_3 = s0_2 * s0;
  s0 = (s0 >= 2.0) ? (
    0.0
  ) : (s0 > 1.0) ? (
    2.0 * s0 - s0_2
  ) : (
    curveA * s0 + curveB * s0_2 + curveC * s0_3 - curveD * (s0_2 - 2.0 * s0_3 + s0_2 * s0_2)
  );
  
  out = sign(in) * s0 * wet + min(max(in * dry, -2 * dry), 2 * dry);
  out = clip ? max(-1, min(out, 1)) : out;
  out * out_db
);

spl0 = apply_waveshaper(spl0);
spl1 = apply_waveshaper(spl1);
