> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.mCvsPQ7iMkW/rev.2067
 * 
 * authors: 
 *   
 *   Darby Rathbone

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



// This sketch builds on a prior work, "PAINTING PROGRAMMING", created by Melissa Harris. I just thought that you might like this.
// http://studio.sketchpad.cc/sp/pad/view/ro.9gt6Y-9tjIJt$/rev.889
/** if anyone wants to modify this and clean the code up by deleting all the useless and unused things that would be AWESOME! I'm currently working on:
minimap - on the top right so the users can zoom in and edit their picture with more detail.
colorselector should be more clear what color is selected. possibly make it show what the brush size is at the same time.
make the RGBA and HSBA editable and archivable.
make all the actions performed append to an array and setup ctrl + z and ctrl + y for undo and redo.
make an erase function.... sounds easy enough.
make a grab color under mouse function.
setup ability to save and load images.
*/

HScrollbar hs1;//width
HScrollbar hs2;//transparent


PImage pg = get();
int[] pointsx = new int[0];
int[] pointsy = new int[0];
int y = 30;
int x = 45;

PGraphics colorchooser;
color current;

void setup () {
  background(255);
  colorchoosersetup();
  current = color(0);
  smooth();
  size (500, 500);
  stroke(current);
  background (255);
  image(colorchooser, 0, 0);
  hs1 = new HScrollbar(0, 110+5, 110, 10, 1, "WIDTH",1);//width
  hs2 = new HScrollbar(0, 120+5, 110, 10, 1, "OPACITY",350/110);//transparent
  fill(100);
  noStroke();
  rect(390, 0, 110, 110);
  hs1.display();
  hs2.display();
  copy(0, 0, width, height, 500-105, 5, 100, 100);
  noFill();

  strokeWeight(hs1.getPos());
  pg = get();
}

boolean colorchoosermouse(boolean setcolors) {
  if (5<=mouseX && mouseX<=105 && 5<=mouseY && mouseY<=105)
  {
    if (setcolors)
    {
      current = colorchooser.get(mouseX, 100-mouseY);
    }
    return true;
  } 
  else
  {
    return false;
  }
}
void colorchoosersetup() {

  colorchooser = createGraphics(110, 110, P3D);

  colorchooser.beginDraw();
  colorchooser.noStroke();
  colorchooser.background(100);

  colorchooser.colorMode(HSB, 100);

  for (int i=0; i<=100; i++) {

    for (int j=0; j<=100; j++) {
      colorchooser.saturation(j);
      colorchooser.stroke(i, j*2, (100-j)*2);

      colorchooser.point(i+5, j+5);
    }
  }

  colorchooser.endDraw();
}


void mousePressed()
{

  //check to see if the mouse clicked in the color change box
  if (!colorchoosermouse(true))
  {


    //draw the lines
    strokeJoin(ROUND);
    curveVertex(mouseX, mouseY);
  }
  if (hs1.overEvent())
  {
    hs1.locked = true;
    hs1.update();
  }
  if (hs2.overEvent()) {
    hs2.locked = true;
    hs2.update();
  }
  fill(100);
  noStroke();
  rect(390, 0, 110, 110);

  copy(0, 0, width, height, 500-105, 5, 100, 100);
  noFill();

  strokeWeight(hs1.getPos());
}

void mouseReleased()
{
  pg = get();
  pointsx = new int[0];
  pointsy = new int[0];
  hs1.locked =false;
  hs2.locked = false;
  fill(100);
  noStroke();
  rect(390, 0, 110, 110);

  copy(0, 0, width, height, 500-105, 5, 100, 100);
  noFill();

  strokeWeight(hs1.getPos());
  curveVertex(mouseX, mouseY);
 
  //fill(current);
  strokeWeight(0);

  curveDetail(5);
  fill(100);
  noStroke();
  rect(390, 0, 110, 110);

  copy(0, 0, width, height, 500-105, 5, 100, 100);
  noFill();

  strokeWeight(hs1.getPos());
}
void mouseDragged() {
  if (!hs1.locked && !hs2.locked){
  image(pg, 0, 0);
  pointsx = append(pointsx, mouseX);
  pointsy = append(pointsy, mouseY);
  noFill();
  stroke(current, hs2.getPos());
  strokeWeight(hs1.getPos());
  beginShape();
  
  
  for (int i = 1;i <pointsx.length()-1;i++)
  {
      vertex(pointsx[i-1], pointsy[i-1]);
    curveVertex(pointsx[i], pointsy[i]);
  }
  endShape();
  }
    hs1.display();
  hs2.display();
  image(colorchooser, 0, 0);
}
void draw () {

  if (hs1.locked && mousePressed)
  {
    hs1.update();    
    hs1.display();
    hs2.display(); 
    return;
  }
  if (hs2.locked && mousePressed)
  {
    hs2.update();    
    hs1.display();
    hs2.display();
    return;
  }
  if (mousePressed && !colorchoosermouse(false) && !hs1.overEvent() && !hs2.overEvent()) {
  }
  if (keyPressed) {
    if (key=='p') {
      current = color(150, 0, 100);
    }
  }
  if (keyPressed) {
    if (key=='g') {
      current =  color(40, 200, 0);
    }
  }
  if (keyPressed) {
    if (key=='r') {
      current =  color(200, 20, 100);
    }
  }
  if (keyPressed) {
    if (key=='o') {
      current =  color(250, 130, 0);
    }
  }
  if (keyPressed) {
    if (key=='y') {
      current =  color(200, 200, 0);
    }
  }


}


class ColorPicker
{
  int swidth, sheight;    // width and height of bar
  float xpos, ypos;        // x and y position of bar
  color scurrentcolor;    
  ColorPicker(float xp, float yp, int sw, int sh)
  {
    swidth = sw;
    swidth = sh;
    xpos = xp;
    ypos = yp;
    scurrentcolor = color(0);
  }
  boolean overEvent() {
    if (mouseX > xpos && mouseX < xpos+swidth &&
      mouseY > ypos && mouseY < ypos+sheight) {
      return true;
    } 
    else {
      return false;
    }
  }
}
class HScrollbar {
  int swidth, sheight;    // width and height of bar
  float xpos, ypos;       // x and y position of bar
  float spos, newspos;    // x position of slider
  float sposMin, sposMax; // max and min values of slider
  int loose;              // how loose/heavy
  boolean over;           // is the mouse over the slider?
  boolean locked;
  float ratio;
  String _Name;

  HScrollbar (float xp, float yp, int sw, int sh, int l, String n,float r) {
    swidth = sw;
    sheight = sh;
    int widthtoheight = sw - sh;
    ratio = (float)sw / (float)widthtoheight;
    xpos = xp;
    ypos = yp-sheight/2;
    spos = xpos + swidth/2 - sheight/2;
    newspos = spos;
    sposMin = xpos;
    sposMax = xpos + swidth - sheight;
    loose = l;
    _Name = n;
    ratio = r;
  }

  void update() {
    if (overEvent()) {
      over = true;
    } 
    else {
      over = false;
    }
    if (mousePressed && over) {
      locked = true;
    }
    if (!mousePressed) {
      locked = false;
    }
    if (locked) {
      newspos = constrain(mouseX-sheight/2, sposMin, sposMax);
    }
    if (abs(newspos - spos) > 1) {
      spos = spos + (newspos-spos)/loose;
    }
    //  fill(255,0,0);

    //textMode(SCREEN);
    //text(_Name+" : "+round(spos*ratio),xpos,(ypos+swidth)-1);
  }

  float constrain(float val, float minv, float maxv) {
    return min(max(val, minv), maxv);
  }

  boolean overEvent() {
    if (mouseX > xpos && mouseX < xpos+swidth &&
      mouseY > ypos && mouseY < ypos+sheight) {
      return true;
    } 
    else {
      return false;
    }
  }

  void display() {
    noStroke();
    fill(204);
    rect(xpos, ypos, swidth, sheight);
    if (over || locked) {
      fill(0, 0, 0, 255);
    } 
    else {
      fill(102, 102, 102, 255);
    }
    rect(spos, ypos, sheight, sheight);
    fill(255, 0, 0);
    textMode(SCREEN);
    text(_Name+" : "+round(spos), xpos, (ypos+sheight)-1);
  }

  float getPos() {
    // Convert spos to be values between
    // 0 and the total width of the scrollbar
    return spos * ratio;
  }
}