public class Rounder{ PApplet parent; Box b,n; static final int NONE = 0; static final int BACK = 1; static final int AHEAD = 2; static final int RANGE = 3; int sliding = NONE; int startX=0; int startBack=0; int startAhead=0; int lookBackPos, lookAheadPos; int maxLookBack, totalPins; float diameter, notchDepth; Rounder(PApplet parent, Box b){ this.parent = parent; this.b = b; parent.registerMouseEvent(this); lookBackPos = 3; lookAheadPos = 0; maxLookBack = 10; totalPins = maxLookBack*2 + 1; diameter = 15; notchDepth = 3; textFont(meta12); n = new Box(b, b.width-diameter, diameter, diameter/2, textAscent()*2.5); } Box getBox(){ return b; } int getLookAhead(){ return lookAheadPos; } int getLookBack(){ return lookBackPos; } void draw(){ // draw pins noStroke(); fill(0.6); ellipse(n.left, n.top+n.height/2-0.5, n.height, n.height); ellipse(n.right, n.top+n.height/2-0.5, n.height, n.height); beginShape(); vertex(n.left, n.top); for(int i=0; i2){ fill(1, 0.6); text(rangeWeeks+" wks", range); } // lookBackSlider if(sliding == BACK || (sliding == NONE && mouseHover(mouseX, mouseY) == BACK)) fill(0.6,0.8,0.8); else fill(0.4); beginShape(); vertex(sliderBackPos, n.top - notchDepth); vertex(sliderBackPos, n.bottom + 2); vertex(sliderBackPos-2, n.bottom + 2); vertex(sliderBackPos-2, n.top + notchDepth-2); vertex(sliderBackPos - notchDepth*2, n.top - notchDepth); endShape(); if(sliding == BACK || (sliding == NONE && mouseHover(mouseX, mouseY) == BACK)) fill(0.6,0.8,0.8,0.5); else fill(0.4,0.5); textAlign(RIGHT); String wksBack = lookBackPos+" wks back"; text(wksBack, sliderBackPos + textWidth(wksBack)*((float)lookBackPos/maxLookBack), range.bottom + textAscent()*1.25); // lookAheadSlider if(sliding == AHEAD || (sliding == NONE && mouseHover(mouseX, mouseY) == AHEAD)) fill(0.6,0.8,0.8); else fill(0.4); beginShape(); vertex(sliderAheadPos, n.top - notchDepth); vertex(sliderAheadPos, n.bottom + 2); vertex(sliderAheadPos+2, n.bottom + 2); vertex(sliderAheadPos+2, n.top + notchDepth-2); vertex(sliderAheadPos + notchDepth*2, n.top - notchDepth); endShape(); if(sliding == AHEAD || (sliding == NONE && mouseHover(mouseX, mouseY) == AHEAD)) fill(0.6,0.8,0.8,0.5); else fill(0.4,0.5); textAlign(LEFT); String wksAhead = lookAheadPos+" wks ahead"; text(wksAhead, sliderAheadPos - textWidth(wksAhead)*((float)lookAheadPos/maxLookBack), range.bottom + textAscent()*1.25); // TITLE fill(0.4); text("Average popularity over weeks", b.left + textAscent()*.5, b.top + textAscent()*1.5); } public void mouseEvent(MouseEvent event){ int x = event.getX(); int y = event.getY(); switch (event.getID()) { case MouseEvent.MOUSE_PRESSED: mousePressed(x,y); break; case MouseEvent.MOUSE_RELEASED: mouseReleased(); break; case MouseEvent.MOUSE_DRAGGED: mouseDragged(x,y); break; } } int mouseHover(int x, int y){ if(b.containsMouse()){ float sliderBackPos = lerp(n.left, n.right, unlerp(0, totalPins, maxLookBack-lookBackPos+0.5)); if(x < sliderBackPos && x > sliderBackPos - notchDepth*5 && y > n.top - notchDepth && y < n.bottom + 2) return BACK; float sliderAheadPos = lerp(n.left, n.right, unlerp(0, totalPins, maxLookBack+lookAheadPos+0.5)) +1; if(x > sliderAheadPos && x < sliderAheadPos + notchDepth*5 && y > n.top - notchDepth && y < n.bottom + 2) return AHEAD; if(x > sliderBackPos && x < sliderAheadPos && y > n.top && y < n.bottom) return RANGE; } return NONE; } void mousePressed(int x, int y){ sliding = mouseHover(x,y); startX = x; startBack = lookBackPos; startAhead = lookAheadPos; } void mouseReleased(){ sliding = NONE; } void mouseDragged(int x, int y){ if(sliding != NONE){ int offset = x - startX; int offsetPins = round(lerp(0, totalPins, unlerp(0, n.width, offset))); switch(sliding){ case BACK: offsetPins = constrain(offsetPins, -1*(maxLookBack - startBack - startAhead), startBack); lookBackPos = startBack - offsetPins; break; case AHEAD: offsetPins = constrain(offsetPins, -startAhead, (maxLookBack - startBack - startAhead)); lookAheadPos = startAhead + offsetPins; break; case RANGE: offsetPins = constrain(offsetPins, -1*min(maxLookBack-startBack, startAhead), min(maxLookBack-startAhead, startBack) ); lookBackPos = startBack - offsetPins; lookAheadPos = startAhead + offsetPins; break; } } } }