WIDTH = 800
HEIGHT = 600
 
set display mode WIDTH, HEIGHT,32
 
DRAW_COLOR = rgb(255,255,255)
 
rem length of slider track
SLIDER_LENGTH = 75
rem thickness of slider track
TRACK_HEIGHT = 3
rem height above and below track to extend the slider thumb
THUMB_EXT = 2
rem width of slider thumb
THUMB_WIDTH = 4
rem x-position to start drawing all sliders at
SLIDER_X = width-100
rem maximum brush size
MAX_BRUSH = 30
rem current brush size
BRUSH_SIZE = 1
rem current drawing action
ACTION = 1
rem density of spray scatter
SPRAY_DENSITY = 20
rem higher number makes spray fill less quickly
MAX_DENSITY = 100
 
 
rem define 3 sliders
rem 2nd dimension:
rem 1 = y-position
rem 2 = 0.0-1.0, thumb position on track
rem 3 = 1 if thumb is being dragged, 0 if not
dim sliders#(5,3)
 
for i = 1 to 3
   sliders#(i,1) = 6+(i-1)*12
   sliders#(i,2) = rnd(100)/100.0
next i
DRAW_COLOR = rgb(255*sliders#(1,2),255*sliders#(2,2),255*sliders#(3,2))
 
sliders#(4,1) = 70
sliders#(4,2) = 0.0
sliders#(5,1) = 100
sliders#(5,2) = (SPRAY_DENSITY*1.0)/MAX_DENSITY
 
rem boundaries of drawing area (left,top,right,bottom)
rem using array to make it gobally accessible
dim dimension(4)
dimension(1) = 2
dimension(2) = 2
dimension(3) = SLIDER_X-6
dimension(4) = HEIGHT-2
 
 
dim buttons(2)
buttons(1) = 1
 
 
sync on
 
ink rgb(192,192,192),0
drawOutlinedBox(dimension(1),dimension(2),dimension(3),dimension(4))  : rem
 
DO
   rem clears side panel
   ink rgb(192,192,192),0
   box dimension(3),dimension(2),WIDTH-1,200
 
   gosub _handle_drawing
 
   gosub _handle_sliders
   gosub _handle_buttons
 
   gosub _draw_sliders
   gosub _draw_buttons
 
sync
LOOP
 
 
 
rem ======================================
rem Handles drawing routines
rem ======================================
_handle_drawing:
   if mouseWithin(dimension(1),dimension(2),dimension(3),dimension(4)) and mouseclick() = 1
      if draw_flag = 0
         draw_flag = 1
         oldmx = mousex()
         oldmy = mousey()
      endif
   else
      draw_flag = 0
   endif
 
   if draw_flag = 1
      ink DRAW_COLOR, 0
      mx = mousex()
      my = mousey()
      bline(oldmx,oldmy,mx,my,BRUSH_SIZE, SPRAY_DENSITY, ACTION)
      oldmx = mx
      oldmy = my
   endif
RETURN
 
 
 
rem ======================================
rem Handles mouse interaction with sliders
rem ======================================
_handle_sliders:
   for i = 1 to 5
      tx = SLIDER_X+SLIDER_LENGTH*sliders#(i,2)
      ty1 = sliders#(i,1)-THUMB_EXT
      ty2 = sliders#(i,1)+THUMB_EXT+TRACK_HEIGHT
      if mouseWithin(tx,ty1,tx+THUMB_WIDTH,ty2)=1 and mouseclick() = 1
         sliders#(i,3) = 1
      endif
      if sliders#(i,3) = 1
         mx# = mousex()
         sliders#(i,2) = (mx# - SLIDER_X)/SLIDER_LENGTH
         if mousex() < SLIDER_X then sliders#(i,2) = 0
         if mousex() > SLIDER_X+SLIDER_LENGTH then sliders#(i,2) = 1
         if i = 4
            BRUSH_SIZE = sliders#(i,2)*MAX_BRUSH
            if BRUSH_SIZE < 1 then BRUSH_SIZE = 1
         else
            if i = 5
               SPRAY_DENSITY = sliders#(i,2)*MAX_DENSITY
            else
               DRAW_COLOR = rgb(255*sliders#(1,2),255*sliders#(2,2),255*sliders#(3,2))
            endif
         endif
      endif
      if mouseclick() <> 1 then sliders#(i,3) = 0
   next i
RETURN
 
rem ======================================
rem Handles mouse interaction with buttons
rem ======================================
_handle_buttons:
   for i = 1 to 2
      x = SLIDER_X+(i-1)*30
      y = 120
      if mouseWithin(x,y,x+24,y+24) and mouseclick() = 1
         for j = 1 to 2
            buttons(j) = 0
         next j
          buttons(i) = 1
          ACTION = i
      endif
   next i
RETURN
 
rem =========================
rem draw buttons
rem =========================
_draw_buttons:
   for i = 1 to 2
      x = SLIDER_X+(i-1)*30
      y = 120
      drawButton(x,y,24,buttons(i))
      ink 0,0
      if buttons(i) then ink rgb(255,0,0),0
      if i = 1 then text x+6,y+6,"P"
      if i = 2 then text x+6,y+6,"B"
   next i
RETURN
 
 
rem =========================
rem Draws the 3 color sliders
rem Draws color box
rem =========================
_draw_sliders:
   for i = 1 to 5
      ink rgb(255,255,255),0
      box SLIDER_X,sliders#(i,1),SLIDER_X+SLIDER_LENGTH,sliders#(i,1)+TRACK_HEIGHT
      tx = SLIDER_X+SLIDER_LENGTH*sliders#(i,2)
      ty1 = sliders#(i,1)-THUMB_EXT
      ty2 = sliders#(i,1)+THUMB_EXT+TRACK_HEIGHT
      ink rgb(128,128,128),0
      box tx,ty1,tx+THUMB_WIDTH,ty2
      cValue = int(255*sliders#(i,2))
      if i = 1 then ink rgb(cValue,0,0),0
      if i = 2 then ink rgb(0,cValue,0),0
      if i = 3 then ink rgb(0,0,cValue),0
      x = SLIDER_X+SLIDER_LENGTH
      if i < 4
         box x+6,ty1,x+23,ty2
      endif
      ink rgb(255,255,255),0
      if i = 4
         text SLIDER_X,ty1-16,"Brush Size"
         text x+6,ty1-6,str$(BRUSH_SIZE)
      endif
      if i = 5
         text SLIDER_X-4,ty1-16,"Spray Density"
         text x+6,ty1-6,str$(SPRAY_DENSITY)
      endif
   next i
   rem current color box
   ink DRAW_COLOR, 0
   box SLIDER_X,40,SLIDER_X+SLIDER_LENGTH+23,50
RETURN
 
 
rem =========================================
rem Checks if mouse is inside the defined box
rem =========================================
function mouseWithin(x1,y1,x2,y2)
   if mousex() > x1 and mousex() < x2 and mousey() > y1 and mousey() < y2 then exitfunction 1
endfunction 0
 
rem =========================================
rem Draws an outline of a box
rem =========================================
function drawOutlinedBox(x1,y1,x2,y2)
   line x1,y1,x2,y1
   line x1,y1,x1,y2
   line x2,y1,x2,y2
   line x1,y2,x2,y2
endfunction
 
 
rem =========================================
rem Draws a line using Bresenham's algorithm
rem =========================================
function bline(x1,y1,x2,y2,size, density, action)
   dx = x2-x1
   dy = y2-y1
 
   if action = 1 then drawDot(x1, y1, size)
   if action = 2 then spray(x1,y1,size, density)
 
   if abs(dx) > abs(dy)
      m# = (0.0 + dy)/dx
      b# = y1 - m#*x1
 
      if dx < 0
         dx = -1
      else
         dx = 1
      endif
      while x1 <> x2
         x1 = x1 + dx
         if action = 1 then drawDot(x1, int(m#*x1+b#), size)
         if action = 2 then spray(x1, int(m#*x1+b#), size, density)
      endwhile
   else
      if dy <> 0
         m# = (0.0 + dx)/dy
         b# = x1 - m#*y1
         if dy < 0
            dy = -1
         else
            dy = 1
         endif
         while y1 <> y2
            y1 = y1 + dy
            if action = 1 then drawDot(int(m#*y1+b#), y1, size)
            if action = 2 then spray(int(m#*y1+b#), y1, size, density)
         endwhile
      endif
   endif
endfunction
 
rem =====================================================
rem draws a box, clipping any parts outside of boundaries
rem =====================================================
function drawDot(x,y,size)
   s = size/2
   for px = x-s to x+s
      for py = y-s to y+s
         if px > dimension(1) and px < dimension(3) and py > dimension(2) and py < dimension(4)
            box px,py,px+1,py+1
         endif
      next py
   next px
endfunction
 
rem
rem
rem
function spray(x,y,size,density)
   s = size/2
   s2 = s*s
   d = density/2
   for px = x-s to x+s
      for py = y-s to y+s
         if px > dimension(1) and px < dimension(3) and py > dimension(2) and py < dimension(4)
            if ((px - x)^2 + (py-y)^2) <= s2
               if rnd(density) = d then box px,py,px+1,py+1
            endif
         endif
      next py
   next px
endfunction
 
 
rem =====================
rem draws a square button
rem =====================
function drawButton(x, y, size, active)
 
   a = 0
   b = rgb(255,255,255)
 
   if active = 0
      a = rgb(255,255,255)
      b = 0
   else
      a = 0
      b = rgb(255,255,255)
   endif
   ink a,0
   box x, y,x+size, y+1
   box x, y,x+1, y+size
   ink b,0
   box x, y+size-1,x+size, y+size
   box x+size-1, y,x+size,y+size
 
endfunction