diff --git a/modules/SliderInput.js b/modules/SliderInput.js index 7e274644562..407ea8c1e1a 100644 --- a/modules/SliderInput.js +++ b/modules/SliderInput.js @@ -5,40 +5,47 @@ exports.interface = function(cb, conf) { const R = Bangle.appRect; // Configuration for the indicator: -conf = conf?conf:{}; -const USE_MAP = conf.useMap || false; -const USE_INCR = conf.useIncr===false?false:true; -const ROTATE = conf.horizontal || false; -let X_START = (conf.xStart+4 || R.x2-R.w/4-4+4); // +4 to compensate for the border. -let WIDTH = conf.width-8 || R.w/4-8; // -8 to compensate for the border. -let Y_START = (conf.yStart+4 || R.y+4+4); // +4 to compensate for the border. -let HEIGHT = conf.height-8 || R.h-10-8; // -8 to compensate for the border. -const STEPS = conf.steps || 30; //Default corresponds to my phones volume range, [0,30]. Maybe it should be 31. Math is hard sometimes... -const OVERSIZE_R = conf.oversizeR || 0; -const OVERSIZE_L = conf.oversizeL || 0; -const TIMEOUT = conf.timeout===false?false:(conf.timeout===0?0:(conf.timeout || 1)); -const COL_FG = conf.colorFG || g.theme.fg2; -const COL_BG = conf.colorBG || g.theme.bg2; -const LAZY = conf.lazy===false?false:true; -const ROUND = conf.rounded?40:0; -const PROPAGATE = conf.propagateDrag || false; -const IMMEDIATE_DRAW = conf.immediateDraw || false; -const AUTO_PROGRESS = conf.autoProgress || false; - -const STEP_SIZE = HEIGHT/STEPS; - -if (ROTATE) { - let mediator = X_START; - X_START = Y_START; - Y_START = mediator; - mediator = WIDTH; - WIDTH = HEIGHT; - HEIGHT = mediator; +if (conf.xStart) conf.xStart += 4; // +4 to compensate for the border. +if (conf.width) conf.width -= 8; // +8 to compensate for the border. +if (conf.yStart) conf.yStart += 4; // +4 to compensate for the border. +if (conf.height) conf.height -= 8; // +8 to compensate for the border. +if (conf.rounded) conf.rounded = 40; + +let c = Object.assign({ +useMap:false, +useIncr:true, +horizontal:false, +xStart:R.x2-R.w/4-4+4, // +4 to compensate for the border. +width:R.w/4-8, // -8 to compensate for the border. +yStart:R.y+4+4, // +4 to compensate for the border. +height:R.h-10-8, // -8 to compensate for the border. +steps:30, // Default corresponds to my phones volume range, [0,30]. Maybe it should be 31. Math is hard sometimes... +oversizeR:0, +oversizeL:0, +timeout:1, +colorFG:g.theme.fg2, +colorBG:g.theme.bg2, +lazy:true, +rounded:0, +propagateDrag:false, +immediateDraw:false, +autoProgress:false, +},conf); + +const STEP_SIZE = c.height/c.steps; + +if (c.horizontal) { + let mediator = c.xStart; + c.xStart = c.yStart; + c.yStart = mediator; + mediator = c.width; + c.width = c.height; + c.height = mediator; delete mediator; } // Initialize the level -let level = conf.currLevel || STEPS/2; +let level = c.currLevel || c.steps/2; let prevLevel; let firstRun = true; @@ -47,42 +54,42 @@ let exFirst; let wasOnIndicator = (exFirst)=>{ "ram"; - if (!ROTATE) return exFirst>X_START-OVERSIZE_L*WIDTH && exFirstY_START-OVERSIZE_L*HEIGHT && exFirstc.xStart-c.oversizeL*c.width && exFirstc.yStart-c.oversizeL*c.height && exFirst{ "ram"; - if (!ROTATE) return {x:X_START,y:Y_START+HEIGHT-levelHeight,w:WIDTH,y2:Y_START+HEIGHT,r:ROUND}; - if (ROTATE) return {x:X_START,y:Y_START,w:levelHeight,h:HEIGHT,r:ROUND}; + if (!c.horizontal) return {x:c.xStart,y:c.yStart+c.height-levelHeight,w:c.width,y2:c.yStart+c.height,r:c.rounded}; + if (c.horizontal) return {x:c.xStart,y:c.yStart,w:levelHeight,h:c.height,r:c.rounded}; }; let dragSlider = e=>{ "ram"; - if (!PROPAGATE) E.stopEventPropagation&&E.stopEventPropagation(); + if (!c.propagateDrag) E.stopEventPropagation&&E.stopEventPropagation(); if (timeout) {clearTimeout(timeout); timeout = undefined;} - if (e.b==0 && !timeout && TIMEOUT) timeout = setTimeout(remove, 1000*TIMEOUT); + if (e.b==0 && !timeout && (c.timeout || c.timeout===0)) timeout = setTimeout(remove, 1000*c.timeout); - let input = Math.min(ROTATE?175-e.x:e.y, 170); + let input = Math.min(c.horizontal?175-e.x:e.y, 170); input = Math.round(input/STEP_SIZE); - if (ebLast==0) exFirst = ROTATE?e.y:e.x; + if (ebLast==0) exFirst = c.horizontal?e.y:e.x; // If draging on the indicator, adjust one-to-one. - if (USE_MAP && wasOnIndicator(exFirst)) { + if (c.useMap && wasOnIndicator(exFirst)) { - level = Math.min(Math.max(STEPS-input,0),STEPS); + level = Math.min(Math.max(c.steps-input,0),c.steps); if (level != prevLevel) cb("map",level); draw(level); - } else if (USE_INCR) { // Heavily inspired by "updown" mode of setUI. + } else if (c.useIncr) { // Heavily inspired by "updown" mode of setUI. - dy += ROTATE?-e.dx:e.dy; + dy += c.horizontal?-e.dx:e.dy; //if (!e.b) dy=0; let incr; @@ -91,7 +98,7 @@ let dragSlider = e=>{ else { dy+=32; incr = -1;} Bangle.buzz(20); - level = Math.min(Math.max(level-incr,0),STEPS); + level = Math.min(Math.max(level-incr,0),c.steps); cb("incr",incr); draw(level); } @@ -107,19 +114,19 @@ let draw = (level)=>{ // If user drags directly on the draw area, adjust level one-to-one. // Pauses and resets the time out when interacted with. - if (firstRun || !LAZY) { - g.setColor(COL_FG).fillRect(borderRect); // To get outer border... + if (firstRun || !c.lazy) { + g.setColor(c.colorFG).fillRect(borderRect); // To get outer border... } if (level == prevLevel) {if (!firstRun) return; if (firstRun) firstRun = false;} prevLevel = level; - g.setColor(COL_BG). + g.setColor(c.colorBG). fillRect(hollowRect). // ... and here it's made hollow. - setColor(0==level?COL_BG:COL_FG). + setColor(0==level?c.colorBG:c.colorFG). fillRect(updateBar(level*STEP_SIZE)); // Here the bar is drawn. - //print(level); + print(level); //print(process.memory().usage); }; @@ -129,19 +136,19 @@ let remove = ()=> { }; let timeout; -if (TIMEOUT) timeout = setTimeout(remove, 1000*TIMEOUT); +if (c.timeout || c.timeout===0) timeout = setTimeout(remove, 1000*c.timeout); let dy = 0; g.reset(); Bangle.prependListener('drag', dragSlider); -if (IMMEDIATE_DRAW) draw(level); +if (c.immediateDraw) draw(level); -if (AUTO_PROGRESS) { +if (c.autoProgress) { draw(level); let autoUpdate = ()=>{ level = level?level+1:0; draw(level); - if (level==STEPS) {clearInterval(autoInterval); return;} + if (level==c.steps) {clearInterval(autoInterval); return;} }; let autoInterval; autoInterval = setInterval(autoUpdate,1000);