From 7ab3fe2f37de68b802dcab074b3e00e4cfa1b45c Mon Sep 17 00:00:00 2001 From: Paul Spenke Date: Fri, 5 Jan 2024 12:15:31 +0100 Subject: [PATCH 1/6] Add new Line Clock application This commit introduces the Line Clock application. The Line Clock is a readable analog clock that is customizable via the theme configuration. It includes a JavaScript logic file, an app icon, a metadata JSON file, a README, and a ChangeLog file. This also includes the MIT license file. --- apps/line_clock/ChangeLog | 1 + apps/line_clock/LICENSE | 21 +++ apps/line_clock/README.md | 11 ++ apps/line_clock/app-icon.js | 1 + apps/line_clock/app-icon.png | Bin 0 -> 3511 bytes apps/line_clock/app-screenshot.png | Bin 0 -> 2653 bytes apps/line_clock/app.js | 273 +++++++++++++++++++++++++++++ apps/line_clock/metadata.json | 17 ++ 8 files changed, 324 insertions(+) create mode 100644 apps/line_clock/ChangeLog create mode 100644 apps/line_clock/LICENSE create mode 100644 apps/line_clock/README.md create mode 100644 apps/line_clock/app-icon.js create mode 100644 apps/line_clock/app-icon.png create mode 100644 apps/line_clock/app-screenshot.png create mode 100644 apps/line_clock/app.js create mode 100644 apps/line_clock/metadata.json diff --git a/apps/line_clock/ChangeLog b/apps/line_clock/ChangeLog new file mode 100644 index 000000000..0f7cf828d --- /dev/null +++ b/apps/line_clock/ChangeLog @@ -0,0 +1 @@ +0.1 init app diff --git a/apps/line_clock/LICENSE b/apps/line_clock/LICENSE new file mode 100644 index 000000000..404cbc7a0 --- /dev/null +++ b/apps/line_clock/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Paul Spenke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/apps/line_clock/README.md b/apps/line_clock/README.md new file mode 100644 index 000000000..5789acbbc --- /dev/null +++ b/apps/line_clock/README.md @@ -0,0 +1,11 @@ +# Line Clock + +This app displays a simple, different looking, analog clock. It considers the +currently configured "theme" (and may therefore look different than shown in +the screenshot on your watch depending on which theme you prefer). + +![](app-screenshot.png) + +## License + +[MIT License](LICENSE) diff --git a/apps/line_clock/app-icon.js b/apps/line_clock/app-icon.js new file mode 100644 index 000000000..eaaf719b4 --- /dev/null +++ b/apps/line_clock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgYMJh/4AgUD+AeKgIRDj/+n41O/4RQABcfIJYAEKZgAkL4U/8ARNBwIRP/+AGx6YBPSH/4ASPh/A/hfDAAZAHg/8gP/LguSoARHEwIRFiVJkDCFjgRHgEJkg4CcwQjIAAMEHAUDCoIRB46kIHAkH//xLIw4I8eAnCNKHAYAO/xxEABg4ByASPHAkBKAbUE/5xGhP//wRFv4RDOIYIB//ACQr1FHAIRJAA0TCAP/ZwIALgYRJVowRCj/4BIkBLIgABgRHC/KqFaI4RC5MkJBlPR4UECJizJJwoAKCKImVQAwAJv0HL5S6CbwIjLCKMAn4RDh0/LMKMhWaYAKA=")) diff --git a/apps/line_clock/app-icon.png b/apps/line_clock/app-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2753538122d298ede31a6526c23ac519dee6d1e7 GIT binary patch literal 3511 zcmY*c2Uru!7Tyq~_aYr)lqw_?X(2R0=|~r)8IWcSp+pEEokw{nO+Y}3f=KVZNfS_{ zs8s1y6zNDue9OH)?|ZY~>^XDhKmVCCJ3BiYX`rt`OT|eA006C)rn(U*#m_1Q8F;@* zau^N@Qb$!iRRAcDp+3Q!1KTh=O(Q)3@DTujz)%1<0!@Km0pJ1XxN-*oP{{zm=9<=E zhz2`C?aj3u^z;A`P^SRSL6`t2s6oIBfN%n5Y@h~cL%9CvMi8Oj7!m*ocLqp*V{U`; ztZ0Ju%;#?jeGd7D@j1yKwD@!AKl+)Q5G{lr6qK%-w>$uVn)$3kfYda0knNVUi8;Ys zPZwo}$00Cx@wWB|BF^>93qTW5po+66U|>YteHRZDQ4#(Z0tM=4W+WW;7leRSgq!Ob zz|`>W_AnWQI6@q*LGQaOb~h2gOossBmZ!NuIMu>>V~_sJsA0nUr7S}7xMpXzvG~hXTkqxFn?$I zmlaG^i3*MUGi^##9M*H>;B3ojsjHeeovXg>d;hV;`I&-Zufp+9g2SFB*J5EzkqW%3 zl9ut5%mN`CDNY9+ml@w!?w*JHP?GIxi@)O;mGXJ~?6T#&J1w*7is^>eaQ0B;uyo4| z$}!-z@p9GjkDA6?jxD3s*tO~rYu^CrF7|x9rl#fx=~ucba6YAn46m{^V(wW)ofo?V zhqohX#Vl$F;~P_rf)lm)QJ>KgE9p!HFT~D~BTQ6O7v;5H6s4bfMT?`(b1iiwJ1gr% zl7Ww}^rvyIexg;Q=euXJ_)rfS{Isaw@m}I%F4>-XkL8t2NG%~dJ3BG&-4nsfj4alL zX2n&-1+a-~Z0=g&&C;ahfz0{NehknyaM4XtkR(` zUdiuBbMTcOPcW1bpHfaU;S<<&Y9e&;qFUrsg?&^(-_}BR^>nd?YAd4wykZ}NQcBXS$@&GDpPE7Wf4K^*yG*rqkRkAF|;*S-v=@j zrSLPahbvm@SIgGy?d{2qO6_n8#}P4DESLX@cAHIOqOQApg*l~18qP80`gc5HBG@D< zaOdYNZ935<``XZJKi_hfcwExK^~ap=>f9DWj|TRB{2-KPboLc>?r?3-a?HYqG`{FO zMVRh8u=V%$CdlB%DL8Dornm>=E^1V*Pm3w!MuV_2Yr8iQjN9J^1^GAIJESsWsp#_~R_~cizKt0|fx-FzN_P;tNUoipnZ=#&iB#`O;l`(6Y^r3IkOao5fdM`B3~ruKmR6jd+{B!pn=^) zllRWu?<2)MdDSn#hyVWc=dt}%!-MD_h3oejLVdsRcEII<{m{LJXI1~Eyoo@&%FEAmvzVV=t%j}Mt;&!){gY&9(kjxI-X3>T=WXr!z?Iya zEMcdM!Mu1kFd!>_7wXLU=BLA08RiR^7ny2$P}SO%ovj58u@FWc@>l7v4X8P(AMf@b zacwIDWIzMSb!b0{KTt&41c<9P>+-`SMS2ooB|!u|PfwY~D{(Nc7L{7*67OH9&3h6` z!RgqPUP%cT+u$G4^h<)=)7>i9uHZV6LC%O-Z0k)xGJ#qSnC(9y`9S*ZRaTkbpg?hk z@<6lHtAlsUgGKWDds2q3g|{6UMkgmm8@=$%930NPN{hT)nO2{|U;#pO|1w|vp&oG| zy@n-W2cQR>65Lx^LtC+Nj_spd?8WH=XjUKYsiyiGR#w*h=t1-R@8R@(BYWWMPet2U zQDL;VHj#_NP1NkREp*+oO7ZQAR1zksRtIGFk_wk^2r>IWnX^?t#fD|hEpks% z4v^3yRrjmwg(A}&#RfC( zcCBYbZdskuNn925uC1Llt$R6Em&5pSBHLKdO6Y=u1x>I5LWzQA zUG0=Tkn9kUqfMrFr6ykyt`bY$UG`*n8ynWkiPtRgaI(uYrk<3uTngmz7t~D_pNrZf z!fsrDxOi1$@S`UgppoAjD@>H&fV#%KS6AeSZS!1Z@(QHO0+xb{L_bGLS~jw;nx)Ea zRyHnmE<}BJJekD7TZVS*=cXN--COKUk*cumq-u69kMZd%7Pyd5l0Lz?gom&}GJ&rK zF<~CpJ^`NGk-w-{1|0fX>WPMnOFHzE4g5=ohdnGsR^tKQRu3+?T_hx~iO~oaCnP0_ zFz-1IEsN1^qw*5!{lm&h~YZv<@ zMPZ(CAC0S9SaYv4Ik11@TDReR$1%Xi-7Xvo(74 zrnTC7Q;G3MIH|hTS;Es=Z*T3diS1Wu+qUj!?SHGrj^1muPSMXuxRpljFg$A*=2avQ z389lNA^Z|7r2YAKy%S%u$35qs7-9j^;gWc87gR}fG z*=WjeemJCyTY%S%Ia*&YGiNU8QKsZBw^S%*6WqV-XIq1AFYm^!y#NMS(++GmCqHp` z=kK#-XEj+y^C}2DMcRx!eOyA(Q98$CGFaNu*Wo-(KBE&tMmasrx{({hckV*1(n`|ow(*y0+FSKTYfCai>o&>9zLLy6!RtIi zLPD{s<_SC4N~ot*1_Yhw04qH?^`(a%bgG5p8wgtdt;uMoHa|HgQPBZ_Q*CxzPM>k;-P zGH)h~P3eW|7M1PNe*uWu^3|*Q(P?i+lLLqpiRz&%gzohaCM=mFRK_~jVqr918atA= zxEA%yK3GBBVvc{>A70@XG*Y2k#V__K#Bzp#Kv&0dl1%sBr`K_$Pwjn^z;Q?3bRVNu3dP>i&w(N%_~EBcPORX%*tar*^i zE!dy~UD2tUs#2!Sw1M)`X-}k=L#G+HH^uH$2O(*7n;wC(F_>IT%I}C!>GTmE;$;+q zj0|J*er+(T`W_Zmu$z99t?)~C_XQtwxX$c6Z^xb#yyEn(} z54WAC8`0Rt07_P)Uq9tUeH+rcm>7sP5=%ZkH%9`5c5`OUujBKpT=If4y5xJ_~G1&k$aDD4>xdO$8EKC`J$z3u>gz9|Z*I9TXWlC@mBP z4C1fAFh~UHsE8p{C7}udMY+tqkN4$1oU_+CYp-?I-uvamIoRQaFjx!#K*;KprPD6b z{wY4*-Co-??YRqx>rQxcP}3{>1pthcmF4lX6i?10>a{5&z7rpJcIFoi6X|w7ZqPB_ zt&j=E!}r#F9!dNs>wf%PUteGAv{yq%Mt)G*`t{3hrlBL38?nCVUDs6c&e?_~=j$$! za;#N-On_QBDC7%FoH#szR*JkN-7Cnm$sQ@k+*S6aQ_mDj&bbS))Ckhhl(bdwmY@%? zQ!tZt7hmorIX-!2rbAq4^GYd~((;JS%4>;yDMTJ&2*52lR&#HQcXFFW1mQ0!uapvz zpvp16uE`lnZ+5%)^4Bb)IZ`nA1q!s?*jxyfhqMwVC*Io4F20U-lG7A|rB0lWNq-t& z5=M}OwC*Fp4?Ypt%;-rqpb_go@dI{o@dpg3R6&sxy2GmgEjh`Lq#$?NdEPw7Z|Y!; zmw~#UBP5uoBDU%61fbLPI)~zs;Qt-v>{(Y{6W+xf1viHtPI=>XqRYzAoA4*2!XOB`z2BDSZR#MD|jqW&xbQjjZ!*?$oib zTMh3R$;n6!O7=M%WX0y(t|7EvnDeb}1>2(Q+>G^=KO%!LvcvSHof@i*?kK(Y87Gom zB?8^5W!0HwdU5y+_@lxejxy-`JCvbOhI@Y1@%^q!p?x&0Xj9F_xqvQ_G!;J?9r)w$ zA+28DI?(7M@A_(>cQ8prDKMo!TQh2=CmL2y&X7>&m~bdt!mEkf{>21E&n7g3!`NQ6 z+R!*-D^PMX+)RB&{?P_iL)(SplhC|Xcc=7Gxtvy)%I8xn$79g5YPnlgT~7jTJbfLA zwlTIhZkxF^`#ByF*>c!`eQLuyK%1?NhU6?;|Bm8kc8;#o+S76yGG##c-U#8I2Z#wb zH`Mimv4}BhNxW?{vXx9;@T^hO17p~_g}D~gxZ7c`8&h~GR;aXwd=%1Mf*hZcc64MB zx|x5owS!yb8-o}ZSUWcpeSuj;3YbmY{B32ZWOPIY^o?|;@E%98=%>5K>96SiAu_Pu z4ILuQ3b9kUb1NyQ?=r5B9VXx5&(-k>SA!~V>YN1I?`H9X6+@;gI>=|S`U8l6jt_TI zR^0eMgpvB{%fwml^_C2JpZ6HCbj8NlSFe2&DiE(PzGTBRCR*saDBj9ddaSpcdS5aJ zZ{Z#Tv68ZQ#)#ygzrm8l9HwQm#JeTC)5b4mf0%aM;c5g z+?B||GLuKLmSu1xd0X$UYg{B{?-P{I-V+A>cUgA`g-9+hxe7~&&MT#@QYy>}B-MW)xt?S79>qTW`P`V&nf)mGaO}gjy{>IOrKaQtLGUa2t;e8fijrvxfxi5mo zUO&I!;`Fbj?}NF~2x&;9`TI|jSHmIjSu~@{?ecl1sVl-T5Enc@Dg)z7!GG6T$Z%JS zBc7rM+TyOyTRNaFl&Zhe0>a`_gDaTEi_8YiyC1E_pYwUdZbE&}?nuFDOIf%ce(KQ8~xbiPMlJk+I z=c3O9=IYhMmvJZ8=sgcFUDm57=bt`AE76K+~^K5g=fB1B--(lvI{$4*D+~b$qOif|J0~dfDS>2^=;C zsSWniy7kZy!cZiU*B(eiLSxgp$X&|yeMjWkqEL0jnPd)r9A{;;S5_;`(muFdj`^PX zX+hoJFR8fzx6o%cBFCJ7xEOhK!usok)pD0|!YmyXB-D7Xpr7WtA<0RbH=>O78)hb~rJX>hd4;&U~uT(iDlJo5E<)T_}9% zl_K$-I1m<-Z15EaOdX>J>l7rA{Y{f43~mRvZ2-~AVX)d@Sx8gtT}e*^3R)A|4a literal 0 HcmV?d00001 diff --git a/apps/line_clock/app.js b/apps/line_clock/app.js new file mode 100644 index 000000000..0596b865e --- /dev/null +++ b/apps/line_clock/app.js @@ -0,0 +1,273 @@ +const handWidth = 6; +const hourRadius = 4; +const hourWidth = 8; +const hourLength = 40; +const hourSLength = 20; +const radius = 220; +const lineOffset = 115; +const hourOffset = 32; +const numberOffset = 85; +const numberSize = 22; + +let settings = { + showLock: true +}; + +let gWidth = g.getWidth(), gCenterX = gWidth/2; +let gHeight = g.getHeight(), gCenterY = gHeight/2; + +let currentTime = new Date(); +let currentHour = currentTime.getHours(); +let currentMinute = currentTime.getMinutes(); + +let drawTimeout; + +function imgLock() { + return { + width : 16, height : 16, bpp : 1, + transparent : 0, + buffer : E.toArrayBuffer(atob("A8AH4A5wDDAYGBgYP/w//D/8Pnw+fD58Pnw//D/8P/w=")) + }; +} + +/** + * Retrieves the angle of the hour hand for the current time. + * + * @returns {number} The angle of the hour hand in degrees. + */ +function getHourHandAngle() { + let hourHandAngle = 30 * currentHour; + hourHandAngle += 0.5 * currentMinute; + return hourHandAngle; +} + +let hourAngle = getHourHandAngle(); + +/** + * Converts degrees to radians. + * + * @param {number} degrees - The degrees to be converted to radians. + * @return {number} - The equivalent value in radians. + */ +function degreesToRadians(degrees) { + return degrees * (Math.PI / 180); +} + +/** + * Rotates an array of points around a given angle and radius. + * + * @param {Array} points - The array of points to be rotated. + * @param {number} angle - The angle in degrees to rotate the points. + * @param {number} rad - The radius to offset the rotation. + * @returns {Array} - The array of rotated points. + */ +function rotatePoints(points, angle, rad) { + const ang = degreesToRadians(angle); + const hAng = degreesToRadians(hourAngle); + const rotatedPoints = []; + points.map(function(point) { + return { + x: point.x * Math.cos(ang) - point.y * Math.sin(ang), + y: point.x * Math.sin(ang) + point.y * Math.cos(ang) + }; + }).forEach(function(point) { + rotatedPoints.push(point.x + gCenterX - (rad * Math.sin(hAng))); + rotatedPoints.push(point.y + gCenterY + (rad * Math.cos(hAng))); + }); + return rotatedPoints; +} + +/** + * Draws a hand on the canvas. + * + * @function drawHand + * + * @returns {void} + */ +function drawHand() { + g.setColor(0xF800); + const halfWidth = handWidth / 2; + + const points = [{ + x: -halfWidth, + y: -gHeight + }, { + x: halfWidth, + y: -gHeight + }, { + x: halfWidth, + y: gHeight + }, { + x: -halfWidth, + y: gHeight + }]; + + g.fillPolyAA(rotatePoints(points, hourAngle, 0)); +} + +/** + * Retrieves the hour coordinates for a given small flag. + * @param {boolean} small - Determines if the flag is small. + * @returns {Array} - An array of hour coordinates. + */ +function getHourCoordinates(small) { + const dist = small ? (hourSLength - hourLength) : 0; + const halfWidth = hourWidth / 2; + const gh = gHeight + lineOffset; + return [{ + x: -halfWidth, + y: -gh - dist + }, { + x: halfWidth, + y: -gh - dist + }, { + x: halfWidth, + y: -gh + hourLength + }, { + x: -halfWidth, + y: -gh + hourLength + }]; +} + +/** + * Assign the given time to the hour dot on the clock face. + * + * @param {number} a - The time value to assign to the hour dot. + * @return {void} + */ +function hourDot(a) { + const h = gHeight + lineOffset; + const rotatedPoints = rotatePoints( + [{ + x: 0, + y: -h + hourLength - (hourRadius / 2) + }], a, radius + ); + g.fillCircle(rotatedPoints[0], rotatedPoints[1], hourRadius); +} + +/** + * Convert an hour into a number and display it on the clock face. + * + * @param {number} a - The hour to be converted (between 0 and 360 degrees). + */ +function hourNumber(a) { + const h = gHeight + lineOffset; + const rotatedPoints = rotatePoints( + [{ + x: 0, + y: -h + hourLength + hourOffset + }], a, radius + ); + g.drawString(String(a / 30), rotatedPoints[0], rotatedPoints[1]); +} + +/** + * Draws a number on the display. + * + * @param {number} n - The number to be drawn. + * @return {void} + */ +function drawNumber(n) { + const h = gHeight + lineOffset; + const halfWidth = handWidth / 2; + const rotatedPoints = rotatePoints( + [{ + x: 0, + y: -h + hourLength + numberOffset + }], hourAngle, radius + ); + g.setColor(0xF800); + g.fillCircle(rotatedPoints[0], rotatedPoints[1], numberSize+ halfWidth); + g.setColor(g.theme.bg); + g.fillCircle(rotatedPoints[0], rotatedPoints[1], numberSize - halfWidth); + g.setColor(g.theme.fg); + g.setFont("Vector:"+numberSize); + g.drawString(String(n), rotatedPoints[0], rotatedPoints[1]); +} + +const hourPoints = getHourCoordinates(false); +const hourSPoints = getHourCoordinates(true); + +/** + * Draws an hour on a clock face. + * + * @param {number} h - The hour to be drawn on the clock face. + * @return {undefined} + */ +function drawHour(h) { + if (h === 0) { h= 12; } + if (h === 13) { h= 1; } + g.setColor(g.theme.fg); + g.setFont("Vector:32"); + const a = h * 30; + g.fillPolyAA(rotatePoints(hourPoints, a, radius)); + g.fillPolyAA(rotatePoints(hourSPoints, a + 15, radius)); + hourNumber(a); + hourDot(a + 5); + hourDot(a + 10); + hourDot(a + 20); + hourDot(a + 25); +} + +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function lockListenerBw(isLocked) { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + draw(); +} +Bangle.on('lock', lockListenerBw); + +Bangle.setUI({ + mode : "clock", + remove : function() { + Bangle.removeListener('lock', lockListenerBw); + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); + +/** + * Draws a clock on the canvas using the current time. + * + * @return {undefined} + */ +function draw() { + queueDraw(); + currentTime = new Date(); + currentHour = currentTime.getHours(); + if (currentHour > 12) { + currentHour -= 12; + } + currentMinute = currentTime.getMinutes(); + + hourAngle = getHourHandAngle(); + + g.clear(); + g.setFontAlign(0, 0); + + g.setColor(g.theme.bg); + g.fillRect(0, 0, gWidth, gHeight); + + if(settings.showLock && Bangle.isLocked()){ + g.setColor(g.theme.fg); + g.drawImage(imgLock(), gWidth-16, 2); + } + + drawHour(currentHour); + drawHour(currentHour-1); + drawHour(currentHour+1); + + + drawHand(); + drawNumber(currentMinute); +} + +draw(); diff --git a/apps/line_clock/metadata.json b/apps/line_clock/metadata.json new file mode 100644 index 000000000..a2aad5f58 --- /dev/null +++ b/apps/line_clock/metadata.json @@ -0,0 +1,17 @@ +{ "id": "line_clock", + "name": "Line Clock", + "shortName":"Line Clock", + "version":"0.1", + "description": "a readable analog clock", + "icon": "app-icon.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "allow_emulator": true, + "screenshots": [{"url":"app-screenshot.png"}], + "readme": "README.md", + "storage": [ + {"name":"line_clock.app.js","url":"app.js"}, + {"name":"line_clock.img","url":"app-icon.js","evaluate":true} + ] +} From a54d37dbfc33f8f088bc75146c89289243c69b67 Mon Sep 17 00:00:00 2001 From: Paul Spenke Date: Fri, 5 Jan 2024 19:15:55 +0100 Subject: [PATCH 2/6] Implement showMinute setting in Line Clock app The commit adds 'showMinute' configuration in both app and settings file for the Line Clock app, allowing users to choose whether to display the minute. An additional property within the settings JSON file is now read at application start to adjust behavior accordingly. --- apps/line_clock/app.js | 17 ++++++++++++--- apps/line_clock/metadata.json | 6 ++++-- apps/line_clock/settings.js | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 apps/line_clock/settings.js diff --git a/apps/line_clock/app.js b/apps/line_clock/app.js index 0596b865e..4d243b736 100644 --- a/apps/line_clock/app.js +++ b/apps/line_clock/app.js @@ -9,10 +9,18 @@ const hourOffset = 32; const numberOffset = 85; const numberSize = 22; +const SETTINGS_FILE = "line_clock.setting.json"; + let settings = { - showLock: true + showLock: true, + showMinute: true, }; +let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings; +for (const key in saved_settings) { + settings[key] = saved_settings[key]; +} + let gWidth = g.getWidth(), gCenterX = gWidth/2; let gHeight = g.getHeight(), gCenterY = gHeight/2; @@ -218,7 +226,7 @@ function queueDraw() { }, 60000 - (Date.now() % 60000)); } -function lockListenerBw(isLocked) { +function lockListenerBw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = undefined; draw(); @@ -267,7 +275,10 @@ function draw() { drawHand(); - drawNumber(currentMinute); + + if(settings.showMinute){ + drawNumber(currentMinute); + } } draw(); diff --git a/apps/line_clock/metadata.json b/apps/line_clock/metadata.json index a2aad5f58..01393efdf 100644 --- a/apps/line_clock/metadata.json +++ b/apps/line_clock/metadata.json @@ -12,6 +12,8 @@ "readme": "README.md", "storage": [ {"name":"line_clock.app.js","url":"app.js"}, - {"name":"line_clock.img","url":"app-icon.js","evaluate":true} - ] + {"name":"line_clock.img","url":"app-icon.js","evaluate":true}, + {"name":"line_clock.settings.js","url":"settings.js"} + ], + "data":[{"name":"line_clock.setting.json"}] } diff --git a/apps/line_clock/settings.js b/apps/line_clock/settings.js new file mode 100644 index 000000000..5a793ed0f --- /dev/null +++ b/apps/line_clock/settings.js @@ -0,0 +1,39 @@ +(function(back) { + const SETTINGS_FILE = "line_clock.setting.json"; + + // initialize with default settings... + const storage = require('Storage') + let settings = { + showLock: true, + showMinute: true, + }; + let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings; + for (const key in saved_settings) { + settings[key] = saved_settings[key] + } + + function save() { + storage.write(SETTINGS_FILE, settings) + } + + E.showMenu({ + '': { 'title': 'Line Clock' }, + '< Back': back, + 'Show Lock': { + value: settings.showLock, + format: () => (settings.showLock ? 'Yes' : 'No'), + onchange: () => { + settings.showLock = !settings.showLock; + save(); + }, + }, + 'Show Minute': { + value: settings.showMinute, + format: () => (settings.showMinute ? 'Yes' : 'No'), + onchange: () => { + settings.showMinute = !settings.showMinute; + save(); + }, + } + }); + }) From e62d3fd2198965e29add4407559da7ada84ea0a1 Mon Sep 17 00:00:00 2001 From: Paul Spenke Date: Sat, 6 Jan 2024 15:00:52 +0100 Subject: [PATCH 3/6] Add Storage requirement to Line Clock app --- apps/line_clock/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/line_clock/app.js b/apps/line_clock/app.js index 4d243b736..67ad742f5 100644 --- a/apps/line_clock/app.js +++ b/apps/line_clock/app.js @@ -9,6 +9,8 @@ const hourOffset = 32; const numberOffset = 85; const numberSize = 22; +const storage = require('Storage'); + const SETTINGS_FILE = "line_clock.setting.json"; let settings = { From 651d08de5316a282deb8c319c4b474b21de4507c Mon Sep 17 00:00:00 2001 From: Paul Spenke Date: Sat, 6 Jan 2024 15:06:25 +0100 Subject: [PATCH 4/6] Update changelog --- apps/line_clock/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/line_clock/ChangeLog b/apps/line_clock/ChangeLog index 0f7cf828d..504dc0efe 100644 --- a/apps/line_clock/ChangeLog +++ b/apps/line_clock/ChangeLog @@ -1 +1 @@ -0.1 init app +0.1: init app From c21ea99724bcfab50d0b6b593f28c329ef59ad6c Mon Sep 17 00:00:00 2001 From: Paul Spenke Date: Sat, 20 Jan 2024 19:48:33 +0100 Subject: [PATCH 5/6] Refactor settings in line_clock app The `settings` object has been renamed to `initialSettings` for better clarity as these values represent the initial, default settings. Also, the code to remove the clock UI has been commented out, possibly signaling future work on applying the Fast Load system, but this needs to be confirmed. Lastly, calling settings to draw locking and minute indicators has been updated to call the renamed `initialSettings` object. --- apps/line_clock/app.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/line_clock/app.js b/apps/line_clock/app.js index 67ad742f5..eadc46fad 100644 --- a/apps/line_clock/app.js +++ b/apps/line_clock/app.js @@ -13,14 +13,14 @@ const storage = require('Storage'); const SETTINGS_FILE = "line_clock.setting.json"; -let settings = { +let initialSettings = { showLock: true, showMinute: true, }; -let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings; +let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || initialSettings; for (const key in saved_settings) { - settings[key] = saved_settings[key]; + initialSettings[key] = saved_settings[key]; } let gWidth = g.getWidth(), gCenterX = gWidth/2; @@ -237,11 +237,12 @@ Bangle.on('lock', lockListenerBw); Bangle.setUI({ mode : "clock", - remove : function() { - Bangle.removeListener('lock', lockListenerBw); - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = undefined; - } + // TODO implement https://www.espruino.com/Bangle.js+Fast+Load + // remove : function() { + // Bangle.removeListener('lock', lockListenerBw); + // if (drawTimeout) clearTimeout(drawTimeout); + // drawTimeout = undefined; + // } }); /** @@ -266,7 +267,7 @@ function draw() { g.setColor(g.theme.bg); g.fillRect(0, 0, gWidth, gHeight); - if(settings.showLock && Bangle.isLocked()){ + if(initialSettings.showLock && Bangle.isLocked()){ g.setColor(g.theme.fg); g.drawImage(imgLock(), gWidth-16, 2); } @@ -278,7 +279,7 @@ function draw() { drawHand(); - if(settings.showMinute){ + if(initialSettings.showMinute){ drawNumber(currentMinute); } } From ef94eab3633458920c8a1f2f7e8ed639b8e93cb6 Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Sat, 20 Jan 2024 22:58:30 +0100 Subject: [PATCH 6/6] Update settings.js Delete custom formatting for booleans in settings, falling back on the default checkboxes. --- apps/line_clock/settings.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/line_clock/settings.js b/apps/line_clock/settings.js index 5a793ed0f..5da04e959 100644 --- a/apps/line_clock/settings.js +++ b/apps/line_clock/settings.js @@ -21,7 +21,6 @@ '< Back': back, 'Show Lock': { value: settings.showLock, - format: () => (settings.showLock ? 'Yes' : 'No'), onchange: () => { settings.showLock = !settings.showLock; save(); @@ -29,7 +28,6 @@ }, 'Show Minute': { value: settings.showMinute, - format: () => (settings.showMinute ? 'Yes' : 'No'), onchange: () => { settings.showMinute = !settings.showMinute; save();