diff --git a/apps/swscroll/ChangeLog b/apps/swscroll/ChangeLog new file mode 100644 index 000000000..c650baf72 --- /dev/null +++ b/apps/swscroll/ChangeLog @@ -0,0 +1 @@ +0.01: Inital release. diff --git a/apps/swscroll/README.md b/apps/swscroll/README.md new file mode 100644 index 000000000..f97d59b71 --- /dev/null +++ b/apps/swscroll/README.md @@ -0,0 +1,9 @@ +This first release seems servicable in testing so far. + +To get the standard menu scrolling back, just remove this app from your Bangle. + +TODO: +- Maybe have how much of "trailing space" there are after the last entry should be dynamic in size, now it's always 8 pixels which corresponds to if there are a widget field and a menu title present. +- I want to change the size of menu entries to be a little bigger vertically. + +Drag List Down icon by Icons8 diff --git a/apps/swscroll/app.png b/apps/swscroll/app.png new file mode 100644 index 000000000..7abd582c2 Binary files /dev/null and b/apps/swscroll/app.png differ diff --git a/apps/swscroll/boot.js b/apps/swscroll/boot.js new file mode 100644 index 000000000..fc5650cad --- /dev/null +++ b/apps/swscroll/boot.js @@ -0,0 +1,100 @@ +E.showScroller = (function(options) { + /* options = { + h = height + c = # of items + scroll = initial scroll position + scrollMin = minimum scroll amount (can be negative) + draw = function(idx, rect) + select = function(idx) + } + + returns { + draw = draw all + drawItem(idx) = draw specific item + } + */ +if (!options) return Bangle.setUI(); // remove existing handlers + +var menuShowing = false; +var R = Bangle.appRect; +var Y = Bangle.appRect.y; +var n = Math.ceil(R.h/options.h); +var menuScrollMin = 0|options.scrollMin; +var menuScrollMax = options.h*options.c - R.h; +if (menuScrollMax { + g.reset().clearRect(R.x,R.y,R.x2,R.y2); + g.setClipRect(R.x,R.y,R.x2,R.y2); + var a = YtoIdx(R.y); + var b = Math.min(YtoIdx(R.y2),options.c-1); + for (var i=a;i<=b;i++) + options.draw(i, {x:R.x,y:idxToY(i),w:R.w,h:options.h}); + g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); +}, drawItem : i => { + var y = idxToY(i); + g.reset().setClipRect(R.x,y,R.x2,y+options.h); + options.draw(i, {x:R.x,y:y,w:R.w,h:options.h}); + g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); +}}; +var rScroll = s.scroll&~1; // rendered menu scroll (we only shift by 2 because of dither) +s.draw(); // draw the full scroller +g.flip(); // force an update now to make this snappier +Bangle.setUI({ + mode : "custom", + back : options.back, + swipe : (hor,ver)=>{ + pixels = 120; + var dy = ver*pixels; + if (s.scroll - dy > menuScrollMax) + dy = s.scroll - menuScrollMax-8; // Makes it so the last 'page' has the same position as previous pages. This should be done dynamically (change the static 8 to be a variable) so the offset is correct even when no widget field or title field is present. + if (s.scroll - dy < menuScrollMin) + dy = s.scroll - menuScrollMin; + s.scroll -= dy; + var oldScroll = rScroll; + rScroll = s.scroll &~1; + dy = oldScroll-rScroll; + if (!dy || options.c<=3) return; //options.c<=3 should maybe be dynamic, so 3 would be replaced by a variable dependent on R=Bangle.appRect. It's here so we don't try to scroll if all entries fit in the app rectangle. + g.reset().setClipRect(R.x,R.y,R.x2,R.y2); + g.scroll(0,dy); + var d = ver*pixels; + if (d < 0) { + g.setClipRect(R.x,R.y2-(1-d),R.x2,R.y2); + let i = YtoIdx(R.y2-(1-d)); + let y = idxToY(i); + //print(i, options.c, options.c-i); //debugging info + while (y < R.y2 - (options.h*((options.c-i)<=0)) ) { //- (options.h*((options.c-i)<=0)) makes sure we don't go beyond the menu entries in the menu object "options". This has to do with "dy = s.scroll - menuScrollMax-8" above. + options.draw(i, {x:R.x,y:y,w:R.w,h:options.h}); + i++; + y += options.h; + } + } else { // d>0 + g.setClipRect(R.x,R.y,R.x2,R.y+d); + let i = YtoIdx(R.y+d); + let y = idxToY(i); + //print(i, options.c, options.c-i); //debugging info + while (y > R.y-options.h) { + options.draw(i, {x:R.x,y:y,w:R.w,h:options.h}); + y -= options.h; + i--; + } + } + g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); + }, touch : (_,e)=>{ + if (e.y=0) && i