uses GUI
uses chaos

'EXAMPLES
'========

'HORIZONTAL SLIDERS

'Slider s1<=(100,100,10,15,50,150,100,100,"Red")
'Slider s2<=(100,140,10,15,50,150,140,140,"Green")
'Slider s3<=(100,180,10,15,50,150,180,180,"Blue")
'Slider s4<=(100,220,10,15,50,150,220,220,"Hue")
'Slider s5<=(100,260,10,15,50,150,260,260,"Luminance")
'Slider s6<=(100,300,10,15,50,150,300,300,"Saturation")

'VERTICAL SLIDERS

'Slider s4<=(200,150,15,10,200,200,100,200)
'Slider s5<=(250,150,15,10,250,250,100,200)
'Slider s6<=(300,150,15,10,300,300,100,200)

'KNOBS

'Knob c1<=(100,110,25,15,.012,.5,"red")
'Knob c2<=(100,160,25,15,.012,.3,"green")
'Knob c3<=(100,210,25,15,.012,.5,"blue")

'BUTTONS

'RoundButton c1<=(100,110,25,15,0x00ffff,1,"red")
'RectButton  c1<=(100,110,25,15,0x00ffff,1,"red")

sub limit(sys min,*v,max)
if v<min then v=min
if v>max then v=max
end sub


function MouseStartIn(sys sx,sy,lx,ly) as sys
if sxMouse>=sx and sxMouse<=lx+sx then
  if syMouse>=sy and syMouse<=ly+sy then
    return 1
  end if
end if
end function



  '======
  'IMAGES
  '======

  macro ImageInterface
  ====================
  method render()
  method create()
  method destroy()
  method show()
  end macro
  '
  class FlatBox
  =============
  'has ImageInterface
  sys px,py,w,h,c,sh,bm,dc
  '
  method render()
  FlatColor dc,w,h,c
  end method
  '
  method create()
  CreateImageRect dc,bm,w,h
  render
  end method
  '
  method destroy()
  DeleteImage dc,bm
  end method
  '
  method show()
  if not dc then exit method
  CopyImageToScene dc,px,py,w,h
  end method
  '
  end class 'flatbox

  class ShadeBox
  ==============
  '
  has FlatBox
  '
  method Render() 'ovverride
  if not dc then exit method
  int cc=c
  int hh=sh
  int y,x
  for y=0 to <h
    for x=0 to <w
      SetPixel dc,x,y,cc
    next
    mov eax,cc
    (
     cmp al,0
     jz exit
     sub al,hh
    )
    (
     cmp ah,0
     jz exit
     sub ah,hh
    )
    ror eax,16
    (
     cmp al,0
     jz exit
     sub al,hh
    )
    rol eax,16
    mov cc,eax
  next
  end method

  method Create() 'ovverride
  sys cc,hh
  CreateImageRect dc,bm,w,h
  Render
  end method
  '
  end class


  class NoiseBox
  ==============
  '
  has   FlatBox
  float rf,gf,bf,af 'colors 0..1
  sys   mm[8],nn[8]   'noise: period and amplitude profiles
  '
  '
  method Render()
  sys i,m,n,p
  if not dc then exit method
  p=getmemory w*h*4
  'scale,rgba bytes
  mm<=128,64,32,16,8,4,2,1 'period octaves
  for i=0 to 7
    n=nn[i] 'amplitude
    m=mm[i] 'period octave
    if n
      'NoiseFn pixbase,width,height,stride,colorval,offset
      AddNoiseC p,w,h,m,n*rf, n*gf, n*bf, n*af, 0x35353535
    end if
  next
  CopyPixelsToImage dc,p,w,h
  end method
  '
  method Create() 'ovverride
  CreateImageRect dc,bm,w,h
  Render
  end method
  '
  end class



  '========
  'CONTROLS
  '========

  macro ControlInterface
  ======================
  method zone()
  method set()
  method anchor()
  method move(sys tx,ty)
  method bget() as sys
  method show()
  end macro

  'Slider
  '======
  '
  Class Slider
  has ControlInterface
  '
  method fget(single s) as single
  method fset(single v,s) as sys
  method bset(sys v) as sys
  '
  sys px,py,sx,sy     'position and sensing-size
  sys lx1,lx2,ly1,ly2 'limits of movement
  bstring txt
  sys spx,spy,slx1,slx2,sly1,sly2,act
  single sc
  end class
  '
  methods of Slider
  '
  method zone() as sys
  if sxMouse>=lx1-sx and sxMouse<=lx2+sx then
    if syMouse>=ly1-sy and syMouse<=ly2+sy then
      return 1
    end if
  end if
  end method
  '
  method Set() as sys
  if not zone() then exit method
  if xMouse>=lx1-sx and xMouse<=lx2+sx then
    if yMouse>=ly1-sy and yMouse<=ly2+sy then
      px=spx+xMouse-sxMouse : py=spy+yMouse-syMouse
      limit(lx1,px,lx2)
      limit(ly1,py,ly2)
      act=1
      return 1
    end if
  end if
  end method
  '
  method anchor()
  spx=px   : spy=py
  slx1=lx1 : slx2=lx2
  sly1=ly1 : sly2=ly2    
  act=0
  end method
  '
  method show() as sys
  Line lx1,ly1,lx2,ly2,4,0xcccccc
  if act then
    Oval px-sx, py-sy, sx*2, sy*2, 0xffff
  else
    Oval px-sx, py-sy, sx*2, sy*2, 0x6464
  end if
  if lx1<lx2 then
    if sc=0 then sc=255
    'string v=txt+" "'+str(round(sc*(px-lx1)/(lx2-lx1)))
    Text lx2+10,ly1-fy*.5,txt+" "+round(sc*(px-lx1)/(lx2-lx1)),255,255,255
  end if
  end method
  '
  method move(sys tx,ty)
  px=spx+tx   : py=spy+ty
  lx1=slx1+tx : lx2=slx2+tx
  ly1=sly1+ty : ly2=sly2+ty
  end method
  '
  method fget(single s) as single
  if lx1<lx2 then return s*(px-lx1)/(lx2-lx1) 'HORIZONTAL
  if ly1<ly2 then return s*(py-ly1)/(ly2-ly1) 'VERTICAL
  end method
  '
  method bget() as sys
  if lx1<lx2 then return 255*(px-lx1)/(lx2-lx1)
  if ly1<ly2 then return 255*(py-ly1)/(ly2-ly1)
  end method
  '
  method fset(single v,s) as sys
  sc=s
  if lx1<lx2 then px=lx1+(lx2-lx1)*v/s
  if ly1<ly2 then py=ly1+(ly2-ly1)*v/s
  end method
  '
  method bset(sys v) as sys
  if lx1<lx2 then px=lx1+(lx2-lx1)*v/255
  if ly1<ly2 then py=ly1+(ly2-ly1)*v/255
  end method
  '
  end methods


  'RoundLight
  '==========
  '
  class RoundLight
  has ControlInterface
  '
  sys px,py,sx,sy,color,latch
  bstring txt
  sys spx,spy,act,state
  end class
  '
  methods of RoundLight
  method zone() as sys
  if MouseStartIn px-sx,py-sx,sx*2,sy*2 then return -1
  end method
  '
  method set() as sys
  'no user action
  end method
  '
  method anchor()
  spx=px
  spy=py
  end method
  '
  method move(sys tx,ty)
  px=spx+tx : py=spy+ty
  end method
  '
  method bget() as sys
  return state
  end method
  '
  method show() as sys
  sys c=0x202020
  if state then c=color
  Oval px-sx, py-sy, sx*2, sy*2, c
  if txt
    Text px,py-sy+(fy>>2),txt,0xffffff
  end if
  end method
  '
  end methods


  'RoundButton
  '===========
  '
  class RoundButton
  has ControlInterface
  '
  sys px,py,sx,sy,color,latch 'position and sensing-size
  bstring txt
  sys spx,spy,act,state
  end class
  '
  methods of RoundButton
  method zone() as sys
  if MouseStartIn px-sx,py-sx,sx*2,sy*2 then return -1
  end method
  '
  method set() as sys
  if sxMouse>=px-sx and sxMouse<=px+sx then
    if syMouse>=py-sy and syMouse<=py+sy then
      if not act then state xor=-1
      act=1
      return state
    end if
  end if
  end method
  '
  method anchor()
  spx=px
  spy=py
  act=0
  if not latch then state=0
  end method
  '
  method move(sys tx,ty)
  px=spx+tx : py=spy+ty
  end method
  '
  method bget() as sys
  return state
  end method
  '
  method show() as sys
  sys c=0x202020
  if state then c=color
  Oval px-sx, py-sy, sx*2, sy*2, c
  if txt
    Text px,py-sy+(fy>>2),txt,0xffffff
  end if
  end method
  '
  end methods


  'RectButton
  '==========
  '
  class RectButton
  has ControlInterface
  '
  sys px,py,sx,sy,color,latch     'position and sensing-size
  bstring txt
  sys spx,spy,act,state
  end class
  '
  methods of RectButton
  '
  method zone() as sys
  if MouseStartIn px,py,sx,sy then return -1
  end method
  '
  method set() as sys
  if sxMouse>=px-sx and sxMouse<=px+sx then
    if syMouse>=py-sy and syMouse<=py+sy then
      if not act then state xor=-1
      act=1
      return state
    end if
  end if
  end method
  '
  method anchor()
  spx=px
  spy=py
  act=0
  if not latch then state=0
  end method
  '
  method show() as sys
  sys c=0x404040
  if state then c=color
  FillBox px-sx, py-sy, sx*2, sy*2, c
  if txt
    Text px,py-sy+(fy>>2),txt,0xffffff
  end if
  end method
  '
  method move(sys tx,ty)
  px=spx+tx : py=spy+ty
  end method
  '
  method bget() as sys
  return state
  end method
  '
  end methods


  'Knob
  '====
  '
  class Knob
  has ControlInterface
  method fget() as single
  '
  sys px,py,sx,sy     'position and sensing-size
  single sens,ang
  bstring txt
  single sang
  sys    spx,spy,act
  '
  end class
  '
  methods of Knob
  '
  method zone() as sys
  if MouseStartIn px-sx,py-sx,sx*2,sy*2 then return -1
  end method
  '
  method set() as sys
  if sxMouse>=px-sx and sxMouse<=px+sx then
    if syMouse>=py-sy and syMouse<=py+sy then
      ang=sang+(xMouse-sxMouse+yMouse-syMouse)*sens
      if ang>1 then ang=1
      if ang<0 then ang=0
      act=1
      return 1
    end if
  end if
  end method
  '
  method anchor()
  sang=ang
  spx=px
  spy=py
  act=0
  end method
  '
  method show() as sys
  sys c=0x606040
  if act then c=0xaaaa
  Oval px-sx, py-sy, sx*2, sy*2, c
  Line px,py,px+sx*sin(ang*6),py-sy*cos(ang*6),2,0xcccccc
  if txt
    'Text px+sx+10,py-sy+(fy>>2),txt+" "+str(ang,2),0xffffff
    Text px+sx+10,py-sy+(fy>>2),txt+" "+str(ang*255,0),0xffffff
  end if
  end method
  '
  method move(sys tx,ty)
  px=spx+tx : py=spy+ty
  end method
  '
  method fget() as single
  return ang
  end method
  '
  method bget() as sys
  return 255*ang
  end method
  '
  end methods 'knob


  'DialogBox
  '=========
  '
  class DialogBox
  has ControlInterface
  '
  sys px,py,sx,sy     'position and sensing-size
  bstring txt
  sys spx,spy,act
  end class
  '
  methods of DialogBox
  '
  method zone() as sys
  if MouseStartIn px,py,sx,sy then return -1
  end method
  '
  method set()
  end method
  '
  method bget() as sys
  end method
  '
  method anchor()
  spx=px
  spy=py
  act=0
  end method
  '
  'method move(sys tx,ty) as sys
  'end method

  method move(sys tx,ty) as sys
  if xMouse>=px-sx and xMouse<=px+sx then
    if yMouse>=py-sy and yMouse<=py+sy then
      px=spx+tx
      py=spy+ty
      limit(0,px,wx-sx)
      limit(0,py,wy-sy)
      act=1
      return 1
    end if
  end if
  end method
  '
  method show() as sys
  FillBox px,py,sx,sy,0xa0a0a0
  if txt then Text px+5,py+5,txt,0xe00000 '0xffffff
  end method
  '
  end methods 'dialog box

  'DisplayBox
  '==========
  '
  class DisplayBox
  has ControlInterface
  '
  sys px,py,sx,sy     'position and sensing-size
  bstring txt
  sys spx,spy,act
  '
  end class
  '
  methods of DisplayBox
  '
  method zone() as sys
  if MouseStartIn px,py,sx,sy then return -1
  end method
  '
  method set()
  end method
  '
  method bget() as sys
  end method
  '
  method anchor()
  spx=px
  spy=py
  act=0
  end method
  '
  method move(sys tx,ty) as sys
  px=spx+tx
  py=spy+ty
  act=1
  return 1
  end method
  '
  method show() as sys
  FillBox px,py,sx,sy,0xa0a0a0
  if txt then Text px+5,py+5,txt,0xe00000 '0xffffff
  end method
  '
  end methods 'display box


