Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

Some Sliders, Checkboxes and a Doubleclick

12. November 2010

I designed my sliders with scalable (length and height) bezier curves. The nob adapts and grows in length and width depending on the slider value. They also have a glowing mouse-over function. The checkbox is a actually a 'checkcircle'. it glows when rolled-over and fills with a color when pressed. optionally, one can get a boolean from the checkbox class to check if it has been activated. Doubleclick was done by checking a time difference (here max. 150ms). An impulse-like circle is shown at the last clicked mouse coordinates. It dissapears when re-clicked anywhere. In the doubleclick class, there is also a method which returns a boolean to check if it has been double-clicked or not. source code: codingSpace18 main class:
/* ----------------------------------------------------------------------------
 *  codingSpace18					
 * ----------------------------------------------------------------------------
 *  GUI - main class
 * ----------------------------------------------------------------------------
 *  prog: eddi.lecesne@zhdk.ch
 *  13.11.2010
 * ----------------------------------------------------------------------------
 */
//sliders
Slider sliderR = null;
Slider sliderG = null;
Slider sliderB = null;
//checkboxes
Checkbox checkboxA = null;
Checkbox checkboxB = null;
//double click
DoubleClick doubleClick = null;
boolean checkDoubleClick = false;

float mX, mY;  //for doubleclick

void setup()
{
  size(400, 400);
  //parameter: [x, y, width, height, start value (0..1)]
  sliderR = new Slider(20,50,50,20,.5);  
  sliderG = new Slider(150,50,100,80,.5);
  sliderB = new Slider(250,50,300,40,.5);
  //parameter: [x,y,diameter]
  checkboxA = new Checkbox(50, 300, 20);
  checkboxB = new Checkbox(150, 300, 50);
  
  doubleClick = new DoubleClick();
}

void draw()
{
  //background(sliderR.pos() * 255,sliderG.pos() * 255,sliderB.pos() * 255);
  background(240, 240, 240, 25);


  sliderR.draw();
  sliderG.draw();
  sliderB.draw();
  
  checkboxA.draw();
  checkboxB.draw();

  //check if doubleclicked
  if(checkDoubleClick)
    doubleClick.ping();  //returns an impulse-like ellipse at the last mouse position. stops when clicked anywhere

  sliderR.fillColor(sliderR.pos() * 255, 0, 0, 255);  //red and alpha
  sliderG.fillColor(0, sliderG.pos() * 255, 0, 255);  //green and alpha
  sliderB.fillColor(0, 0, sliderB.pos() * 255, 255);  //blue and alpha

  sliderR.mouseOver(mouseX, mouseY);
  sliderG.mouseOver(mouseX, mouseY);
  sliderB.mouseOver(mouseX, mouseY);

  //glow on mouse-over
  checkboxA.mouseOver(mouseX,mouseY);  
  checkboxB.mouseOver(mouseX,mouseY);
}

void mousePressed()
{
  sliderR.mousePos(mouseX,mouseY,true);
  sliderG.mousePos(mouseX,mouseY,true);
  sliderB.mousePos(mouseX,mouseY,true);
  
  //activate (fill) or deactivate( nofill) checkbox
  checkboxA.mousePos(mouseX,mouseY);
  checkboxB.mousePos(mouseX,mouseY);

  // send doubleclick request. returns a boolean
  checkDoubleClick = doubleClick.checkDoubleClick(millis());
  if(checkDoubleClick) {
    mX = mouseX;
    mY = mouseY;
  }
}

void mouseDragged()
{
  sliderR.mousePos(mouseX,mouseY,true);
  sliderG.mousePos(mouseX,mouseY,true);
  sliderB.mousePos(mouseX,mouseY,true);
}

slider class:
/* ----------------------------------------------------------------------------
 *  codingSpace18					
 * ----------------------------------------------------------------------------
 *  GUI - Slider
 * ----------------------------------------------------------------------------
 *  prog: eddi.lecesne@zhdk.ch
 *  13.11.2010
 * ----------------------------------------------------------------------------
 */

class Slider
{
  PVector _p1;
  PVector _p2;
  float[] _a = new float[4];

  int     _w;
  int     _h;
  float   _pos;



  Slider(int x,int y,int h,int w,float pos)
  {   
    _p1 = new PVector(x + w * 0.5, y);
    _p2 = new PVector(x + w *.5, y + h);

    _w = w;
    _h = h;

    _pos = pos;
    if(_pos > 1.0)
      _pos = 1.0;
    else if(_pos < 0.0)
      _pos = 0.0;
  }

  float pos()
  {
    return _pos;
  }
  //fill color
  void fillColor(float c1, float c2, float c3, float a) {
    _a[0] = c1;
    _a[1] = c2;
    _a[2] = c3;
    _a[3] = a;
  }

  boolean isHit(int x,int y)
  {
    if(x > _p1.x - 20 && x < _p1.x + 20 && y > _p1.y  && y < _p2.y) {

      return true;
    }
    else {
      return false;
    }
  }


  void draw()
  {
    pushStyle();
    drawSlider();
    drawKnob();
    popStyle();
  } 

  void drawSlider()
  {
    noFill();
    stroke(_a[0], _a[1], _a[2], _a[3]);
    smooth();
    strokeWeight(2);   

    bezier(_p1.x-(_w/2.0), _p1.y, _p1.x-(_w/10.0), _p1.y + (_h/8.0),  _p2.x-(_w/10.0), _p2.y-(_h/8.0), _p2.x-(_w/2.0), _p2.y);  //left side
    bezier(_p1.x+(_w/2.0), _p1.y, _p1.x+(_w/10.0), _p1.y + (_h/8.0), _p2.x +(_w/10.0), _p2.y-(_h/8.0), _p2.x+(_w/2.0), _p2.y);  //right side
    bezier(_p1.x-(_w/2.0), _p1.y, _p1.x-(_w/5.0), _p1.y-(_h/12), _p1.x+(_w/5.0), _p1.y-(_h/12), _p1.x+(_w/2.0), _p1.y);  //top
    bezier(_p2.x-(_w/2.0), _p2.y, _p2.x-(_w/5.0), _p2.y+(_h/12), _p2.x+(_w/5.0), _p2.y+(_h/12), _p2.x+(_w/2.0), _p2.y);  //bottom
  }

  void drawKnob()
  {
    stroke(0, 0,0,100);
    
    PVector dir = PVector.sub(_p2,_p1);
    PVector pos = PVector.add( _p1, PVector.mult(dir,_pos));
    noFill();
    float bezier1= pos.x-(_w/10.0);
    float bezier2= pos.x+(_w/10.0);
    float bezier3= pos.x-(_w/10.0);
    float bezier4= pos.x+(_w/10.0);
    float bezier5= pos.y+(_h/20.0);
    float bezier6= pos.y-(_h/20.0);

    if(_pos >= 0.6) {
      bezier1 = map(_pos, 0.5, 1.0, pos.x-(_w/10.0), pos.x-(_w/3.0) );  //change bottom left side
      bezier2 = map(_pos, 0.5, 1.0, pos.x+(_w/10.0), pos.x+(_w/3.0) );  //change bottom right side
      bezier6 = map(_pos, 0.6, 0.0, pos.y+(_h/10.0), pos.y+(_h/3.0) );  //expand top middle
    }
    else
      bezier6= pos.y-(_h/20.0);
      
    if(_pos <= 0.6) {
      bezier3 = map(_pos, 0.5, 0.0, pos.x-(_w/10.0), pos.x-(_w/3.0));  //top left side
      bezier4 = map(_pos, 0.5, 0.0, pos.x+(_w/10.0), pos.x+(_w/3.0));  ///top right side
      bezier5 = map(_pos, 0.6, 1.0, pos.y-(_h/50.0), pos.y-(_h/3.0) );  //expand bottom middle
    }
    else
       bezier5= pos.y+(_h/20.0);

    rect(pos.x-3, pos.y-2, 6, 4);
    bezier(bezier3, pos.y-4, pos.x-(_w/15.0), bezier6, pos.x+(_w/15.0), bezier6, bezier4, pos.y-4);  //top arc
    bezier(bezier1, pos.y+4, pos.x-(_w/15.0), bezier5, pos.x+(_w/15.0),bezier5, bezier2, pos.y+4);  //bottom arc

    bezier(bezier3, pos.y-4, pos.x-(_w/10.0), pos.y-2, pos.x-(_w/10.0), pos.y+2, bezier1, pos.y+4);  //left side arc
    bezier(bezier4, pos.y-4, pos.x+(_w/10.0), pos.y-2, pos.x+(_w/10.0), pos.y+2, bezier2, pos.y+4);  //right side arc
  }

  void mousePos(int x,int y,boolean pressed)
  {
    if(pressed)
    {
      if(isHit(x,y)) {
        // move knob
        PVector dir = PVector.sub(_p1, _p2);  //laenge der 2 punkte bestimmen
        _pos = 1.0 / dir.mag() * (y-_p1.y);  //mapping im zahlenbereich (laenge in scalar) . mag (magnitude) berechnet die laenge in scalar (eine zahl)
      }
    }
    else
    {  // mouse over
    }
  }
  void mouseOver(int x, int  y) {
    if(isHit(x,y)) {
      noFill();
      int t = 10;
      strokeWeight(t  );
      
      //fade
      float al=100;
      al-= (millis()%1000/10.0);

      stroke(_a[0], _a[1], _a[2],al);
      
      //as drawn at the beginning (can be different)
      bezier(_p1.x-(_w/2.0), _p1.y, _p1.x-(_w/10.0), _p1.y + (_h/8.0),  _p2.x-(_w/10.0), _p2.y-(_h/8.0), _p2.x-(_w/2.0), _p2.y);  //left side
      bezier(_p1.x+(_w/2.0), _p1.y, _p1.x+(_w/10.0), _p1.y + (_h/8.0), _p2.x +(_w/10.0), _p2.y-(_h/8.0), _p2.x+(_w/2.0), _p2.y);  //right side
      bezier(_p1.x-(_w/2.0), _p1.y, _p1.x-(_w/5.0), _p1.y-(_h/12), _p1.x+(_w/5.0), _p1.y-(_h/12), _p1.x+(_w/2.0), _p1.y);  //top
      bezier(_p2.x-(_w/2.0), _p2.y, _p2.x-(_w/5.0), _p2.y+(_h/12), _p2.x+(_w/5.0), _p2.y+(_h/12), _p2.x+(_w/2.0), _p2.y);  //bottom
    }
  }
}
checkbox class:
/* ----------------------------------------------------------------------------
 *  codingSpace18					
 * ----------------------------------------------------------------------------
 *  GUI - main class
 * ----------------------------------------------------------------------------
 *  prog: eddi.lecesne@zhdk.ch
 *  13.11.2010
 * ----------------------------------------------------------------------------
 */
class Checkbox
{
  PVector _p1;
  float     _r;
  float   _pos;
  boolean _activateFlag = false;
  int _time1;
  boolean _pressedOnce=false;

  Checkbox(int x,int y,int d)
  {   
    _p1 = new PVector(x, y);  //center of circle

    _r = d*0.5;
  }

  float pos()
  {
    return _pos;
  }
  //for main class if feedback is needed
  boolean isChecked(){
    return _activateFlag;
  }

  boolean isHit(int x,int y)
  {
    if(x > _p1.x-_r && x < _p1.x+_r && y > _p1.y-_r && y < _p1.y+_r) {
      return true;
    }
    else {
      return false;
    }
  }
  void draw()
  {
    //_time = System.currentTimeMillis();
    pushStyle();
    drawCheckbox();
    activate(_activateFlag);
    popStyle();
  }
  void drawCheckbox() {
    noFill();
    smooth();
    strokeWeight(2);   
    stroke(50,50,40,255);

    ellipse(_p1.x, _p1.y, _r*2, _r*2);
  }
  void mousePos(int x,int y)
  {
    if(isHit(x,y)) {
      _activateFlag = !_activateFlag;
    }
  }
  void mouseOver(int x, int  y) {
    if(isHit(x,y)) {
      noFill();
      strokeWeight(5);   
      stroke(50,50,40,90);
      ellipse(_p1.x, _p1.y, (_r*2)+2, (_r*2)+2);
    }
  }
  void activate(boolean a) {
    if(a) {
      strokeWeight(5);
      fill(50,50,40,100);   
      stroke(50,50,40,100);
      ellipse(_p1.x, _p1.y, (_r*2)+2, (_r*2)+2);

      text("active!", _p1.x,_p1.y+(_r*2));
    }
  }
}
doubleclick class:
/* ----------------------------------------------------------------------------
 *  codingSpace18					
 * ----------------------------------------------------------------------------
 *  GUI - main class
 * ----------------------------------------------------------------------------
 *  prog: eddi.lecesne@zhdk.ch
 *  13.11.2010
 * ----------------------------------------------------------------------------
 */
class DoubleClick
{
  int _time1;
  boolean _pressedOnce=false;

  DoubleClick()
  {
  }

  boolean checkDoubleClick(int time)
  {
    boolean drawFlag=false;

    if(!_pressedOnce) {
      _time1 = time;
      _pressedOnce=true;
      drawFlag=false;
      println("time 1: "+_time1 +" " +_pressedOnce);
      return false;
    }
    if(_pressedOnce) {
      int time2 = time;
      int delta = time2-_time1;
      println("delta (max 150ms): " +time2 +"-"+_time1+"="+delta);
      if(delta<=150) {
        println("doubleclicked in " + delta +"ms");
        drawFlag=true;
        _pressedOnce=false;
        return true;
      }
      else {
        _time1 = time;
        _pressedOnce=true;
        return false;
      }
    }
    return false;
  }
  void ping() {
    smooth();
    float  a= (millis()%1000)/10.0;
    float b= (millis()%1000)/50.0;
    fill(203, 49, 49, a);
    stroke(203, 49, 49, a);
    ellipse(mX, mY, b, b);
  }
}