From b29a2c4d0b9d10b4d66c41a402c051236ecc2f68 Mon Sep 17 00:00:00 2001 From: Hugh Barney Date: Tue, 6 Dec 2022 23:12:14 +0000 Subject: [PATCH] Added simplestpp, basic clock with fast load and clock_info support --- apps/simplestpp/README.md | 54 ++++++++++++++++ apps/simplestpp/app.js | 108 ++++++++++++++++++++++++++++++++ apps/simplestpp/app.png | Bin 0 -> 994 bytes apps/simplestpp/icon.js | 1 + apps/simplestpp/metadata.json | 16 +++++ apps/simplestpp/screenshot1.png | Bin 0 -> 2411 bytes apps/simplestpp/screenshot2.png | Bin 0 -> 2444 bytes apps/simplestpp/screenshot3.png | Bin 0 -> 2622 bytes 8 files changed, 179 insertions(+) create mode 100644 apps/simplestpp/README.md create mode 100644 apps/simplestpp/app.js create mode 100644 apps/simplestpp/app.png create mode 100644 apps/simplestpp/icon.js create mode 100644 apps/simplestpp/metadata.json create mode 100644 apps/simplestpp/screenshot1.png create mode 100644 apps/simplestpp/screenshot2.png create mode 100644 apps/simplestpp/screenshot3.png diff --git a/apps/simplestpp/README.md b/apps/simplestpp/README.md new file mode 100644 index 000000000..4b459bda1 --- /dev/null +++ b/apps/simplestpp/README.md @@ -0,0 +1,54 @@ +# Simplest++ Clock + +The simplest working clock, with fast load and clock_info + +![](screenshot1.png) +![](screenshot2.png) +![](screenshot3.png) + + +Simplest++ has 1 clock info menu that is displayed as a single line at the bottom of the screen. + +This provides a working demo of how to use the clock_info modules. + + +## Usage + +* When the screen is unlocked, tap at the bottom of the csreen on the information text. + It should change color showing it is selected. + +* Swipe up or down to cycle through the info screens that can be displayed + when you have finished tap again towards the centre of the screen to unselect. + +* Swipe left or right to change the type of info screens displayed (by default + there is only one type of data so this will have no effect) + +* Settings are saved automatically and reloaded along with the clock. + +## About Clock Info's + +* The clock info modules enable all clocks to add the display of information to the clock face. + +* The default clock_info module provides a display of battery %, Steps, Heart Rate and Altitude. + +* Installing the [Sunrise ClockInfo](https://banglejs.com/apps/?id=clkinfosunrise) adds Sunrise and Sunset times into the list of info's. + + +## References + +* [What is Fast Load and how does it work](http://www.espruino.com/Bangle.js+Fast+Load) + +* [Clock Info Tutorial](http://www.espruino.com/Bangle.js+Clock+Info) + +* [How to load modules through the IDE](https://github.com/espruino/BangleApps/blob/master/modules/README.md) + + +## With Thanks + +* Gordon for support +* David Peer for his work on BW Clock + + +Written by: [Hugh Barney](https://github.com/hughbarney) For support +and discussion please post in the [Bangle JS +Forum](http://forum.espruino.com/microcosms/1424/) diff --git a/apps/simplestpp/app.js b/apps/simplestpp/app.js new file mode 100644 index 000000000..c07fdbcbb --- /dev/null +++ b/apps/simplestpp/app.js @@ -0,0 +1,108 @@ +/** + * + * Simplestpp Clock + * + * The entire clock code is contained within the block below this + * supports 'fast load' + * + * To add support for clock_info_supprt we add the code marked at [1] and [2] + * + */ + +{ + // must be inside our own scope here so that when we are unloaded everything disappears + // we also define functions using 'let fn = function() {..}' for the same reason. function decls are global + + let draw = function() { + var date = new Date(); + var timeStr = require("locale").time(date,1); + var h = g.getHeight(); + var w = g.getWidth(); + + g.reset(); + g.setColor(g.theme.bg); + g.fillRect(Bangle.appRect); + + g.setFont('Vector', w/3); + g.setFontAlign(0, 0); + g.setColor(g.theme.fg); + g.drawString(timeStr, w/2, h/2); + clockInfoMenu.redraw(); // clock_info_support + + // schedule a draw for the next minute + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); + }; + + /** + * clock_info_support + * this is the callback function that get invoked by clockInfoMenu.redraw(); + * + * We will display the image and text on the same line and centre the combined + * length of the image+text + * + * + */ + let clockInfoDraw = (itm, info, options) => { + + g.reset().setFont('Vector',24).setBgColor(options.bg).setColor(options.fg); + + //use info.text.toString(), steps does not have length defined + var text_w = g.stringWidth(info.text.toString()); + // gap between image and text + var gap = 10; + // width of the image and text combined + var w = gap + (info.img ? 24 :0) + text_w; + // different fg color if we tapped on the menu + if (options.focus) g.setColor(options.hl); + + // clear the whole info line + g.clearRect(0, options.y -1, g.getWidth(), options.y+24); + + // draw the image if we have one + if (info.img) { + // image start + var x = (g.getWidth() / 2) - (w/2); + g.drawImage(info.img, x, options.y); + // draw the text to the side of the image (left/centre alignment) + g.setFontAlign(-1,0).drawString(info.text, x + 23 + gap, options.y+12); + } else { + // text only option, not tested yet + g.setFontAlign(0,0).drawString(info.text, g.getWidth() / 2, options.y+12); + } + + }; + + // clock_info_support + // retrieve all the clock_info modules that are installed + let clockInfoItems = require("clock_info").load(); + + // clock_info_support + // setup the way we wish to interact with the menu + // the hl property defines the color the of the info when the menu is selected after tapping on it + let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { x:64, y:132, w:50, h:40, draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg, hl : "#0ff"} ); + + // timeout used to update every minute + var drawTimeout; + g.clear(); + + // Show launcher when middle button pressed, add updown button handlers + Bangle.setUI({ + mode : "clock", + remove : function() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + // remove info menu + clockInfoMenu.remove(); + delete clockInfoMenu; + } + }); + + // Load widgets + Bangle.loadWidgets(); + draw(); + setTimeout(Bangle.drawWidgets,0); +} // end of clock diff --git a/apps/simplestpp/app.png b/apps/simplestpp/app.png new file mode 100644 index 0000000000000000000000000000000000000000..814306471485b135eb105e2d63304b06565e4d7e GIT binary patch literal 994 zcmV<810DQ{P)D(Dg!Z*3O znLFp6^F8m~bKkk=at|HxP-=a{P$oUwaS#Wv2an<5RWjFc2^a7U&S4>w{Y_yM)A$N2 zXjj@TwD3!6tu$7ZS-~8RC0zqU6UXs;h0FrZ;0PXHhtO#H?`V=;tjzxnub|Oq?k4e5 z#qbw6v`NEFynxw?zIjY!VY&)KcnizP(06z$qy8!UkaREM4f*0z6Yp1)pTKY~h)N-0h3jV;ZY}D#w zhj{C4yx#5PNwF4}3})G^hp7sW+PhOzxmBL%k-)pD^@6t(mmk%PhvUkvve(__@6>uh zLy&Ld<&A_#m0#E#`+N=uV87sW1tXmVr8O@1X_*`&&z8I`Ja3J+x50F&1m`nY$ z#X!}8J*l4`7@h8MKJ~lT`twimnsT0wa>f8`6U+PR>OY3@j|h^S$n5|@ennb6#cuO} z$oOv5Q1Fg8+|#cCi?!I`D1kpBosR?op%=Yi0{YGPh{!CUY$j17qt6 zowIe*=@$jJ*-k>o>Iij#oDLKZ_edw9QBi1ZV{Zndxg2;}aJp=RBPCHKZi`ywRyow4 zPn=$=J7GRenCa1Yj;D(sx5Wvsxahu? z##YPBiri*1ZxH#eGRH(|@)=Pe+a)RoRa_M(sf!|?pOgO#o*fUSb`R^}U&vwyOs<=L Q@Bjb+07*qoM6N<$f{4=I_5c6? literal 0 HcmV?d00001 diff --git a/apps/simplestpp/icon.js b/apps/simplestpp/icon.js new file mode 100644 index 000000000..bec6c9752 --- /dev/null +++ b/apps/simplestpp/icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4UA///E8MBqtVoALHBQIABBQ0FqgDBitQCwwEIFoISEgoxEiodFFAQEGCQoiFEgsBLQwHDgplHD4UUCYwIDBZY6DBYgsCBZQGEAgwLXLwhvFqALmirvDXIQLPI9ibja677MBZZgELwhnHA4sBHgY6DCYatCAAcVAhASGEgoiEAANVAhASCDwUVIIwTBAARlHgIKBMgwAV")) diff --git a/apps/simplestpp/metadata.json b/apps/simplestpp/metadata.json new file mode 100644 index 000000000..10f756e32 --- /dev/null +++ b/apps/simplestpp/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "simplestpp", + "name": "Simplest++ Clock", + "version": "0.01", + "description": "The simplest working clock, with fast load and clock_info, acts as a tutorial piece", + "readme": "README.md", + "icon": "app.png", + "screenshots": [{"url":"screenshot3.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"simplestpp.app.js","url":"app.js"}, + {"name":"simplestpp.img","url":"icon.js","evaluate":true} + ] +} diff --git a/apps/simplestpp/screenshot1.png b/apps/simplestpp/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..94cb35cd604fd3648c679f135feb4df9101ee5d2 GIT binary patch literal 2411 zcmdT`dpOe#8=ha2ZK*~~4q?r_yzHx&P`3Ichmd30u#u9F$k1wtZI$wx-}AeEl`*IRM2;Ldy@9p~v>VEW0g>Z}S~lFJ z^Ye?DE6cIlMH?cmlUjFp&7GLw*wVFB@36kpdcb9*PWw;a!7O;+(9*rW{dvr>P?rEeeu7F}(#J9cGSB$9LBuXJJ%Jh`Wi<>v5 zUfV2Fp_D#sKDHSGJr3(B}}?q(eMgr0%U*%GXKv!DBwpA$n|@J=xJ z4d@jGpM#T`f1l!utOfa=O&V)CpPlPor=iCU9)x2T)`63at!oEtX)=falzI8H z@AYEL4ug|wVVc7mE;-i2c5SwN9}A#GPv#>vke zdC82%Me98s*PyjvN;+e>Ec=7bx}I6hDc(e$P2JhL^1rS6-^^~;+ycH9oY`)T7)#pC z@KKRgs`=I@?ezr^_wf#m>I(3NFr`y9aP)qc)L0V$ac*E+%NeA8RQAqgG8{ehWY^Vp zRU4`4Z!;AL{VH!F;toC$@;%*8Rj~;yW1wEE@)dustK~VPM6` z;d`bE@E+Box5+So`u|1v%2nFcoJoAIH_Yt36VX-rHewf@m8;le`f=>J%5L#g4t6f` zgC8L(#R!)up7ND%lerjSsga|!UR+JpRf@j6gQ5*iyb3qa#YaWxT7lt`>Marugwyce zG(yNIdg?wMhL6I04FzjiG{qi%&@cQNsH2dBv)Pwn)+WaGk;2{-vieE5DQ~mC{2cdX zXiMmT$*qByybhX5XmENy%K=G>+a-?9g3pPJ>~kNVrL%M<*D7duFkD+L&4j(vNvGR? zNkq-hwXka|D~-07CgBmZxK2)6+GH|>AhnJ-(Nr#}eteg`v+{i=ap9&?HO9$rG4-4W z)0Ob~Wq=D$j~mjyjTGyN8VYg^*VO>2lFTX0K<`U)e`%=aOv)l6{|76Bv<>*?bED%J zFE1+Ifu#pnC4BG*AXZ>jc(klTZaaKH662dJC!_>AC@Dbf80hLTx0ep58C6gY7Eh35olfZ$l+$2A{e zD=iPcIZ9dh2;f`Shk;=Ek)9JR7Dvh!5AMCixHS+ad{VsLUlJo#p48m#KxZuyR${J> zT8}M`Mej0PP-dB@J;(~FgK7s0P$Uy~4R9PY^&b)a87?v?d9V5WQ30twB8qy0ny*Un z4HVdmrVhXL10vp|g=r_3LIv7=1b4WP>QICyowfUA%mZ=7GeSm7eIC^D!px$iwhpjn z5K0;>-DUgn$6dSKSe#{Sm96p0gUGw|$K0#YqdPf+`c<|_(BAob&7gpcFg2?jcM5M~ zSHBJ>PI+Q(Kqx#jFw?6kb=Ush@-RDDk2jJ3Yw_ODQc}zLy5_7|rf|Zz*R4euEiG zY5=0#qp($O@X?0rfhYwy*~l|UZvF`Bk-gVofC=YuwLBOaDzNu#VW7Hm|B$Lp;OHRw z7&cL^F66=s;+95cJYNIWT7ydM3su)x8C#@8f5PFkzER&%Sg!aqXfB&^6?A4UA}<+?^AV2tj8>@_`@5BnFACd&qoxrR=)>;`yt4-;i$qqUvz= z(%JUD<=&to5*{3=?#mqlyA66!n1jl^&d!dwi<`T36vKMkO7e_u`v+GG>AmI)DkJ0H zqo02%Ak#|Pac=|V=luPYs{tpLOumagc#gM38^A`XH#Wvda{$3hZSFxAh9EUqiT{W3 zhizVY6S3>wdc|}6qV)OiDK;|})Zs4K%1O#-oYJ9Yt=NqNst>=uEAifZF`m=>^__cW zd3KuFw}-iFisZL;e}$(08hF+!oK;n>If`4-{}Su^lLi(oMen)NRm*_^dtUUupdwdw z!8je9-&yk}q5^y_or4Tfy~KywtkhUa(6VHim9n9dzX=to&`j@4a( z0hJGXEW|1{Qo2!2sGjROlx{CXX52bU0e5?QH1x--uU~ Ytg!jVig__2`S%2KvUjuN+Xi0w7v-!_{Qv*} literal 0 HcmV?d00001 diff --git a/apps/simplestpp/screenshot2.png b/apps/simplestpp/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..d24d55b029b7bbb2ba5f918188ab2df741526690 GIT binary patch literal 2444 zcmeHJ{X5eOAD&qm4vkt)Wtf-K(>2ReEDIY7qe5P1V&o-^@-j@`I^R>|UD75?JVJ#H z#WuCku5{{>jl7H^YbW89jb-JfH;;3j>-iU+>-pjN;d9?V+@Jft?(6f@r|_f~K}T!1 z76=5=@o;zX-Q&=LVchh(O4j%P5<=A* z^9h%q$cG1ARkoo=f(C^%?zl$bB=6^urIWG7TAV~=qrj3@n7kv?c69HSTsekmer!RR zBVfl%{cC10?W#rr3`IQp*0&7akG z!|xZ{N}=?(TK(I>_({8=WXXp=#W5s+%}=t5Elt`bzUxnL*}qF9N<`Y^#pzeg4U6h? zOvgoVdih+065kaqLEc-dm{UE-F{|&N7+9FtQ>9Q8oH^KxJwBpGb=_Q^pfr2-jVvqA zkoZ-F(ceN@7BMKRDk0->m*!{CT}CkHYB(j>*6VZlPB^X`Ds z1;$b;n0PS+ZR{~3)fi;WL&c$J)f#*mM)YJ*)a?j#-5RY{inuh?E}^?%lpi0pbC<=n<7A6t|1bVwmhcKJKHnU<2} z3MRf-&}W3Sc^tI}lPsV2m7Qo~+T~9Ht^K}eW6#l32O7o!p|orRVN01AiY^a+cJl9L zOB`$pVpLOp_N@fFR7G)_uU|)~Ct72`gb8bXqNk$eO&;jecSiytyp*E2F1_pr3B13$ z7$Qx6-X%J1HrudI7rEQ=J1Pd&j~(Wi?*s*ebcSro!}O;OVLLnkXJlFfOTAFAXW{cOL%^% z8Un*s9*WP~?j%cUJaPShS#+U%H%(HkUi+M@Mh-8Wy?sO`WVk@(-`oBW9?WNI0qRo{ zR7bjl{qhCRqcSG|on-9y@ICB`F1oEgk9T<=P1f^D0$GvwGDCA_ zufK=13H(Tq-eR0~RvCT2tcA9BC=c5uoOi3)vlla>F0yyi_f>&tX@rWWi!;H=l11OZ z-aakXbegGoSq2A=R7zj-FFUq^h}6vaek0pFAt9Ey%?W2O-UBvP(aT(kbz!qTVzjs# zeT&wE+`=`2XVU&415MMk_}U%Ry)`QdJ?zK_{}lK}m+kQiZ!eK1>xr+t8-r#WG{A#0 zaTC<4BH6p@$bSG?7IMUr8mqzpz(s8!tZRfle3uoJIb>y^dDr0*p$|W1%wc!;!%EVO1!-bvkGDBW+tTEio9YuAyyk_$IemipeTBr!AOv@K9fpXUky? zS_yPwr*?d<{+;hSyzxwLvMAHyY{l#rF8$~y3IvwHDf14r0(+0YkUV#mN$l{X9;gH9 zC=sOr5Es^>KAS3|bVAvN5HfqFQc^6e#H4ak{(Gh$YE~wS69F$xIGgVk$ivmkrR_-g GZ~q31IDNPP literal 0 HcmV?d00001 diff --git a/apps/simplestpp/screenshot3.png b/apps/simplestpp/screenshot3.png new file mode 100644 index 0000000000000000000000000000000000000000..af7ae7249bcc816643c766973237ca6472143124 GIT binary patch literal 2622 zcmdUx=|9wu7RUK!)R%OR2P930RsQ^Sjw!rgv89LXUg4;zNWwkQIZbN+Q3h)-mpkI=9pRktL^r;IsDys7{kC|GPo(-@T#ur*A zgP*Qb8B;Gn^mfCH8ueCXVYhZ*rhYi14sg#4m6n%Zb88@J;!B-z3LeABaOM6m)wnR+ z#*l}R%}@(f3ldYN_cmyIcg}?ejvZ1U+Q*k7E`~AQRg_=Hc1@rmP%0!98$D5 z#`&_m7!N4HKi~_k-xTTh{lfkMT1*@271sU&MKRsGTKeRlAPS(^Jxqxvoz6MxIumDS zpiQtUENboR5!E!B^@|YNRtS7}vNRpsLGROqwy)m|44@f#>8nVK4aBx9qqS0-uL!3gyK^98w~pWdTIfC2exL832&aO!dxmut&Gp$h?hOZ+*9KrO0*+q%lK+QIn_*MBM`{ z-f}L58nc0~=I|Qu|26iQbPY3Z-uLg>Pc)|ONlHew1G+xC1>(Si)CjuWLu2+H3-ft7 z2(XgR0pa!0x)O|37ayXO(Zqop(;1Zu_7|t}nn>_1-gcuoTcB~#-g1_X^!*|S)u}B< zyr(gr%dCEACh=hsQCOUMQ3X&*80gAF6v(D(0mYgY>0t&oA`Mq$juZ}?MBEoCUDgY# z2;x0nKpcqu0L_q{rMf4+)PHx$r5BDv^Npw`9u%6U>9s5V ziHL4XuGbKGcyi=fnOVl_mp(d?uGbd%CxpBMC&J@b1e!iaf9ytUSfO^#*_9xVJ)@9~ zS?64F+;6^>vWlgc7c;~amDahwpJ-~lV~espp{Y-D%Nk)yMi{FrwceFsjOdJV`Of=< zrpRPvZ+owRS34Y|1%o2TaZzvQ^{J8j7*6dbf(T5ywx-pkZ2h^CN`KzM=yIn<=3tT& z{@alkK#IbPg)>XTCmBC74(`{21-A0e{1F9UWltIh+SM_lVI{OrxGL`Sbk4ZwTM0n^ z)VZN{8uLmvw#wr*_l~#MIBrh$Re@&m<#NzsR1s$jcO0)=_<*HGJ;Iv9@V>l8NPg=S z!aF4kT<%J_+It@6CeMKGg3VFq+b7}cMTKf}@?2)4%*~bdDVMPW#vQiGWo2`FQw1nM z$`6r$PuZV;`Cv|Xu3y<)C^Q}C^jSu+UK3UOd!W7l=A|iLqGGl5<;`yn9@wRlKgRE_ z@nNzBP_;H+1~&Y+RkSk2KFC@8(77~R-edq7%5sd*9_~A+uJ$#uQl)C$#qfZ$)Aonn zCn#*MD4x4Y+b~IiAAfp*?c$=SB6)r*@^(nJb(#P6slT~kxy)+Eq4ixtm%vZ5U&o|4 zzp{3bcBBWus$W}Op;NFSV$N;!XdBAJG^J5VI`bOu>A)LG%e+3s1Id~E;dNc9Z9;sF z^T9OzRq*i?qJYcjFa?}>yDvObq>+vYA5)r=>Q62+wARJ5?u6kyse1T^9&2k`Npvco z#7%GA9g@>*0>C00pi@R8y)p)t@LnFVVw!VDPNTL(>3@10#yzNwi^oUw?!&Z86z*cSZHZu$IIV-d-#`<5!dZ)B_P$9{~x!hiJ1^ZCuYPwt|B#4Wc#q@(+)Dx6H=iu1t;Od9{YK9awY342hsnqn7~>fKl7JTty?^Bk{`D{Dxjx z5ZdBp3FQz(pu8oX>oZ9=HJz^2dUp|nD;b$EXk0XU-L-Lkm+=9yGXZ-Tn^nmcXo*0N|&%mcNW z$rX5JFG+;);AuAnjJskbwdQ6LN=??qmcJw++0a+~$uR zT;xV?OCT=4w5~re6LaFDyO(g!`Qk9D*HUHC2$st?c)}B{>aEF2zwdw>%Sz@hR=+#D zYSUhM4=n`|&zmuyE zCgM{47L^_kiNzQ=%2R=A`mZEf08yO&p4RsYtR(#P*uc&vsfX0xR9N#Djl;Afwmf)U mt3+UJSgN=~_5XTppA$@wb>`Tlh_fF;4pSp5!