From f1973805471bcc0f2054ba9a297b9adeb60930fa Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 16 Oct 2021 14:49:13 +0100 Subject: [PATCH] Toucher: support for b2, Pastel: added 2 new custom fonts --- apps.json | 6 +- apps/pastel/ChangeLog | 1 + apps/pastel/README.md | 5 +- apps/pastel/pastel.app.js | 14 ++++ apps/pastel/pastel.settings.js | 4 +- apps/toucher/ChangeLog | 3 +- apps/toucher/README.md | 22 +++++ apps/toucher/app.js | 145 +++++++++++++++++++++++---------- apps/toucher/screenshot1.jpg | Bin 0 -> 21329 bytes 9 files changed, 152 insertions(+), 48 deletions(-) create mode 100644 apps/toucher/README.md create mode 100644 apps/toucher/screenshot1.jpg diff --git a/apps.json b/apps.json index c7abcf9f0..8e0dd604d 100644 --- a/apps.json +++ b/apps.json @@ -1478,9 +1478,9 @@ "name": "Touch Launcher", "shortName":"Toucher", "icon": "app.png", - "version":"0.06", + "version":"0.07", "description": "Touch enable left to right launcher.", - "tags": "tool,system,launcher", + "tags": "tool,system,launcher,b2", "type":"launch", "data": [ {"name":"toucher.json"} @@ -3517,7 +3517,7 @@ "name": "Pastel Clock", "shortName": "Pastel", "icon": "pastel.png", - "version":"0.04", + "version":"0.05", "description": "A Configurable clock with custom fonts and background", "tags": "clock,b2", "type":"clock", diff --git a/apps/pastel/ChangeLog b/apps/pastel/ChangeLog index e0e967166..1277f0d9d 100644 --- a/apps/pastel/ChangeLog +++ b/apps/pastel/ChangeLog @@ -2,3 +2,4 @@ 0.02: Display 12 hour clock as 12:xx not 00:xx when just into PM 0.03: Make it work with Gadgetbridge, Notifications fullscreen on a Bangle 2 0.04: Leave space at the bottom for Chrono widget, set back option at first option +0.05: Added 2 new fonts diff --git a/apps/pastel/README.md b/apps/pastel/README.md index 9e8c133ec..324c3915a 100644 --- a/apps/pastel/README.md +++ b/apps/pastel/README.md @@ -1,7 +1,7 @@ # Pastel Clock - a configurable clock with custom fonts and background * Designed specifically for Bangle 1 and Bangle 2 -* A choice of 5 different custom fonts +* A choice of 7 different custom fonts * Supports the Light and Dark themes * Has a settings menu, change font, enable/disable the grid and the date display @@ -15,3 +15,6 @@ I came up with the name Pastel due to the shade of the grid background. ![](screenshot_b1_light.jpg) ![](screenshot_b2_dark.jpg) +![](screenshot_monoton.jpg) +![](screenshot_elite.jpg) + diff --git a/apps/pastel/pastel.app.js b/apps/pastel/pastel.app.js index 98f8af7f9..1fe3e4a58 100644 --- a/apps/pastel/pastel.app.js +++ b/apps/pastel/pastel.app.js @@ -47,6 +47,16 @@ var scale = 1; // size multiplier for this font g.setFontCustom(font, 46, widths, 58+(scale<<8)+(1<<16)); }; +Graphics.prototype.setFontMonoton = function(scale) { + // Actual height 44 (43 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAABmwAAAAAAzYAAAAAAZsAAAAAAM2AAAAAAGbAAAAAADNgAAAAABmwAAAAAAzYAAAAAAZsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAD+AAAAAAf8AAAAAD/ggAAAAf8HwAAAD/g/4AAAf8H/AAAD/g/4OAAf8H/B/AD/g/4P+Af8H/B/wAfg/4P+AAMH/B/wAAA/4H+AAAD/A/4AAAB4H/AAAAAA/4AAAAAH/AAAAAAP4AAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAA/gAAAAAH//gAAAAf//8AAAA/AAPgAAA8f/x8AAB4//+PAAB5+APxwABzwfwecAAzj//jnAA7n+P85gA7ngAPO4AbnH/xzsAdnP/+c3AN3PAHndgGzOAA5m4DbuAAO7MD9mAADN2Bs3AAB2bA2bAAAbNgbNgAANmwNmwAAGzYGzYAADZsDdmAADN2B+7AABuzAbMwABmbgNneAD3NgHZ3+/3MwBuc//nO4A7nB8HGYAM58AfOcAHeP/+OcABzx/8ecAAc+AA+cAAHH//8cAAB4//48AAAPg+B8AAAD+AP4AAAAP//wAAAAA/+AAAAAAAAAAAAAAAAAAABsAAAAAAA2AAAAAAAbAAAAAAANgAAAAAAGwAAAAAADf////8ABv////+AA3/////AAbAAAAAAAN/////wAG/////4ADYAAAAAABv////+AA3/////AAb/////gANgAAAAAAG/////4ADf////8AAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAADcAAAA2wBs2AADbYA2bAADtsAbZgADm2AftwAHjbAN24AHNtgGzYAPO2wDZsAPebYBs2AOeNsA2bAec22AbNge87bANmwc55tgG7c8542wD9355zbYA2Z5zztsAbODzjm2ANz/nnjbADc/nnhtgBnCPHA2wA74fPAbYAOf+OANsADj8eAG2AA8A+ADbAAP/8AAAAAB/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAABgG6AAAAuwDdsAAG3YBs2AADZuA27AABu3A/ZgAA7dgbtwAAduwN2w2zG3YGzYbZjZsDZsNsxs2Bs2G2Y2bA2bDbMbNgbNhtmNmwNmw2zGzYG7MbdnbsD939m/d2A2Z/7PM3AbuBtwO7AOz73eeZgDc/9n+dwB3H2Y8cwAZ4HnA84AGf/5/84ADz/OP44AAeALwB4AAH/+//4AAA/+H/wAAADwAfAAAAAAAAAAAAAAAAAAAAAAAZsAAAAAB82AAAAAD+bAAAAAHzNgAAAAPjmwAAAAfHzYAAAB+P5sAAAD8fM2AAAHw+ObAAAPj8fNgAAfH4/mwAA+Ph8zYAAcfH4ZsAAA+Px82AAB8fD+bAAD4+HzNgABh8PhmwAAH4/AzYAAPx+AZsAAPD4AM2AAGHwP+bfgAfgH/NvwA/AABmwAA8AAAzYAAYAA/5t+AAAAf82/AAAAAGbAAAAAADNgAAAAAAAAAAAAAAAAAAAAAAAGAAE///ADAAGf//gBwADP//wCcABmAAADmAAz//8C7gAZ//+DMwAMwAAA3YAGf//hZsADP//xu3ABn//4zdgAzDNsNuwAZhu2GzYAMw2bDZsAGYbNhs2ADMNmw2bABmGzYbNgAzDZsdmwAZhs2M3YAMw3d+zcAGYZm+ZsADMOzgd2ABmDM883AAzB3P87AAZgZx47gAMwOcB5gAGYDn/5gADMA4/zwAAAAPADwAAAAD8fgAAAAAf/gAAAAAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB///4AAAD////AAAHwAADwAAHH//8eAAHP///ngAHfgAB8wAHeH/8PcADcf//x3ADsf//+ZgBu8AADu4B2c//8zMA3d///M2AbNwAB2bgduxs2bswP2Z2/O3YGzYzbDZsDZsbths2Bs2Nmw2bA2bGzYbNgbNjZsNmwNmxs2GzYH7c2bHbsDtmbtzdmA2bM3fs3AbMHZnO7AM3BuYOZgHZAzP+dgBmAMx+cwA7gHeAcwAMgB3584AHAAc/84ABgAHHx4AAAAB4D4AAAAAf/wAAAAAD/gAAAAAAAAAAAAAAAAAAZsAAAAAAM2AAAAAAGbAAAAAADNgAAAAABmwAAAAAAzYAAAAAAZsAAAAAAM2AAAAPAGbAAAB/gDNgAAP+ABmwAD/wYAzYAf+D8AZsD/wf8AM2f8D/gAGT/gf8HgAf8D/g/wB/g/8H/AA8H/g/4MAA/8H/B+AH/g/4P+AH4H/B/wADA/4P+AAAH/B/wAAA/4P+AAAAfB/wAAAAAP+AAAAAB/wAAAAAD+AAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAGAAwAAAA/8H/gAAB//v/8AAB4B/APgADz+PP54ABn/x//OABng8eDzAB3HHOcdwA3P9z/nYA7P/d/5mAbOBmYO7ANmebvzNwP3fs392YGzc3ZmbsDZsZsxs2Bs2M2Y2bA2bGbMbNgbNjNmNmwNmxmzGzYGzYzZjZsDZsZsxs2Bs2M2Y2bA2bGbMbNgbNzNmNmwP2Zm7s3YDbv7M+7MBszt3OZuA3MGZwd2ANn/uf8zAGY+zn47gDvAc4A7gA78/Pj5gAOf/z/zwADj8cPjwAA+A/gHgAAH/9//gAAA/4P/AAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAD/4AAAAAHw/AAAAAHADwADAAHP8cABgAHf/nAA4AHeB5gDuAHcfOYAzADc/7uBdwBs8ezBmYBu4DdgbsA2Z924s3AbN+bM3bgfsxt2duwNm4zbG3YGzYZtjZsDZsM2xs2Bs2GbY2bA2bDNsbNgbNhv2NmwP242zO3YHbszbm7sBs3AAHZuA2Z///M2Abuf//O7AGzh/8ObgDc8AA+dgB3P//+dwAdx//8cwAGeAAA8wADn///44AA8///54AAPgAAB4AAB+AAPwAAAP///gAAAA//+AAAAAAAAAAAAAAAAAAAAAAAAAAAADbBmwAAABtgzYAAAA2wZsAAAAbYM2AAAANsGbAAAAG2DNgAAADbBmwAAABtgzYAAAA2wZsAAAAAAAAAAAAAAAAAAA="), 46, atob("DRYpFR0eHiImHygmDQ=="), 49+(scale<<8)+(1<<16)); +} + +Graphics.prototype.setFontSpecialElite = function(scale) { + // Actual height 40 (39 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAYAAAAAAAfwAAAAAAP/AAAAAAH/4AAAAAB/+AAAAAAf/gAAAAAH/4AAAAAB/+AAAAAAf/gAAAAAH/4AAAAAAv8AAAAAAN6AAAAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAfAAAAAAAPwAAAAAAP8AAAAAAH+AAAAAAH+AAAAAAD+AAAAAAD/AAAAAAD/AAAAAAB/AAAAAAB/AAAAAAB/AAAAAAB/gAAAAAB/gAAAAAB/gAAAAAA/gAAAAAB/wAAAAAA/4AAAAAA/wAAAAAA/4AAAAAA/4AAAAAAf8AAAAAAP8AAAAAAD8AAAAAAA8AAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//wAAAAP///gAAAH/9/+AAAD/gAf4AAB/AAB+AAA/AAAHwAAPAAAA+AADgAAAPgAAwAAAD4AAcAAAAfAAHAAAAHwABwAAAB8AA4AAAAfAAOAAAAHwABwAAAB8AAcAAAA/AAHgAAAPgAB+AAAH4AAPgAAD8AAD+AAD+AAA/4Af/AAAB////AAAAP///wAAAAP//gAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAOAAAAHAADgAAAD4AB4AAAA+AAeAAAAPgAHgAAAD4AB4AAAAeAAeAAAAHgAHgAAAB4AB4AAAAcAAeAAAAPAAH4AAP/wAB/////+AAf/////gAH/////4AB///+/+AAAAQAAPgAAAAAAB4AAAAAAAeAAAAAAAHgAAAAAAD4AAAAAAA+AAAAAAAPgAAAAAADwAAAAAAA+AAAAAAAPgAAAAAAB4AAAAAAAAAAAAAAAAAAAAAAAcAAAB+AAfwAAA/wAf/AAA/8Af/wAAf/AP/8AAGPwP//AADh8D48AAA4OB8OAAAOAAfDgAAHAAPg4AABwADwPAAAcAB8DwAAHAAeAeAABwAHAHgAAcADwB8AAHAB4APgAB4A+AB4AAPAfAAeAAD4fgADgAAf/4AA4AAD/8AAeAAAf+AAfAAAB8AAPwAAAAAAD4AAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/gAAAAAAf8AAB/wAH/wAAf8AB/8AAH+AAffgAB4AcDx4AAcAPAAfAAHAPwAHwABwHwAA8AAcB+AAPAAHA/gADwABw/4AA8AAcf+AAPAAHP/gAHwABz74AB8AAf8fAA/AAH8DwAPgAD/A8AHwAA/gHwP8AAPwA//+AADwAH//AAAAAA//gAAAAAD/wAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAAAAAP8AAAAAAD/AAAAAAD/wAAAAAD/8AAAAAB/PAAAAAA/jwAAAAAfg8AAAAAPwPAAAAAH4DwAAAAD4A8HAAAD8APBwAAB+ADw8AAA+AA8PAAA/AAPDgAAPgADw8AAHwAB8/AAD+B///wAA/////8AAP/////AAB+f///wAAAAAHx8AAAAAB8PAAAAAAPDwAAAAADw8AAAAAA4PAAAAAAODwAAAAADgcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAAAAAB/gAAH//wf8AAB//+H/gAAf//h/4AAHJ/wf/AABwD4D/4AAeA+AAeAAHgPAAHgAB4DwAB4AAeA4AAeAAHgOAAHgAA4DgAB4AAOA8AAeAADgPAAHgAB4D4ADwAAeAeAB4AAHAHwAeAABgAfAPgAAYAD8fgAAAAA//wAAAAAH/4AAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAAAAA//wAAAAB///AAAAB////AAAB/7//wAAA/AfB+AAAfAPAPwAAPgHgB+AAHwBwAPgAB4A8AB8AAeAPAAfAAPADwAHwADgA8AB8AA8APAAfAAPADwAHwADwA8AB8AA8AHgA+AAP8B4APgAD/wfAH4AA/8D4D8AAH/A///AAB/wH//gAAH8A//wAAA8AH/4AAAAAA/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAAAAB/4AAAAAA/8AAAAAAP+AAAAAAD+AAAAAAAeAAAAAAAHAAAAAAADwAAAAAAB8AAAAAAAfAAAAAAAHwAAA/8AD+AAB//AA/gAB//wAP4AB//gAB+AB//AAAfwB//AAAH8A/wAAAA/A/wAAAAHw/wAAAAB8/wAAAAAffwAAAAAP/wAAAAAD/4AAAAAA/4AAAAAAP8AAAAAAD4AAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAP/wAAAH8H/+AAAH/z//wAAD////+AAB///h/gAA/B/gH4AAPAP4A/AAHwB8AHwAB4APAB8AAeADgAfAAHgA4ADwABwAOAA8AAcADgAPAAHAA4ADwAB4AeAA8AAfAHwAPAADwB8AHgAA+A/gD4AAPgP4B+AAB+P/h/gAAP////wAAB/8f/4AAAP8D/8AAAAAAf8AAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAAAA/4APAAAA//gH4AAAP/8D/gAAP4Pg/8AADwB8P/AAB4AfD/4AAeAD4d+AAHAA+AfwADwAHgH8AA4AA8A/AAOAAPAPgADgADwD4AA8AA4B+AAPAAeAfAAB4AHgHgAAeADwD4AAHwA8A8AAA+AfA/AAAHp/h/gAAA3//+gAAAB//+gAAAAd//gAAAACf/wAAAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAABwB/AAAAB/A/8AAAA/wf/gAAAP+H/4AAAH/h/+AAAB/8f/gAAAP+H/4AAAD/h/+AAAAfwf/gAAAH8C/wAAAAAA3oAAAAAABwAAAAAAAAAAAAAAAAAAAA=="), 46, atob("ERwfHB0cHxsdHB4dEQ=="), 50+(scale<<8)+(1<<16)); +} + const SETTINGS_FILE = "pastel.json"; let settings = undefined; @@ -113,6 +123,10 @@ function draw() { g.setFontCabinSketch(); else if (settings.font == "Orbitron") g.setFontOrbitron(); + else if (settings.font == "Monoton") + g.setFontMonoton(); + else if (settings.font == "Elite") + g.setFontSpecialElite(); else g.setFontLato(); diff --git a/apps/pastel/pastel.settings.js b/apps/pastel/pastel.settings.js index 2e4afadc8..a8aadd58f 100644 --- a/apps/pastel/pastel.settings.js +++ b/apps/pastel/pastel.settings.js @@ -22,14 +22,14 @@ storage.write(SETTINGS_FILE, settings) } - var font_options = ["Lato","Architect","GochiHand","CabinSketch","Orbitron"]; + var font_options = ["Lato","Architect","GochiHand","CabinSketch","Orbitron","Monoton","Elite"]; E.showMenu({ '': { 'title': 'Pastel Clock' }, '< Back': back, 'Font': { value: 0 | font_options.indexOf(s.font), - min: 0, max: 4, + min: 0, max: 6, format: v => font_options[v], onchange: v => { s.font = font_options[v]; diff --git a/apps/toucher/ChangeLog b/apps/toucher/ChangeLog index 494110d55..7b5c53de7 100644 --- a/apps/toucher/ChangeLog +++ b/apps/toucher/ChangeLog @@ -3,4 +3,5 @@ 0.03: Close launcher when lcd turn off 0.04: Complete rewrite to add animation and loop ( issue #210 ) 0.05: Improve perf -0.06: Complete rewrite in 80x80, better perf, add settings \ No newline at end of file +0.06: Complete rewrite in 80x80, better perf, add settings +0.07: Added suppport for Bangle 2, added README file diff --git a/apps/toucher/README.md b/apps/toucher/README.md new file mode 100644 index 000000000..a327a654c --- /dev/null +++ b/apps/toucher/README.md @@ -0,0 +1,22 @@ +# Toucher - A touch based launcher, swipe left, switch right, tap to launch + +* Designed specifically for Bangle 1 and Bangle 2 + +## Installation +- Use the App loader to install toucher +- Then delete the existing launcher +- When you restart the new launcher will be loaded +- To return to the default launcher, delete toucher and install the default launcher. + +## Bangle 1 +In the settings menu 'Low Res' refers to setting the Bangle 1 screen into 80x80 mode. +This significantly improves the animation performance. + +## Bangle 2 +The Hires/Lowres settings is ignored. +Touch the top third of the screen to launch the selected app. +Press button 1 to launch the selected app. + +## Screenshots + +![](screenshot1.jpg) diff --git a/apps/toucher/app.js b/apps/toucher/app.js index 455a29c5d..b6c37f0d0 100644 --- a/apps/toucher/app.js +++ b/apps/toucher/app.js @@ -7,8 +7,11 @@ let settings = Storage.readJSON(filename,1) || { debug: false }; -if(!settings.highres) Bangle.setLCDMode("80x80"); -else Bangle.setLCDMode(); +// this means that setFont('6x8',1) is actually setFont('6x8',3) +if (process.env.HWVERSION == 1) { + if(!settings.highres) Bangle.setLCDMode("80x80"); + else Bangle.setLCDMode(); +} g.clear(); g.flip(); @@ -23,7 +26,7 @@ const ORIGINAL_ICON_SIZE = 48; const STATE = { settings_open: false, index: 0, - target: 240, + target: g.getWidth(), offset: 0 }; @@ -63,7 +66,7 @@ const APPS = getApps(); function noIcon(x, y, scale){ if(scale < 0.2) return; - g.setColor(scale, scale, scale); + g.setColor(g.theme.fg); g.setFontAlign(0,0); g.setFont('6x8',settings.highres ? 6:3); g.drawString('x_x', x+1.5, y); @@ -81,23 +84,24 @@ function render(){ g.clear(); const visibleApps = APPS.filter(app => app.x >= STATE.offset-HALF && app.x <= STATE.offset+WIDTH-HALF ); + let cycle = 0; + let lastCycle = visibleApps.length; + visibleApps.forEach(app => { - - const x = app.x+HALF-STATE.offset; - const y = HALF - (HALF*0.3); + cycle++; + const x = app.x + HALF - STATE.offset; + const y = HALF; let dist = HALF - x; if(dist < 0) dist *= -1; - const scale = 1 - (dist / HALF); if(!scale) return; if(app.special){ - const font = settings.highres ? '6x8' : '4x6'; - const fontSize = settings.highres ? 2 : 1; - g.setFont(font, fontSize); - g.setColor(scale,scale,scale); + const fontSize = (process.env.HWVERSION == 2) ? 4 : (settings.highres ? 6 : 2); + g.setFont('6x8', fontSize); + g.setColor(g.theme.fg); g.setFontAlign(0,0); g.drawString(app.name, HALF, HALF); return; @@ -111,26 +115,69 @@ function render(){ if(icon){ icons[app.name] = icon; try { - const rescale = settings.highres ? scale*ORIGINAL_ICON_SIZE : (scale*(ORIGINAL_ICON_SIZE/2)); - const imageScale = settings.highres ? scale*2 : scale; + let rescale; + let imageScale; + + if (process.env.HWVERSION == 1) { + // on a bangle 1 !highres means 80x80 + rescale = settings.highres ? scale*ORIGINAL_ICON_SIZE : (scale*(ORIGINAL_ICON_SIZE/2)); + imageScale = settings.highres ? scale*2 : scale; + } else { + // !highres mode is meaningless on a bangle 2 at present + rescale = 1.25*scale*ORIGINAL_ICON_SIZE; + imageScale = 2.5*scale; + } + g.drawImage(icon, x-rescale, y-rescale, { scale: imageScale }); - } catch(e){ + } catch(e) { noIcon(x, y, scale); } - }else{ + } else { noIcon(x, y, scale); } //draw text - g.setColor(scale,scale,scale); - if(scale > 0.1){ - const font = settings.highres ? '6x8': '4x6'; - const fontSize = settings.highres ? 2 : 1; - g.setFont(font, fontSize); - g.setFontAlign(0,0); - g.drawString(app.name, HALF, HEIGHT/4*3); - } + g.setColor(g.theme.fg); + if (cycle == 2 && scale > 0.1) { + const fontSize = (process.env.HWVERSION == 2) ? 2 : 1; + if (process.env.HWVERSION == 1) { + fontSize = (settings.highres) ? 3 : 1; + } + + if (app.name.length <= 12) { + g.setFont("6x8", fontSize); + g.setFontAlign(0,1); + g.drawString(app.name, HALF, HEIGHT); + } else { + // some app names are too long for one line + var name = app.name; + var first = name.substring(0, name.indexOf(" ")); + var last = name.substring(name.indexOf(" ") + 1, name.length); + + // all this to handle long names like + // Simple 7 Segment Clock + if (last.length > 12 && process.env.HWVERSION == 1) { + g.setFont((settings.highres ? "6x8" : "4x6"),(settings.highres ? 2 : 1) ); + } else { + g.setFont("6x8", fontSize); + } + + g.setFontAlign(0,-1); + g.drawString(first, HALF, 0); + + if (last.length > 12 && process.env.HWVERSION == 1) { + g.setFont((settings.highres ? "6x8" : "4x6"),(settings.highres ? 2 : 1) ); + } else { + g.setFont("6x8", fontSize); + } + + g.setFontAlign(0,1); + g.drawString(last, HALF, HEIGHT); + } + } + + /* if(settings.highres){ const type = app.type ? app.type : 'App'; const version = app.version ? app.version : '0.00'; @@ -138,18 +185,21 @@ function render(){ g.setFontAlign(0,1); g.setFont('6x8', 1.5); g.setColor(scale,scale,scale); - g.drawString(info, HALF, 215, { scale: scale }); + g.drawString(info, HALF, HEIGHT/8*7, { scale: scale }); } + */ }); const duration = Math.floor(Date.now()-start); if(settings.debug){ g.setFontAlign(0,1); - g.setColor(0, 1, 0); - const fontSize = settings.highres ? 2 : 1; - g.setFont('4x6',fontSize); - g.drawString('Render: '+duration+'ms', HALF, HEIGHT); + g.setColor(g.theme.fgH); + const fontSize = (process.env.HWVERSION == 2) ? 2 : (settings.highres ? 2 : 1); + g.setFont(((process.env.HWVERSION == 2) ? '6x8' : (settings.highres ? '6x8' :'4x6')), fontSize); + // steal the bottom line, and print the duration + g.clearRect(0, HEIGHT - (process.env.HWVERSION == 1 && !settings.highres ? 8 : 24), WIDTH, HEIGHT); + g.drawString('Render: '+duration+' ms', HALF, HEIGHT); } g.flip(); if(STATE.offset == STATE.target) return; @@ -202,7 +252,7 @@ function run(){ E.showMessage("App Source\nNot found"); setTimeout(render, 2000); } else { - Bangle.setLCDMode(); + if (process.env.HWVERSION == 1) Bangle.setLCDMode(); g.clear(); g.flip(); E.showMessage("Loading..."); @@ -211,10 +261,11 @@ function run(){ } -// Screen event -Bangle.on('touch', function(button){ - if(STATE.settings_open) return; - switch(button){ +if (process.env.HWVERSION == 1) { + // Screen event + Bangle.on('touch', function(button){ + if(STATE.settings_open) return; + switch(button){ case 1: prev(); break; @@ -224,8 +275,17 @@ Bangle.on('touch', function(button){ case 3: run(); break; - } -}); + } + }); +} + +if (process.env.HWVERSION == 2) { + // tap at top 1/3 of screen to launch app + Bangle.on('touch', function(button, xy) { + if (xy.y < HEIGHT / 3) + run(); + }); +} Bangle.on('swipe', dir => { if(STATE.settings_open) return; @@ -238,9 +298,12 @@ Bangle.on('lcdPower', on => { if(!on) return load(); }); +if (process.env.HWVERSION == 1) { + setWatch(prev, BTN1, { repeat: true }); + setWatch(next, BTN3, { repeat: true }); + setWatch(run, BTN2, { repeat:true }); +} else { + setWatch(run, BTN1, { repeat:true }); +} -setWatch(prev, BTN1, { repeat: true }); -setWatch(next, BTN3, { repeat: true }); -setWatch(run, BTN2, { repeat:true }); - -jumpTo(1); \ No newline at end of file +jumpTo(1); diff --git a/apps/toucher/screenshot1.jpg b/apps/toucher/screenshot1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..698121cbe9790999983c97c5d1503c749c65f28e GIT binary patch literal 21329 zcmeIZ1#leAmL}R_w3u14n3C2nYZG0u;deHYlZ(h={(TvVypj ztk~a9fMNlF2PhH%U~S{%pe!Lwq^YG%^pW=Ohk=o!-M{Pq;1^i#pT&>T0f0HWe{lXk zOM)>raWn#Ex&(fl9Dp|m8fy&H(aio$cl*!{|4onl&>d8jMSyv7fjXtx|E3%MZ@R0K zof9z6@JD_lJBJT_6{z!Ce{=r0*T?Z;F}#V5nhNk&6ZpXcI0BRb5&&VK{$G0hM|;}l z0|1@M=B}{|P{b2Gjy-!9b7!pvWL#$RO|i0DNHgfr5P${_iaSfQEsB zg@b?u0|%bw2f8yDBm@XJBn$)q>?02(6goHrG#Umb01O5d3mXKKLJ}E;ijCcjjGU5{ z!^9#u1s3NsDJPefa|rNy9ALR0rT?$O0RSjySQtnM;5jyA000~U6dVi+9GK-J2LvP< zIshCB6$1MA$1^pL(JUwtzZ!Z=jOW5$Hvfn+j}ns%)zK4$7$==ZH8D1h$NXX zBZ3T(ej;zJ0>VMR3Flq{x+1aS{J(@dG>u5&eo<(1y%8|-%Ge}i-07(K0 z2@4OHyp+Nz8aHSVW_Ii_WS&1XhWpt@BF7vGe<(k3h|3x7Z*tUYd{xS;I4Oq%2f~;- z;RG3XBk|>ICfo9xo_QBwl8G$Q8RX5? z*0u5?u(l(c(32krsXL^2S26mp*J)|L1JsAHQt10m#haxIyBoqo?Tc3|${SLUt>rnD zuJpfS|4Pe@G(A4up$&_nJITSY|FX53`(``a@v4q5njzyfEqvnApSvG}$%f_J7zy<` zL}SQ8{M43fZS~p(bxo(E!TpBA>JF=wnxNI{6GB!{)X1iN(XR+9dk$6VhQ#(ei$ILK z@X@8GAA~nHznJp2P_PsIT&%Y-7$9Ii5G|aG#W!-Ic9~#2% z5%!>Nyps-&YmZ4+bc+2kb$*aRvAVUE_Ei;r<-+6c;*sVsa-TduNT|&|UfausQ;$Fum6 zZdtk4ucH!;=Bcqh=t6Gx8N02WbBx4j%;R7nQ=`R|QXu2DMnEk@iF|gA6{&5lj*_cj zU_u<<`ZLJz*22|_QakRXt1E9-;Jx|R7n2CKi?lwNMFkmiTG6JNsINUN(x{pDMY-*prWPgBH)igeC~+Eg4TNun;5=YNBVO zeyuyUx9*-&v^Be%-t5~f9Wyzo@;NNx;Pb%YCj8uysl!m-wkcIJqjEi-gQhz{PpY~5 z<`?F0%HMD0R4(((SsH?4U7TLQWsfnx6GVu9UzZh@HauukJ;^+rdcEFyWrlu^KZ>~j zN;9=!FfY~EEC){C{7o9c{K`=&L`U+c1E;g6OQOx-P1f2Jg#q6}`xr+Ki%YjsM10;! za_#idFU{3#C>*`e`V>@W;R-I9ZuL|lTg}QUp9*7mnG}ORpLL3q|N0m?`r=)IkS|x% zW=`zfZm8%e5s@Cry&?`4*H^LASm45ud4BHB19M)ruGR6F(exCln}n#_6dWSoJGgtv zIeRLW*pg9>t~ILn)YuE>F<@f#szYR`+m2X=vql~NHc3r9m|;;|KB+6##JMFg;B{(d zXzIX}QPB`tPtMz1?Wr~JJ;Wj4v0M7)PSY91nr==AuIe{RKsvAPyusouBVIJVK7J8y zUB`i|r%Xc zQlPW0^H>m9<;_f{q?pb1`LxVV(bLq8p&wH;n~VgPQFSvBnc--!Z@aC-2xN$e$=!E4 zEWww`Ti%@2NbuIY_}~dwr2@ZtJ4>u380qgNbOuLmB-R;2febwH!JO}Rk~-Dyh;XA? zc5b&lEE*SGYf?nLMzQtes-XIS^l6g0Y+Kug_?`-_ikii48>_tK1+G8q9QzK12HbNM zNuON#{jWiZYBssSq--^7f(jHVJoGt{)pE##pmNylHYpst!&CVqwsf}ISW!WB7iE)p|UC>}u;ysC0fn-o9> z`DBz>c-th%B%9h~$sal3ymJ7$p6pIj9ugmmJj~f6w;v!cHlo5Bop_Y)rl9O0I*Mh6 zK0TL%JOf%bFhjtU1qRs-oq1lmrwoyKRW^k02wi0wm%1jzs*R6ylgm0^EnwjcY6n`Yk4)_9Q$rrE=r59=|D5)Yn1 zkha7E7`c*y9=@em~Bz<-x5iTDPGjA8OMEHybIN$qJwK_70qEFr2)LkN{*7IHT}MeTFQ% zHJ@cu9UPHUyUxWqu~1kc-WGC1%x5xSTgf^673M%3L`675A8i5QfI3aLt{ab^mn_lP z)22QwrBhEB!MYe&Pv?^QNUTMkc-Jajj@LWTX;VcRaZKef(o)l6+N{1W9D{xLlAd?( zytIOfI}=vj6r3pnV)5L1?1)pb;aX#vB8+ER z&x#ID{P%*K&zg}ybWEEq4MTM~{k@sGQe`AQ$h?A2$a@=&(m}_O2Gh7k_IFl`Z&i5G zGWB$tvvXI}Xt8E-`P_(;dFH}82e?JC^`Lw;=DoI9aE97NU1W@|WkwVYZ}|$JI%zy7 zO>s!8>Zd66J2kGFiB7h2<*zC1rN-VJGWg3p8% zHF^Ns+)hIdIzeXj3q~nTkY$C-xFv3W)_tbq&FI>(BP!cc*@kWbWszlDXT-gR4G zY|!-3EfWpZsKcUXR{rTl@+A9rOp?<09l|!|(O#}eapl3~Gya`vJjsfzg z)lCg?3l^t$-f|P=kXTeZJ29zzbw50a4$;aD6Xj0!HL1xHoe#aGuLt=ZAkt5yhf`aN z*fiE#>I1E~h*6*cND+c1nZGTpQa@l-r857n^Rp$T-0ZZfVzcb9YLEar=81q9`{h5c z8Iqs4Qi+xT`0VUM`<^olFXCZ>sbSiwT0KWdN<%uE-AtthbeQIv#!GHirxWZca`4hAYM{?b&V{IQi1C~@e}zhFpEDS=s%+@E?_7Em zmN@H|c71S3E~>m3Zi5|oRNhXhm67(Yd0FUQu5o+^G`qS^yaQq#=r`Xk??dj;rkbnY z0bjRX$1ncV$nq5wb!00VM|&u(6g;fkXENEZ$dCITw-&L>U|2=tv9L&dR$VZ+eR=PM$n-tiWB>qsK}j$6)WKom-7wUiF)))F#|@-F|9{#D5e`N{PnAWvRL_?Pj=klp;c)m;|fFaNztQ3J*#5cDo z-@T;@^5i5+qE?PiF>IE#%;6o7OnBSwr)2K28lkt<^A30pP_7Q#G2R3Vl=#Mk&IIx* z04?eReKc>+Yo55YMqXwW-!+B&3qOCUh0*V_@UzGQ!#A5eg-ctkQhsDNiynDuA%#D+ zd4T9F3Dm(bIj>pE$f^plU@cFgMRq0vlmoD(kP=olipG!)~J z+OXb&$xOK9wWksq^|G#)2d50Tku|gfK`G6Bf`@{-n&TOKcc_!H8l;Ai5KHF1@2C81!TU2NY36^r)E6U-1tOhY3=-S>0@d~!_cUjz`Z-Ghe#19Q} z<}wS?XH3_^^>S1v4oRw9K@lEn+De%7%6kd+`gRjGRpUVfEGLg_BIhSHjTGsPhE`Pu zg*W9-Yh}h#Mdy6BoavxVYVD@HmU=uP?n44N-sc{fgXQ;YCo4tMA=s5s5dR206g7_` z-yPJ6r34+B-UL74+rkP_uupy!`EOL=(3KbC42l=NpBjB$!YSU7o}&H{qZURQ4SSS#t_J4Vy8vOY zM;gWHEaIfnHRb|v*Xd-(Gi@8=nfkuwlSt~lDq7+bVqvL0`4W*^sh>no^&PyibdaU`f@dtr$wYB3Na5z=dIryeB`dswRHvwA)dn zq$G*0gt$!sZqPyT5LuwiN>92+F^gpEV%>3u-RP$@^717998MR4)Ej*f(4!_kSS)_| zxoI?=Zj$wUIN0Gsy7?UjjSOU+3~9m zJAD}io<6%NY3mFHvPtJp&6O4G#{KA2J!|`kb>z!MuJ3_DAjZXQ zRjHgKf{i604L6B@|8^qH)#+$b@y2JY26MX9s@cP|H*QyL@F3sZns$P>qnysDN{0E% zj?$^uSSM==E2h$Ch&)`~YJrf;J7fd(dpJg;_|&FOD(a}UDiqi!@1V`HgYE`%3j{ho zvX;G}5DxMC_%CK|T~W*$?T18Mb6XJYuQZmZx_uexzU1P23ay9{g13JlZ{nkUNRDJ}Eg2^}uv$R;4>C40=pmuOkc9XTa5-ySdK5pQr6lsiXh~gP%pVSLFS`6UL?DThG)Kulv@AR+q(-aG+KdNY| zYn>^X%(6xhCra~!F*=}k(YG6;UlyFAv>E^I>R&rL1wWa9D}3TJqCk)Ck*vmagDyxR z4dD;1a;1FexgUGQI@3!^#A!rrekctkgLxa{NP-d|gp*Fdj}z~}LR<`bHJwD$52FEM zxlA6RpqE; zz9z6m01zG5SfNU_pPVM%kwl|~oAPF4^zzTG86FjlLnE*wtR+>WYKr?9bSKUhqWVfQ z$#Mf;eQa&b%xG>?HMMlEt)%X$uO(&lCgqL?KKRP-eDdB<3$3+}Aio zj`x~yP*46U@L)yTeqSlT(%g8ZJ@LL8>52Bh9ifLq22CCO{e#&NRZP1dv* zu~HmqwM?)v8|5GsE&0)IC+cmUZ&=o+5oNZmk8I3-GSTmA){inX zn5V<%&U>+8B)rBJd67wd5g{YI^k3Hmy?C?VhB6cHA8K@I9;aGWFZx2Qey#{Rd zzFxF>O>(wGo~He96nnv9qOi7BgTEl>04GtLbk3~Wjc&uU0FOS%-LlVt-kl(p!@ZAc z!}WPltz##{cs~H|C0mBi^y6GlXJH;X$6G;NDE*-9FY{PT}=^8B~$}egy7pjaJ zSjRi5tLkrZ7@jAoaxJ?tTIx5^)(Nf~Y1w~zO1p!IbU70P4^LS!*@SACWELj-?=A70 zG7&UBr?j00wP^FOXk{*&f+PO?oJul}jrs$&otaD)bZs95uJ6)0gOm$iHa7a#*Fz%< zcZL1lf*UZUaT73iyBvC4dIc25Bg>Qkxdzmygd51^uX0@2XF{#%A;nCEOeKm3J$I~w zq~Jl3hP}c*FQYB?6-i$b9cjL_=Ir@~Ne;)G`gd&2e-r$6LZp|P!lZDNTEt5Ruk8$J zq#~iCAe@6$JQxUBJpKiun&2}-=!0LWpyy0UsYZ<&MyI+Z%S1Mm|30CpVXsw_z)T&= zt_ZBMK)xQ{EbJ~tu1-fQDUS$kj75M`Rcw5-u>gie6^ymlUx)G3OZ%6!`=k!k?%I`y zfsm5Nx;-nz2c+aS-{y*N6Yb6Vx_ZYIrFPN2)FhLKz@mi%`}gsoV5I-=MTp+!jghr} zY=*du@io&Q1QwUQv7e3>)|sniuvg9atr107H78naRxz2ATY*YM(`d8q*SE{kRNci} zNDr{7=Z({9?^j>7d@SLz&UW2xKvZU>#_J{3W2bW6-@Jczg%8-~Ei}b}z-K-NAUN6k z@yy5e0ZvYGJ?`1uafPLy%wJS1C0Z;h^sqK|(Ld@5O9~$vJz*s!?r~Z1%g?yDj+x=| zMZ~E}+519lUpmo(g({WK2d%i6Xn(4#5EM;-Ui=z1%T7e7FDD8aR~wDuKmwkJCqDF+ z8d==I+0gW2UoY^mK4TcrBVYD^NnV%G&~pCLoMQ!rkUpt`-WdF zfv|r8K&Yq^20>#L=riiw&>6w}X`duLxm>sl4K;W4L&>&8JQI3;Ehk65bzlJ1D5>

Wm?3!Mt<_!7vupX1HX?3>?LHW#^ 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 OaCrVtk_Ynp^8WyThLmdn literal 0 HcmV?d00001