/* TimeEventList * * a list of time events * also handles the maintenance of the list, and determining what the current display color should be */ class TimeEventList { TimeEvent[] events; TimeEvent bg; int ne = 8; float longDelay = 3000; int sz = 50; // box size value (box h,w = sz*2, sz*2) int w2 = width/2; int h2 = height/2; boolean extendedDrag = false; boolean animate = false; int animateStep = 0; // constructor - pass in half-width of the target box in the centre of the display TimeEventList( int _sz ) { events = new TimeEvent[ne]; for( int x=0 ; x0 ; j-- ) { events[j].copyFrom( events[j-1] ); } } // handle the button being pressed void mousePressed() { if( mouseButton == LEFT ) { shiftElements(); events[0].now( events[0].event_down ); events[0].here(); } animate = false; extendedDrag = false; } // handle the button being held down void mouseDragged() { if( mouseButton == LEFT ) { events[0].here(); if( events[0].duration > longDelay ) { extendedDrag = true; } } } // update the location/time for idle - this is necessary to keep track of the "off" blink time void mouseIdle() { events[0].here(); } // handle the button being released void mouseReleased() { events[0].updateDuration(); shiftElements(); events[0].now( events[0].event_up ); if( extendedDrag == true ) { bg.copyFrom( events[0] ); stopAnimation(); } else { startAnimation(); } } // for averaging out blink timing... float evenDurations() // on time { float ret = 0; for( int j = 2 ; j < ne ; j+=2 ) { ret += events[j].duration; } return( ret/3 ); } float oddDurations() // off time { float ret = 0; for( int j = 3 ; j < ne ; j+=2 ) { ret += events[j].duration; } return( ret/3 ); } // start up the animation // we basically keep the trigger time for each animation step in the TimeEvent structure itself. // we start with "now" and add in the average durations (computed via the above) and generate the // trigger times for a complete animation cycle void startAnimation() { animate = true; animateStep = ne-1; float onDuration = evenDurations(); float offDuration = oddDurations(); float nowTime = millis(); for( int j=ne-1 ; j>=0 ; j-- ) { if( (j&0x01) == 0x01 ) { nowTime += offDuration; } else { nowTime += onDuration; } events[j].animateTime = nowTime; } } // step through an animation cycle // when we've reached the end of the cycle, just call the above to re-setup the durations void updateAnimationStep() { float nowTime = millis(); // move on to the next step, if we've reached our time if( events[animateStep].animateTime <= nowTime ) { animateStep--; } // if we've gone past the end of the array, reset it and restart the timer if( animateStep < 0 ) { startAnimation(); } } // disable the animation display void stopAnimation() { animate = false; } // get a COLOR from the passed in X and Y values color colorHueFromXY( int x, int y ) { int h = x - w2 + sz; int s = sz; int v = sz; y = y - h2 + sz; if( y < sz ) { // top half of screen s = sz - (sz - y); } if( y > sz ) { // bottom half of screen v = sz + sz - y; } color c = color( h, s, v ); return( c ); } // return the current color based on animation, clicking etc color getColor() { if( mousePressed ) { return( colorHueFromXY( events[0].mx, events[0].my )); } if( !animate ) { return( colorHueFromXY( bg.mx, bg.my )); } updateAnimationStep(); if( events[animateStep].event == events[animateStep].event_up ) { return( colorHueFromXY( bg.mx, bg.my )); } return( colorHueFromXY( events[animateStep].mx, events[animateStep].my ) ); } // display the contents in a single line for debug void debugPrint() { print( "b) " ); bg.debugPrint(); for( int j = 0 ; j < ne ; j++ ) { print( j + ") " ); events[j].debugPrint(); } println( "averages: " + evenDurations() + " " + oddDurations() ); } }