2023-08-26 23:00:03 +00:00
|
|
|
try { // for making it possiblie to run the test app in the following catch statement. It would complain on `exports` not being defined.
|
2023-08-26 18:18:36 +00:00
|
|
|
|
2023-09-09 10:25:35 +00:00
|
|
|
exports.create = function(cb, conf) {
|
2023-08-26 23:00:03 +00:00
|
|
|
|
|
|
|
const R = Bangle.appRect;
|
|
|
|
|
2023-09-02 09:17:04 +00:00
|
|
|
let o = {};
|
|
|
|
o.v = {}; // variables go here.
|
|
|
|
o.f = {}; // functions go here.
|
|
|
|
|
2023-08-29 20:03:42 +00:00
|
|
|
// configuration for the indicator:
|
|
|
|
|
2023-09-02 09:17:04 +00:00
|
|
|
o.c = Object.assign({ // constants go here.
|
2023-09-02 09:31:54 +00:00
|
|
|
useMap:false,
|
|
|
|
useIncr:true,
|
|
|
|
horizontal:false,
|
|
|
|
xStart:R.x2-R.w/4-4,
|
|
|
|
width:R.w/4,
|
|
|
|
yStart:R.y+4,
|
|
|
|
height:R.h-10,
|
|
|
|
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,
|
2023-09-12 12:54:08 +00:00
|
|
|
outerBorderSize:2,
|
|
|
|
innerBorderSize:2,
|
2023-09-18 23:35:45 +00:00
|
|
|
drawableSlider:true,
|
|
|
|
dragableSlider:true,
|
2023-09-19 17:27:58 +00:00
|
|
|
currLevel:undefined,
|
2023-09-20 17:53:53 +00:00
|
|
|
dragRect:R,
|
2023-08-29 20:03:42 +00:00
|
|
|
},conf);
|
|
|
|
|
2023-09-12 12:54:08 +00:00
|
|
|
let totalBorderSize = o.c.outerBorderSize + o.c.innerBorderSize;
|
|
|
|
o.c._xStart = o.c.xStart + totalBorderSize;
|
|
|
|
o.c._width = o.c.width - 2*totalBorderSize;
|
|
|
|
o.c._yStart = o.c.yStart + totalBorderSize;
|
|
|
|
o.c._height = o.c.height - 2*totalBorderSize;
|
2023-09-02 09:17:04 +00:00
|
|
|
if (o.c.rounded) o.c.rounded = 40;
|
|
|
|
|
|
|
|
o.c.STEP_SIZE = o.c._height/o.c.steps;
|
|
|
|
|
|
|
|
if (o.c.horizontal) {
|
|
|
|
let mediator = o.c._xStart;
|
|
|
|
o.c._xStart = o.c._yStart;
|
|
|
|
o.c._yStart = mediator;
|
|
|
|
mediator = o.c._width;
|
|
|
|
o.c._width = o.c._height;
|
|
|
|
o.c._height = mediator;
|
|
|
|
|
|
|
|
mediator = o.c.xStart;
|
|
|
|
o.c.xStart = o.c.yStart;
|
|
|
|
o.c.yStart = mediator;
|
|
|
|
mediator = o.c.width;
|
|
|
|
o.c.width = o.c.height;
|
|
|
|
o.c.height = mediator;
|
2023-08-24 23:05:34 +00:00
|
|
|
delete mediator;
|
|
|
|
}
|
|
|
|
|
2023-09-04 21:17:53 +00:00
|
|
|
o.c.r = {x:o.c.xStart, y:o.c.yStart, x2:o.c.xStart+o.c.width, y2:o.c.yStart+o.c.height, w:o.c.width, h:o.c.height};
|
|
|
|
|
2023-08-05 00:14:29 +00:00
|
|
|
// Initialize the level
|
2023-09-03 21:21:40 +00:00
|
|
|
o.v.level = (o.c.currLevel||o.c.currLevel===0)?o.c.currLevel:o.c.steps/2;
|
2023-08-05 00:14:29 +00:00
|
|
|
|
2023-09-02 09:17:04 +00:00
|
|
|
o.v.firstRun = true;
|
|
|
|
o.v.ebLast = 0;
|
2023-09-19 17:30:31 +00:00
|
|
|
o.v.dy = 0;
|
2023-08-10 00:19:59 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
if (o.c.dragableSlider) {
|
2023-09-20 17:53:53 +00:00
|
|
|
o.f.wasOnDragRect = (exFirst, eyFirst)=>{
|
|
|
|
"ram";
|
|
|
|
return exFirst>o.c.dragRect.x && exFirst<o.c.dragRect.x2 && eyFirst>o.c.dragRect.y && eyFirst<o.c.dragRect.y2;
|
|
|
|
};
|
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
o.f.wasOnIndicator = (exFirst)=>{
|
|
|
|
"ram";
|
|
|
|
if (!o.c.horizontal) return exFirst>o.c._xStart-o.c.oversizeL*o.c._width && exFirst<o.c._xStart+o.c._width+o.c.oversizeR*o.c._width;
|
|
|
|
if (o.c.horizontal) return exFirst>o.c._yStart-o.c.oversizeL*o.c._height && exFirst<o.c._yStart+o.c._height+o.c.oversizeR*o.c._height;
|
|
|
|
};
|
2023-08-24 23:05:34 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
o.f.dragSlider = e=>{
|
|
|
|
"ram";
|
2023-09-20 17:53:53 +00:00
|
|
|
if (o.v.ebLast==0) {
|
|
|
|
exFirst = o.c.horizontal?e.y:e.x;
|
|
|
|
eyFirst = o.c.horizontal?e.x:e.y;
|
|
|
|
}
|
2023-08-26 21:31:19 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
if (o.f.wasOnDragRect(exFirst, eyFirst)) {
|
|
|
|
o.v.dragActive = true;
|
|
|
|
if (!o.c.propagateDrag) E.stopEventPropagation&&E.stopEventPropagation();
|
2023-08-24 23:05:34 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
if (o.v.timeoutID) {clearTimeout(o.v.timeoutID); o.v.timeoutID = undefined;}
|
|
|
|
if (e.b==0 && !o.v.timeoutID && (o.c.timeout || o.c.timeout===0)) o.v.timeoutID = setTimeout(o.f.remove, 1000*o.c.timeout);
|
2023-08-15 21:07:55 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
let input = Math.min(o.c.horizontal?175-e.x:e.y, 170);
|
|
|
|
input = Math.round(input/o.c.STEP_SIZE);
|
2023-08-21 21:52:00 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
if (o.c.useMap && o.f.wasOnIndicator(exFirst)) { // If draging starts on the indicator, adjust one-to-one.
|
2023-08-07 22:56:16 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
o.v.level = Math.min(Math.max(o.c.steps-input,0),o.c.steps);
|
2023-08-15 20:50:29 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
if (o.v.level != o.v.prevLevel) cb("map",o.v.level);
|
|
|
|
o.f.draw&&o.f.draw(o.v.level);
|
2023-08-08 18:38:22 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
} else if (o.c.useIncr) { // Heavily inspired by "updown" mode of setUI.
|
2023-08-08 18:38:22 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
o.v.dy += o.c.horizontal?-e.dx:e.dy;
|
|
|
|
//if (!e.b) o.v.dy=0;
|
2023-08-08 18:38:22 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
let incr;
|
|
|
|
while (Math.abs(o.v.dy)>32) {
|
|
|
|
if (o.v.dy>0) { o.v.dy-=32; incr = 1;}
|
|
|
|
else { o.v.dy+=32; incr = -1;}
|
|
|
|
Bangle.buzz(20);
|
2023-08-08 18:38:22 +00:00
|
|
|
|
2023-09-20 17:53:53 +00:00
|
|
|
o.v.level = Math.min(Math.max(o.v.level-incr,0),o.c.steps);
|
|
|
|
cb("incr",incr);
|
|
|
|
o.f.draw&&o.f.draw(o.v.level);
|
|
|
|
}
|
2023-09-18 23:35:45 +00:00
|
|
|
}
|
2023-09-20 17:53:53 +00:00
|
|
|
o.v.ebLast = e.b;
|
|
|
|
};
|
|
|
|
}
|
2023-08-08 18:38:22 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
o.f.remove = ()=> {
|
|
|
|
Bangle.removeListener('drag', o.f.dragSlider);
|
|
|
|
o.v.dragActive = false;
|
|
|
|
cb("remove", o.v.prevLevel);
|
|
|
|
};
|
|
|
|
}
|
2023-08-08 18:38:22 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
if (o.c.drawableSlider) {
|
2023-08-05 00:14:29 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
o.f.updateBar = (levelHeight)=>{
|
|
|
|
"ram";
|
|
|
|
if (!o.c.horizontal) return {x:o.c._xStart,y:o.c._yStart+o.c._height-levelHeight,w:o.c._width,y2:o.c._yStart+o.c._height,r:o.c.rounded};
|
|
|
|
if (o.c.horizontal) return {x:o.c._xStart,y:o.c._yStart,w:levelHeight,h:o.c._height,r:o.c.rounded};
|
|
|
|
};
|
|
|
|
|
|
|
|
o.c.borderRect = {x:o.c._xStart-totalBorderSize,y:o.c._yStart-totalBorderSize,w:o.c._width+2*totalBorderSize,h:o.c._height+2*totalBorderSize,r:o.c.rounded};
|
|
|
|
|
|
|
|
o.c.hollowRect = {x:o.c._xStart-o.c.innerBorderSize,y:o.c._yStart-o.c.innerBorderSize,w:o.c._width+2*o.c.innerBorderSize,h:o.c._height+2*o.c.innerBorderSize,r:o.c.rounded};
|
2023-09-02 09:17:04 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
o.f.draw = (level)=>{
|
|
|
|
"ram";
|
2023-08-05 00:14:29 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
if (true || o.v.firstRun || !o.c.lazy) {
|
|
|
|
g.setColor(o.c.colorFG).fillRect(o.c.borderRect); // To get outer border...
|
|
|
|
}
|
|
|
|
if (false && level == o.v.prevLevel) {if (!o.v.firstRun) return; if (o.v.firstRun) o.v.firstRun = false;}
|
2023-08-05 00:14:29 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
o.v.prevLevel = level;
|
2023-08-05 00:14:29 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
g.setColor(o.c.colorBG).
|
|
|
|
fillRect(o.c.hollowRect). // ... and here it's made hollow.
|
|
|
|
setColor(0==level?o.c.colorBG:o.c.colorFG).
|
|
|
|
fillRect(o.f.updateBar(level*o.c.STEP_SIZE)); // Here the bar is drawn.
|
2023-08-08 18:38:22 +00:00
|
|
|
|
2023-09-18 23:35:45 +00:00
|
|
|
//print(level);
|
|
|
|
//print(process.memory().usage);
|
|
|
|
};
|
|
|
|
}
|
2023-08-07 22:56:16 +00:00
|
|
|
|
2023-09-02 09:17:04 +00:00
|
|
|
if (o.c.autoProgress) {
|
2023-09-12 22:10:20 +00:00
|
|
|
o.v.shouldAutoDraw = true;
|
2023-09-02 09:17:04 +00:00
|
|
|
o.f.autoUpdate = ()=>{
|
|
|
|
//if (o.v.level===undefined) o.v.level = -1;
|
|
|
|
o.v.level = o.v.level+1;
|
2023-09-18 23:35:45 +00:00
|
|
|
if (o.v.shouldAutoDraw) o.f.draw&&o.f.draw(o.v.level);
|
2023-09-09 22:51:15 +00:00
|
|
|
cb("auto");
|
2023-09-03 21:19:42 +00:00
|
|
|
if (o.v.level==o.c.steps) {o.f.stopAutoUpdate();}
|
2023-08-27 10:17:57 +00:00
|
|
|
};
|
2023-09-16 16:51:39 +00:00
|
|
|
o.f.startAutoUpdate = ()=>{
|
|
|
|
o.f.stopAutoUpdate();
|
2023-09-18 23:35:45 +00:00
|
|
|
if (o.v.shouldAutoDraw) o.f.draw&&o.f.draw(o.v.level);
|
2023-09-16 16:51:39 +00:00
|
|
|
o.v.autoIntervalID = setInterval(o.f.autoUpdate,1000);
|
|
|
|
};
|
2023-09-03 21:19:42 +00:00
|
|
|
o.f.stopAutoUpdate = ()=>{if (o.v.autoIntervalID) {clearInterval(o.v.autoIntervalID); o.v.autoIntervalID = undefined;}};
|
2023-08-27 10:17:57 +00:00
|
|
|
}
|
2023-09-02 09:17:04 +00:00
|
|
|
|
|
|
|
//o.f.printThis = ()=>(print(this));
|
|
|
|
|
|
|
|
return o;
|
2023-08-06 00:03:38 +00:00
|
|
|
}
|
2023-08-26 18:18:36 +00:00
|
|
|
|
2023-08-26 22:37:33 +00:00
|
|
|
} catch (e) {
|
2023-09-02 09:31:54 +00:00
|
|
|
print(e);
|
2023-09-15 20:46:53 +00:00
|
|
|
let appName = "spotrem";
|
|
|
|
eval(require("Storage").read(appName+".app.js"));
|
2023-08-26 22:37:33 +00:00
|
|
|
}
|