From 272d1f9fe4e8ea22b5c5bb3e23ca1515cb454156 Mon Sep 17 00:00:00 2001 From: Darren Croton Date: Fri, 14 Apr 2017 18:47:14 +1000 Subject: [PATCH] Initial commit of near final version --- .project | 17 + bin/SnapshotWatch-settings.json | 1 + bin/SnapshotWatch.prg | Bin 0 -> 56337 bytes bin/SnapshotWatch.prg.debug.xml | 560 +++++++++++++++++++++++ manifest.xml | 16 + resources/drawables/alarm-clock-12.png | Bin 0 -> 374 bytes resources/drawables/alarm-clock-13.png | Bin 0 -> 399 bytes resources/drawables/alarm-clock-14.png | Bin 0 -> 442 bytes resources/drawables/alarm-clock-15.png | Bin 0 -> 457 bytes resources/drawables/alarm-clock-16.png | Bin 0 -> 484 bytes resources/drawables/bluetooth-2-12.png | Bin 0 -> 262 bytes resources/drawables/bluetooth-2-13.png | Bin 0 -> 220 bytes resources/drawables/bluetooth-2-14.png | Bin 0 -> 310 bytes resources/drawables/bluetooth-2-15.png | Bin 0 -> 284 bytes resources/drawables/bluetooth-2-16.png | Bin 0 -> 297 bytes resources/drawables/drawables.xml | 7 + resources/drawables/launcher_icon.png | Bin 0 -> 1292 bytes resources/drawables/mute-2-12.png | Bin 0 -> 269 bytes resources/drawables/mute-2-13.png | Bin 0 -> 314 bytes resources/drawables/speech-bubble-12.png | Bin 0 -> 252 bytes resources/drawables/speech-bubble-13.png | Bin 0 -> 272 bytes resources/drawables/speech-bubble-14.png | Bin 0 -> 303 bytes resources/drawables/speech-bubble-15.png | Bin 0 -> 308 bytes resources/drawables/speech-bubble-16.png | Bin 0 -> 285 bytes resources/layouts/layout.xml | 2 + resources/resources.xml | 27 ++ resources/strings/strings.xml | 3 + source/SnapshotWatchApp.mc | 22 + source/SnapshotWatchView.mc | 547 ++++++++++++++++++++++ source/SunCalc.mc | 110 +++++ 30 files changed, 1312 insertions(+) create mode 100644 .project create mode 100644 bin/SnapshotWatch-settings.json create mode 100644 bin/SnapshotWatch.prg create mode 100644 bin/SnapshotWatch.prg.debug.xml create mode 100644 manifest.xml create mode 100644 resources/drawables/alarm-clock-12.png create mode 100644 resources/drawables/alarm-clock-13.png create mode 100644 resources/drawables/alarm-clock-14.png create mode 100644 resources/drawables/alarm-clock-15.png create mode 100644 resources/drawables/alarm-clock-16.png create mode 100644 resources/drawables/bluetooth-2-12.png create mode 100644 resources/drawables/bluetooth-2-13.png create mode 100644 resources/drawables/bluetooth-2-14.png create mode 100644 resources/drawables/bluetooth-2-15.png create mode 100644 resources/drawables/bluetooth-2-16.png create mode 100644 resources/drawables/drawables.xml create mode 100644 resources/drawables/launcher_icon.png create mode 100644 resources/drawables/mute-2-12.png create mode 100644 resources/drawables/mute-2-13.png create mode 100644 resources/drawables/speech-bubble-12.png create mode 100644 resources/drawables/speech-bubble-13.png create mode 100644 resources/drawables/speech-bubble-14.png create mode 100644 resources/drawables/speech-bubble-15.png create mode 100644 resources/drawables/speech-bubble-16.png create mode 100644 resources/layouts/layout.xml create mode 100644 resources/resources.xml create mode 100644 resources/strings/strings.xml create mode 100644 source/SnapshotWatchApp.mc create mode 100644 source/SnapshotWatchView.mc create mode 100644 source/SunCalc.mc diff --git a/.project b/.project new file mode 100644 index 0000000..9ffa4e3 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + SnapshotWatch + + + + + + connectiq.builder + + + + + + connectiq.projectNature + + diff --git a/bin/SnapshotWatch-settings.json b/bin/SnapshotWatch-settings.json new file mode 100644 index 0000000..54e0047 --- /dev/null +++ b/bin/SnapshotWatch-settings.json @@ -0,0 +1 @@ +{"settings":[{"key":"showHeartRate","valueType":"boolean","defaultValue":true,"configTitle":"ShowHeartRateLabel","configPrompt":null,"configHelpUrl":null,"configError":null,"configType":"boolean","configReadonly":false,"configRequired":false,"configOptions":null,"configMin":null,"configMax":null,"configMaxLength":null},{"key":"showDigitalTime","valueType":"boolean","defaultValue":false,"configTitle":"ShowDigitalTimeLabel","configPrompt":null,"configHelpUrl":null,"configError":null,"configType":"boolean","configReadonly":false,"configRequired":false,"configOptions":null,"configMin":null,"configMax":null,"configMaxLength":null},{"key":"digitalTimeOffset","valueType":"number","defaultValue":0,"configTitle":"DigitalTimeOffsetLabel","configPrompt":null,"configHelpUrl":null,"configError":null,"configType":"numeric","configReadonly":false,"configRequired":false,"configOptions":null,"configMin":null,"configMax":null,"configMaxLength":null}],"languages":{"valyrian":{"ShowDigitalTimeLabel":"Show digital time","DigitalTimeOffsetLabel":"Digital time offset (integer, +-24)","ShowHeartRateLabel":"Show heart rate graph and cur/min/max values","AppName":"SnapshotWatch"}}} \ No newline at end of file diff --git a/bin/SnapshotWatch.prg b/bin/SnapshotWatch.prg new file mode 100644 index 0000000000000000000000000000000000000000..daa46ddc87bd53ca44c416adebe274a141d602f5 GIT binary patch literal 56337 zcmcG%2Vh&(761P?-e!wDIX0U3~C!iq!UA;(H=%UE^>%P6)Ii`bTt`t{|(Mp=e_&xIQOi3 z?tRv?*0UBrUd!$F9dpdXzv1(2%k}<(H_!cWdeh7+zxvbLomcW=vb zJqKDZ9sh$LT2{e|M{YjqeW9~Iqn6t$FR(0kF+~rxERWzBv>~{|vV4N?T9zM_G6jN* zXaTgMyH-cj<&!O|uu`{BBjt3UMM8 z8yao@G{A*IyF8yg9f{+CvQ3FhWH6aY#{1VK6I;1bE`=JCo06G$e`j(aA(w{x zQe!Up_ubc2>YcT4aW91mQiHKfJe}dAXO_CMVnNq%B0apIwrg}yO5`&rH z1>v6lOm1~Ok z2;rCZQbT<5GR|3GNop{>Et!e+ClYem73Uu_JwKPTkKj>`T(2(@?;opcK-E;L4m&*!@ zd$m@~FVi3D=9i6M;&yRy)GA%bzpjG<jR$IhqSft^qQiLvsXNE=f$&Y&wF>aF4_?AdCa}AjIvlUbT*AD zrZ)z%tu)PE{_(_l`f@nnn_YY33&nX)2v6PiV=&w2nSJmzk&a!;m`*mzg!l|`aKLAJ zvC^(VV-o{d{?^|fQ{}LC0lT-&yVPsiUMcmO$|AW!(*tv7ANtg7ZMiGiL9S$wxo1}C zhL;62Hqe2kcieuhrWiQn8`TL-HV1q*XIBL65!3}eWw?}}nS%1bq&e0EU4FIA*Htu$ zfGMFJ!}8^Uptqvjo!?LQ*b8cQBGPdsoVt#^s6MZxT*#I5hx|dLaumrIu`7c35ya%e zIhJp}^hTFGG>~h18Ws4<-9e8TjL4lXm6fbefxZC43jPbLLWMb|pnR43L19XvW{1A8 zDiAERKY6{OqFk{eiirjrCEHKy->0H>X2uujOP{DqO3Op;pj$rFPM%}ksjFHT(3jj* zrVDbRLX{4>XV(uATIN_VCE!z%?W@!eS?KH>n5QZ&pH|?Yrsh%mPAiyWRp(k%4Y+1~ z_St8*S5{l&cX#6<(}v3va#w$*RAJQZ*ONGEUC+c2`pWdUKjWgSoXK{N7ZWK=nWk&p zCosp_ra#UR7_}y=C$2J9%6&s%?nFkoPgYBmjC@Wp@2lBjO7}mfnD1SRWhH1XU5M*0 z%nQs{{3^Fe;pN0V6xVXs;K@5v;np6elwDYQudFh48-1Lorb*h8n?5mD*0C})=2@(< zyF|0gvi4PS9Fh|5S%Gqox!)L=tEy1{=!W()buS2%`_!~rA&V#>S9Hi{ z-?v^;gDeOZNM(1y);X}m5Fw8gvxiRsOAmWL2McP11q|n)P^eHwH9u4&aC4|wz!fTy z$CMrMcEQ5pU zwjS8fCsk%HE!c+(;EyR&-%4zIRVQh@?tBZvSDv21vT#7gxXD}^#qg4qN zaoxBZNt`uS5`$X9n2T;*9Bs0-QToI1R41IHsq#pxTD12HV8py1NTE?{n$+%IqSV-? z4h$5Q`x)X1|A*B}y#>m=T&)e}JBm$J`&oik&{J8igOV?3J*e%+B<*gMAF(FkZi~eL z`$N^$mTJJ+jQ6W*^x0;-mAXM!&_{!z>i=OhAr%tXYzitDWOHRnKrv-^#$wkgQWLNw zPYT4eANW7buX^|ZEi_mj1WP!o47O*yu?n7BsjgO6w_ID(y=C~y{ZL{vhQO!X`#E(!qYV)%onLdc)I32t@dY*S`2{t5Z``G~%62aLFLmzq1$BC!&Gz

ANz(+N|8!P6zBGTHi=}vW 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 P<=wv?a|6!~G(-F!@MXJW literal 0 HcmV?d00001 diff --git a/bin/SnapshotWatch.prg.debug.xml b/bin/SnapshotWatch.prg.debug.xml new file mode 100644 index 0000000..7d851ff --- /dev/null +++ b/bin/SnapshotWatch.prg.debug.xml @@ -0,0 +1,560 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Load your resources here
]]>
+
+ + Restore the state of the app and prepare the view to be shown
]]>
+
+ + + Update the view
]]>
+
+ + The user has just looked at their watch. Timers and animations may be started here.
]]>
+
+ + Terminate any active timers and prepare for slow updates.
]]>
+
+ + + + + + + Draw the watch hand
]]>
+
+ + + + + + + + + + + + + + + + + + + Draw the hash mark symbols
]]>
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Draw the layout
param The context
]]>
+
+
+
diff --git a/manifest.xml b/manifest.xml new file mode 100644 index 0000000..d8ea1bf --- /dev/null +++ b/manifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/resources/drawables/alarm-clock-12.png b/resources/drawables/alarm-clock-12.png new file mode 100644 index 0000000000000000000000000000000000000000..1dbf3339eb0097a9347e2bf2a111ad18b32613f4 GIT binary patch literal 374 zcmV-+0g3*JP)DtXO5i zFi>pbgnggEpYRS`xNz>_d^f-h*aeQ%%_LFx)Td+L06qgx)YX+FkJ~;-@*&B4V4?m_ z5@0LI>m{uB%spAL_0;Q#aLxI#qXo zpXxRBRtD$3`by0}Spav37vQCOm?RS*Np7nLZIdKz*V>*Rd)hurvH?s2On@`sn>rZ{ zhrkgq9Sz6+(==+-V|6P-z&T)BJpiKKQBMX<0_*@E)#*|wz=k>l-l=<8GS`5wzzblm z-c;9tOThDibTP|PFRN$jsd_Tzbo_Va|J}+`W}f7s`nK(LHElm7xzTo>DpBqSsvnwL?E*bu zR=wHcw}7+2BG7NXhXJJzos_*K-qKu>+9{%T#O)z`qZx&r)A zUjU2h{j`~v)gf>>P3qR+8@QwnfR&6J)aMzK`fh?Z)$JtdT3}wCQ|B6=Q!lC)8qccd z)%l~Os-mj)lZ;y7QIhvb)`6)cqpI4kD#km#QU6rc*H+|9k}K-lBx_amUH#ekXx5W#3+BUst`2Z)745G!jDizA3!p%_Gu zkit?4C^p&!jg?=;JQlvEKY{~O%&`0Ju=}E-UPv-gA0?Sf(pM+yMv{R#t3GJnWfjzO zs!3E=lb{|@&o&-xkKghiR#3-DOtPvTO)_b^%Z((*)tgPP_ks7oovL~aOn|MbS_X~* z1K_24qpDs2%K%li7j>x4C)rLiR)+vd&L>#`PzUN-k{xwHo#|E858w(gtg4Gm1I#v3 zRlk5sKu^6|Ro{B8=oIh@_|o*BI50QW>es4z4lL3!-?Xh>?|2jSqdL>{wYJfB-NyAK z<0So#cUT=I871i@=_grBvI#Ja`V=_P;!UG&sms8Js#*m004ITGe;1ix9X>=de|-e4WFZm2S|4|o&W#<07*qoM6N<$f=vCy*Z=?k literal 0 HcmV?d00001 diff --git a/resources/drawables/alarm-clock-15.png b/resources/drawables/alarm-clock-15.png new file mode 100644 index 0000000000000000000000000000000000000000..cb6bf731b3958de40fa0b0915a08f6f2cc9a264f GIT binary patch literal 457 zcmV;)0XF`LP);DuEP@t+ASr^4T~HAW7QwRg;-gLq!N)R;v?kyES!zQ9vJ4{Gv}VU^GK2aE5J}4s*6dYt^;3yjhgp?eP9UO zNF|qnV?gyiFsF9ZzPbursd*0=Ro#iY8enf+s9sRFfRBL9I0PQ6=f?)XAnLCA4!Eek zsSEq+!)m&z4r+X$&Z{GJFTlJyr#=Uc)w^oyIB4QE;J5lx?WvbiFYIb{ev$_2hlzZv zcDCG-+rW2qy5Ty&k=kjvDd4O6EJ-?*yj)88rQT^a>X%Z^CRuEXZN-5{6?th*7R6PQwCeApm4%8PwfUf#k-DySF{fEs=K)zcqV z1p!{EKgSC|)CDy)Ur~Rkug6?#Fr&UzPk>$Ze(h!h*inyxk=mQ=ZtT9M9@Zy1MSaFk zzEwOOm_Pudd>^dLsEsJ)rJaHzjvW{h7Hx)N#~1WwE+5xh2=}S-q=v2SjFufEri^ zP5~9L2uuUdfEU0k;3;qp=mVp`N#GaI4s`U`^k9k(*fXe>B#+8&|IioK~;peM~*1PN>_GyR1%^ aHGcs@=Di$AR^?y-0000m6iPa4MQ|vEm@b+k$M1J0{2OF`eyo!4ZnCyGFa8OHW&q517DKHN%lL9Kn2_;Ig}*Z zvi)KE%=Vk@2cYUQeoA_gGzRLjQNS^9B1p=5JhLV$Qe@j04~$Jh>nm0r1BYp`rtDdRX&FMq{vMSsY42p2;NKK6)YkW@`q)a zWghbf{zlA5y$3#lr@5Y40b5mIQ1>^(fa*~lfERTU*aHtWT<&M!M}4jPb6upAb`kNe zHk0>DMEt6o*~w~FJD^wFV!H);pi}cKTK{xv(%hd$~JvXP^M}TD?>EOT3c6%r7j|!yKpALFW-T03Ot;D4<+3p7+HqVUv00000NkvXXu0mjfk|%zI literal 0 HcmV?d00001 diff --git a/resources/drawables/drawables.xml b/resources/drawables/drawables.xml new file mode 100644 index 0000000..cea479a --- /dev/null +++ b/resources/drawables/drawables.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/resources/drawables/launcher_icon.png b/resources/drawables/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d3594e7cb975929fe36f50e5bffde505262c0901 GIT binary patch literal 1292 zcmV+n1@roeP)@WZT1er-h zK~zY`<(A)TmSq^nKiB>IdiTD2w>fi5H+`GV>1^WEG${}%gHBRYgw7JFgHHMnf)0XC zDu^JYjx2~muu?oJVwhw>YA7}ln>v=;+}v#M-k;C=-1ptVv!AZHNrDGn@Eklm&wYQd zU*GR_$&$=Q%OfzwBeF*Z?EbIQ)`B&Nv4F)QpaevL$O8adi&R2T4%T(=3n-NkQ(KQs zrLkTBN`W;HmQlGZlF!BtD77%Ktx6HKZ9;NmID>uhMKetVDVH#{^;A~2618t3YH3F| zuD}LKq+G-q?#Jor#=CY2x2GE^jDs^b2&by9@!iQ6-Lj7Hx8KL4>+rhIBVl*bEu(P;CXR9tpQ{3FZ@in zWhbRwdxcYT+gdtJeCQNz>L=}QFr=||yUz!x64c^6HQ6sl8%QKjU6;pLy zFk*>9bYnBNx)$&H6{K8RyuNro?)3>u8AG(P6_m5sR2yuv8tVth=nz;IRHa!_XGbB5 z;(O9{i;oxtjE)bwJ_vwaw4{pT#b5&H$^#4u$3fj4L5g{FQ%mfKT_8hVfUQb`(L@bR z;0K@_)Sba8HCzDLV*CKN?;0w57n5m4H#E(k>Zn4LX=Ci2BNPt4g-zAq4));;^g$)W z?YRPrrjzI4cArPaMj)4^xbH9|l5=$&!1d6}S7B2%gxhve+;a$1TTk-K52^nAJ)~Ti za(Y^;MKH^j6F$2e=XM|drQeWp5kw(j8PSHQWj%W3YH&TAz8+LD&qUGV3ys0Obput* z5oOwl)^*06-PeQLdv#W0&JTQX8kh-Mm?u`C8=HyRH)EDQi8DGBi-<9ZHL=#a9`0Y4 z5v_@uo+8@t4AyaQ|GqJ6=**VP$@!@iRs@;RoiB>-V`oLCQmGr8NqzAViJy)G#NaQ#h8n$1;`GV5B(s<^aFf(mAEQQx zky0^UWA0f5Y$8c;`ULKk3q)%>&<)MlnkC?R5LJ-e7;gW~_}y9(UEhOpsB~<{xic^& zw=!$JH3kVwvB-P=f{G?#Ii_5?4qP9i3M!ukqp?BNM8j#UpTI0_#Odz^N5wPXq3qSx z#*fHquP!~Tq+>dI^YKMw)eKN4RD=nmhGo({wvLy z70>|B5%CMO5wVSkdqk*Y1xQ-t`b*Lhc$0JoX2)+LLS+*eB(;(X)Xcf`LLDEr`!u4P zUb+ERz#8}libKaVqJ}1p4I`Hh1+qO4*%t7bqg_*|&&REP#Q3Bma2^SDwtxNsZh8Ph TbryGB00000NkvXXu0mjfym@dp literal 0 HcmV?d00001 diff --git a/resources/drawables/mute-2-13.png b/resources/drawables/mute-2-13.png new file mode 100644 index 0000000000000000000000000000000000000000..42e05498a7ab9d18187660117a70b1b0511708f2 GIT binary patch literal 314 zcmV-A0mc4_P)IzGxB23maX5Ma0NC7EUDouRa(C z-psjon0Eu*st4&5umoJIqwZPMkvdh!3&65E@vBaHPy@%nwCyXv4IrR;+PyzalB&8? z2T9JW>N&}dnyUKMWB_ccH%Z=;94FasLi1M)dQerZC)rJMp}r+KO7fv*5&i+S6?K^8 zD#;IU4tJq%#i|-6xl-S%>ZqzdlC1V9U`u@hUes4rV5W|MLtqMwd*Gq~@Yue428`6h z`8fUr)lK!j&1eSf%|W1-oJGeC^{yr2to6n%Is5-Pt^t!yybjcdPt6zp5+iKUcK`qY M07*qoM6N<$fWS0000j)@QwArciJ5(JVX0t#>e2u$Q;AIY6{I?muH zZL+gpyEFP>fO-s^t7pIr*d%!c?vkt-4Y%r*y0xRK9I);5wts+nQ&s*~>a7Y@wQz#b zreS}9`Z%fX=PBw}XL{_DB;z)~rd2Bm>MwPw2UL?}1(4*>TA|Lz#s_JQ(^H-IkuML7 ze7QThs!smeq<&Y`MO6XNsz<=}!2ElX7j*`FcHii}X_}9ICh8?{3cRTgNuKvaz2gT& WV}gAAw-6Kn00003~~4X literal 0 HcmV?d00001 diff --git a/resources/drawables/speech-bubble-14.png b/resources/drawables/speech-bubble-14.png new file mode 100644 index 0000000000000000000000000000000000000000..6888c30aa8bf324b8e2041372b6a572daa0ab600 GIT binary patch literal 303 zcmV+~0nq-5P)#jB}Slb?#z-5x*pX}Wj0#~yAD(NT*l1S3ZZq(jN;Gm7Pv$QsoQ6Xv7muuHVQvF{Q zz`RN56IUtbN^+Rwxh--B-X)#Z4wEFG|2V}*lF8P>_KEH9zT+o(usyCdrR@=L1C-Uu zmy)iN464}{NgjchqA0e_N=X;Msw&v?wCR6@=5pMth002ovPDHLkV1i;; BfRg|K literal 0 HcmV?d00001 diff --git a/resources/drawables/speech-bubble-15.png b/resources/drawables/speech-bubble-15.png new file mode 100644 index 0000000000000000000000000000000000000000..781a0e4e82fcf4c9b84c60fd937f802c7d95d075 GIT binary patch literal 308 zcmV-40n7f0P)VqLK;)0vC@DbVg43oVMz%2 z7&yg+`@5XOxmF{9Bpm~1woibTq?x2w+c&^_Q50H9k`6FPLR|pObCN-l&NA#JnJ!&i zSJNcDy44mi-V)XwjgzzsNqwNZI>`C}UE6&F&%o&}Sdwgyoa9?ldsi%JR@(mE14`1o z0ABWyz^IUPxevB|tt16-$8H${|6eUhm1MF>EOz{uq-yqm1pI7(Q{Vz9YgYn?l5Qm( zEFSulbY*)Ysgm>syxD%TJ#WrkN;;SHA?ZQV(Dwbd>-z&oP;ZyeIqOUS0000%cy+2eg10@C@7l7ZEWjJB664C+f)gjPf_>uV2-xKg2S_yi-t7 zdrQa#Jr&eW4Y{C`0Ed-BS&VL|Przo)fR_Yltk6Lt;cLfrc}#%83ISQDJHQ>Vwxs+4 zv;k0$YOL`1N1S@Opg66Px762v#CP>f-Tm&S>Nd~^ntAOFI0epujlA{%+(yK>JctxH j0PcYdxCXMhCtJZMJxP=;#ts%#00000NkvXXu0mjfm~41M literal 0 HcmV?d00001 diff --git a/resources/layouts/layout.xml b/resources/layouts/layout.xml new file mode 100644 index 0000000..8064b73 --- /dev/null +++ b/resources/layouts/layout.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/resources.xml b/resources/resources.xml new file mode 100644 index 0000000..3aff0ff --- /dev/null +++ b/resources/resources.xml @@ -0,0 +1,27 @@ + + + + true + false + 0 + + + + Show heart rate graph and cur/min/max values + Show digital time + Digital time offset (integer, +-24) + + + + + + + + + + + + + + + diff --git a/resources/strings/strings.xml b/resources/strings/strings.xml new file mode 100644 index 0000000..67cc5dd --- /dev/null +++ b/resources/strings/strings.xml @@ -0,0 +1,3 @@ + + SnapshotWatch + diff --git a/source/SnapshotWatchApp.mc b/source/SnapshotWatchApp.mc new file mode 100644 index 0000000..79db8ed --- /dev/null +++ b/source/SnapshotWatchApp.mc @@ -0,0 +1,22 @@ +using Toybox.Application as App; + +class SnapshotWatchApp extends App.AppBase { + + function initialize() { + AppBase.initialize(); + } + + // onStart() is called on application start up + function onStart(state) { + } + + // onStop() is called when your application is exiting + function onStop(state) { + } + + // Return the initial view of your application here + function getInitialView() { + return [ new SnapshotWatchView() ]; + } + +} \ No newline at end of file diff --git a/source/SnapshotWatchView.mc b/source/SnapshotWatchView.mc new file mode 100644 index 0000000..5fa341d --- /dev/null +++ b/source/SnapshotWatchView.mc @@ -0,0 +1,547 @@ +using Toybox.Graphics as Gfx; +using Toybox.System as Sys; +using Toybox.Lang as Lang; +using Toybox.Math as Math; +using Toybox.Time as Time; +using Toybox.Time.Gregorian as Calendar; +using Toybox.WatchUi as Ui; +using Toybox.Application as App; +using Toybox.ActivityMonitor as ActMon; +using Toybox.SensorHistory as Sensor; +using Toybox.Activity as Activity; + +enum +{ + LAT, + LON +} + + +class SnapshotWatchView extends Ui.WatchFace { + + var usePreferences = true; + var showHeartRate = true; + var showDigitalTime = false; + var digitalTimeOffset = 0; + + var showSeconds = true; + var background_color = Gfx.COLOR_BLACK; + var width_screen, height_screen; + var hashMarksArray = new [60]; + + + //! Load your resources here + function onLayout(dc) { + + //get screen dimensions + width_screen = dc.getWidth(); + height_screen = dc.getHeight(); + + //get hash marks position + for(var i = 0; i < 60; i+=1) + { + hashMarksArray[i] = new [2]; + hashMarksArray[i][0] = (i / 60.0) * Math.PI * 2; + + if(i != 0 && i != 15 && i != 30 && i != 45) + { + hashMarksArray[i][1] = -85; + } + else + { + hashMarksArray[i][1] = -67; + } + } + + setLayout(Rez.Layouts.WatchFace(dc)); + } + + + //! Restore the state of the app and prepare the view to be shown + function onShow() { + } + + //! Update the view + function onUpdate(dc) { + + if (usePreferences) { + showHeartRate = Application.getApp().getProperty("showHeartRate"); + showDigitalTime = Application.getApp().getProperty("showDigitalTime"); + digitalTimeOffset = Application.getApp().getProperty("digitalTimeOffset"); + } + + if (showDigitalTime) + { + if (digitalTimeOffset != null && digitalTimeOffset <= 24 && digitalTimeOffset >= -24) { + digitalTimeOffset = digitalTimeOffset.toNumber(); + } + else + { + digitalTimeOffset = 0; + } + } + + var clockTime = Sys.getClockTime(); + + // Clear screen + dc.setColor(background_color, Gfx.COLOR_WHITE); +// dc.setColor(Gfx.COLOR_DK_GRAY, Gfx.COLOR_DK_GRAY); + dc.fillRectangle(0,0, width_screen, height_screen); + + var heartNow = 0; + var heartMin = 0; + var heartMax = 0; + + if (showHeartRate) + { + // Plot heart rate graph + var sample = Sensor.getHeartRateHistory( {:order=>Sensor.ORDER_NEWEST_FIRST} ); + if (sample != null) + { + if (sample.getMin() != null) + { heartMin = sample.getMin(); } + + if (sample.getMax() != null) + { heartMax = sample.getMax(); } + + var heart = sample.next(); + if (heart.data != null) + { heartNow = heart.data; } + + dc.setColor(Gfx.COLOR_DK_GREEN, Gfx.COLOR_TRANSPARENT); + + var maxSecs = 14355;//14400; //4 hours + var totHeight = 44; + var totWidth = 165; + var binPixels = 1; + + var totBins = Math.ceil(totWidth / binPixels).toNumber(); + var binWidthSecs = Math.floor(binPixels * maxSecs / totWidth).toNumber(); + + var heartSecs; + var heartValue = 0; + var secsBin = 0; + var lastHeartSecs = sample.getNewestSampleTime().value(); + var heartBinMax; + var heartBinMin; + + var finished = false; + + for (var i = 0; i < totBins; ++i) { + + heartBinMax = 0; + heartBinMin = 0; + + if (!finished) + { + //deal with carryover values + if (secsBin > 0 && heartValue != null) + { + heartBinMax = heartValue; + heartBinMin = heartValue; + } + + //deal with new values in this bin + while (!finished && secsBin < binWidthSecs) + { + heart = sample.next(); + if (heart != null) + { + heartValue = heart.data; + if (heartValue != null) + { + if (heartBinMax == 0) + { + heartBinMax = heartValue; + heartBinMin = heartValue; + } + else + { + if (heartValue > heartBinMax) + { heartBinMax = heartValue; } + + if (heartValue < heartBinMin) + { heartBinMin = heartValue; } + } + } + + // keep track of time in this bin + heartSecs = lastHeartSecs - heart.when.value(); + lastHeartSecs = heart.when.value(); + secsBin += heartSecs; + +// Sys.println(i + ": " + heartValue + " " + heartSecs + " " + secsBin + " " + heartBinMin + " " + heartBinMax); + } + else + { + finished = true; + } + + } // while secsBin < binWidthSecs + + if (secsBin >= binWidthSecs) + { secsBin -= binWidthSecs; } + + // only plot bar if we have valid values + if (heartBinMax > 0 && heartBinMax >= heartBinMin) + { + var height = ((heartBinMax+heartBinMin)/2-heartMin*0.9) / (heartMax-heartMin*0.9) * totHeight; + var xVal = (width_screen-totWidth)/2 + totWidth - i*binPixels -2; + var yVal = height_screen/2+28 + totHeight - height; + + dc.fillRectangle(xVal, yVal, binPixels, height); + +// Sys.println(i + ": " + binWidthSecs + " " + secsBin + " " + heartBinMin + " " + heartBinMax); + } + + } // if !finished + + } // loop over all bins + + } // if sample != null + + } + + // First draw hash marks the analogue time hands + drawHashMarks(dc); + drawHands(dc, clockTime.hour, clockTime.min, clockTime.sec); + + if (showHeartRate) + { + // Now show HR information (calculated above) + dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT); + + if (heartNow == 0) + { dc.drawText(width_screen/2, height_screen/2 + 20, Gfx.FONT_SMALL, "-- bpm", Graphics.TEXT_JUSTIFY_CENTER|Graphics.TEXT_JUSTIFY_VCENTER); } + else + { dc.drawText(width_screen/2, height_screen/2 + 20, Gfx.FONT_SMALL, Lang.format("$1$ bpm", [heartNow]), Graphics.TEXT_JUSTIFY_CENTER|Graphics.TEXT_JUSTIFY_VCENTER); } + + var heartMinMaxString; + if (heartMin == 0 || heartMax == 0) + { heartMinMaxString = "-- / -- bpm"; } + else + { heartMinMaxString = Lang.format("$1$ / $2$ bpm", [heartMin, heartMax]); } + dc.drawText(width_screen/2, height_screen - 19, Gfx.FONT_SMALL, heartMinMaxString, Graphics.TEXT_JUSTIFY_CENTER); + + } + + // Date + dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT); + drawDate(dc); + + // Digital time + if (showDigitalTime) + { + dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT); + drawDigitalTime(dc, clockTime); + } + + // BT, alarm, notification, and do not disturb icons + if (Sys.getDeviceSettings().phoneConnected) + { + dc.drawBitmap(39, 6, Ui.loadResource(Rez.Drawables.BluetoothIcon)); + } + + if (Sys.getDeviceSettings().alarmCount > 0) + { + dc.drawBitmap(25, 23, Ui.loadResource(Rez.Drawables.AlarmIcon)); + } + + if (Sys.getDeviceSettings().doNotDisturb) + { + dc.drawBitmap(10, 49, Ui.loadResource(Rez.Drawables.MuteIcon)); + } + + if (Sys.getDeviceSettings().notificationCount > 0) + { + var offset = 0; + if (Sys.getDeviceSettings().notificationCount >= 10) + { + offset = 6; + } + + dc.drawText(width_screen/2+16+offset, 7, Gfx.FONT_SMALL, Sys.getDeviceSettings().notificationCount, Graphics.TEXT_JUSTIFY_RIGHT|Graphics.TEXT_JUSTIFY_VCENTER); + dc.drawBitmap(width_screen/2+18+offset, 2, Ui.loadResource(Rez.Drawables.NotificationIcon)); + } + + // Battery + var systemStats = Sys.getSystemStats(); + var battery = systemStats.battery; + + var offset = 0; + if (battery == 100) + { offset = 6; } + + dc.drawText(width_screen/2-33-offset, 7, Gfx.FONT_SMALL, Lang.format("$1$%", [battery.format("%2d")]), Graphics.TEXT_JUSTIFY_LEFT|Graphics.TEXT_JUSTIFY_VCENTER); + + // Steps + var stepsInfo = ActMon.getInfo(); + var steps = stepsInfo.steps; + var goal = stepsInfo.stepGoal; + dc.drawText(width_screen-4, height_screen/2 - 14, Gfx.FONT_SMALL, steps, Graphics.TEXT_JUSTIFY_RIGHT|Graphics.TEXT_JUSTIFY_VCENTER); + dc.drawText(width_screen-4, height_screen/2 + 11, Gfx.FONT_SMALL, goal, Graphics.TEXT_JUSTIFY_RIGHT|Graphics.TEXT_JUSTIFY_VCENTER); + + // Sunrise & sunset + dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT); + drawSunriseSunset(dc); + + } + + + //! The user has just looked at their watch. Timers and animations may be started here. + function onExitSleep() { + showSeconds = true; + } + + + //! Terminate any active timers and prepare for slow updates. + function onEnterSleep() { + showSeconds = false; + requestUpdate(); + } + + + //! Draw the watch hand + function drawHand(dc, angle, whichHand, width, handColour) + { + dc.setColor(handColour, Gfx.COLOR_TRANSPARENT); + + var length, r1, r2, r3, r4, deflect1, deflect2; + + var centerX = width_screen/2; + var centerY = height_screen/2; + + if (whichHand == 0) //hour hand + { + length = 0.6*centerX; + r1 = 0.0*length; + r2 = 0.39*length; + r3 = 0.49*length; + r4 = 1.1*length; + deflect1 = 0.10*width; + deflect2 = 0.08*width; + } + else //minute hand + { + length = 1.0*centerX; + r1 = 0.0*length; + r2 = 0.37*length; + r3 = 0.47*length; + r4 = 1.2*length; + deflect1 = 0.10*width; + deflect2 = 0.08*width; + } + + var coords = [ + [centerX + r1 * Math.sin(angle) , centerY - r1 * Math.cos(angle)], + [centerX + r2 * Math.sin(angle+deflect1) , centerY - r2 * Math.cos(angle+deflect1)], + [centerX + r3 * Math.sin(angle+deflect2) , centerY - r3 * Math.cos(angle+deflect2)], + [centerX + r4 * Math.sin(angle) , centerY - r4 * Math.cos(angle)], + [centerX + r3 * Math.sin(angle-deflect2) , centerY - r3 * Math.cos(angle-deflect2)], + [centerX + r2 * Math.sin(angle-deflect1) , centerY - r2 * Math.cos(angle-deflect1)], + [centerX + r1 * Math.sin(angle) , centerY - r1 * Math.cos(angle)] + ]; + + dc.fillPolygon(coords); + + } + + + function drawHands(dc, clock_hour, clock_min, clock_sec) + { + var hour, min, sec; + + // Draw the hour. Convert it to minutes and compute the angle. + hour = ( ( ( clock_hour % 12 ) * 60 ) + clock_min ); // hour = 2*60.0; + hour = hour / (12 * 60.0) * Math.PI * 2; + drawHand(dc, hour, 0, 2.0, Gfx.COLOR_DK_BLUE); + drawHand(dc, hour, 0, 1.6, Gfx.COLOR_LT_GRAY); + + // Draw the minute + min = ( clock_min / 60.0); // min = 40/60.0; + min = min * Math.PI * 2; + drawHand(dc, min, 1, 1.2, Gfx.COLOR_DK_BLUE); + drawHand(dc, min, 1, 1.0, Gfx.COLOR_LT_GRAY); + + // Draw the seconds (use hash graphic here) + if(showSeconds){ + sec = ( clock_sec / 60.0) * Math.PI * 2; + drawHash(dc, sec, width_screen/2, 4, 25, Gfx.COLOR_DK_BLUE); + drawHash(dc, sec, width_screen/2, 2, 25, Gfx.COLOR_LT_GRAY); + } + + // Draw the inner circle + dc.setColor(Gfx.COLOR_DK_GRAY, background_color); + dc.fillCircle(width_screen/2, height_screen/2, 6); + dc.setColor(background_color,background_color); + dc.drawCircle(width_screen/2, height_screen/2, 6); + dc.fillCircle(width_screen/2, height_screen/2, 2); + } + + + function drawHash(dc, angle, length, width, overheadLine, handColour) + { + dc.setColor(handColour, Gfx.COLOR_TRANSPARENT); + + var centerX = width_screen/2; + var centerY = height_screen/2; + + var result = new [4]; + var cos = Math.cos(angle); + var sin = Math.sin(angle); + + var coords = [ + [-(width/2), 0 + overheadLine], + [-(width/2), -length], + [width/2, -length], + [width/2, 0 + overheadLine] + ]; + + for (var i = 0; i < 4; i += 1) + { + var x = (coords[i][0] * cos) - (coords[i][1] * sin); + var y = (coords[i][0] * sin) + (coords[i][1] * cos); + result[i] = [ centerX + x, centerY + y]; + } + + dc.fillPolygon(result); + + } + + + //! Draw the hash mark symbols + function drawHashMarks(dc) + { + + for(var i = 0; i < 60; i += 5) + { + if(i != 30) + { + if(i != 0 && i != 15 && i != 45) + { + drawHash(dc, hashMarksArray[i][0], 110, 3, hashMarksArray[i][1], Gfx.COLOR_WHITE); + } else { + drawHash(dc, hashMarksArray[i][0], 110, 5, hashMarksArray[i][1], Gfx.COLOR_WHITE); + } + } + + if(!showHeartRate && i == 30) + { + drawHash(dc, hashMarksArray[i][0], 110, 5, hashMarksArray[i][1], Gfx.COLOR_WHITE); + } + } + } + + + function drawDate(dc) + { + var info = Calendar.info(Time.now(), Time.FORMAT_LONG); + var dateStr = Lang.format("$1$ $2$ $3$", [info.day_of_week, info.month, info.day]); + + if (showDigitalTime) + { + dc.drawText(width_screen/2, height_screen/2 - 60, Gfx.FONT_MEDIUM, dateStr, Gfx.TEXT_JUSTIFY_CENTER); + } + else + { + dc.drawText(width_screen/2, height_screen/2 - 55, Gfx.FONT_MEDIUM, dateStr, Gfx.TEXT_JUSTIFY_CENTER); + } + } + + + function drawDigitalTime(dc, clockTime) + { + + var offsetHour = clockTime.hour + digitalTimeOffset; + + if (offsetHour > 23) + { + offsetHour -= 24; + } + else if (offsetHour < 0) + { + offsetHour += 24; + } + + var ampm = "am"; + if (offsetHour >= 12) + { + ampm = "pm"; + } + + var timeString = Lang.format("$1$:$2$$3$", [to12hourFormat(offsetHour), clockTime.min.format("%02d"), ampm]); + dc.drawText(width_screen/2, height_screen/2 - 30, Gfx.FONT_SMALL, timeString, Gfx.TEXT_JUSTIFY_CENTER|Graphics.TEXT_JUSTIFY_VCENTER); + + } + + + function drawSunriseSunset(dc) + { + var sc = new SunCalc(); + var lat; + var lon; + + var loc = Activity.getActivityInfo().currentLocation; + if (loc == null) + { + lat = App.getApp().getProperty(LAT); + lon = App.getApp().getProperty(LON); + } + else + { + lat = loc.toDegrees()[0] * Math.PI / 180.0; + App.getApp().setProperty(LAT, lat); + lon = loc.toDegrees()[1] * Math.PI / 180.0; + App.getApp().setProperty(LON, lon); + } + +// lat = -37.81400 * Math.PI / 180.0; +// lon = 144.96332 * Math.PI / 180.0; + + if(lat != null && lon != null) + { + var ampm; + var timeString; + + var now = new Time.Moment(Time.now().value()); + var sunrise_moment = sc.calculate(now, lat.toDouble(), lon.toDouble(), SUNRISE); + var sunset_moment = sc.calculate(now, lat.toDouble(), lon.toDouble(), SUNSET); + + var timeInfoSunrise = Calendar.info(sunrise_moment, Time.FORMAT_SHORT); + var timeInfoSunset = Calendar.info(sunset_moment, Time.FORMAT_SHORT); + + ampm = "a"; + if (timeInfoSunrise.hour >= 12) + { + ampm = "p"; + } + + timeString = Lang.format("$1$:$2$$3$", [to12hourFormat(timeInfoSunrise.hour), timeInfoSunrise.min.format("%02d"), ampm]); + dc.drawText(3, height_screen/2 - 14, Gfx.FONT_SMALL, timeString, Gfx.TEXT_JUSTIFY_LEFT|Graphics.TEXT_JUSTIFY_VCENTER); + + ampm = "a"; + if (timeInfoSunset.hour >= 12) + { + ampm = "p"; + } + + timeString = Lang.format("$1$:$2$$3$", [to12hourFormat(timeInfoSunset.hour), timeInfoSunset.min.format("%02d"), ampm]); + dc.drawText(3, height_screen/2 + 11, Gfx.FONT_SMALL, timeString, Gfx.TEXT_JUSTIFY_LEFT|Graphics.TEXT_JUSTIFY_VCENTER); + + } + + } + + + function to12hourFormat(hour) + { + var hour12 = hour % 12; + if (hour12 == 0) { + hour12 = 12; + } + + return hour12; + } + +} + diff --git a/source/SunCalc.mc b/source/SunCalc.mc new file mode 100644 index 0000000..ededba6 --- /dev/null +++ b/source/SunCalc.mc @@ -0,0 +1,110 @@ +using Toybox.Math as Math; +using Toybox.Time as Time; + +enum { + NIGHT_END, + NAUTICAL_DAWN, + DAWN, + BLUE_HOUR_AM, + SUNRISE, + SUNRISE_END, + GOLDEN_HOUR_AM, + NOON, + GOLDEN_HOUR_PM, + SUNSET_START, + SUNSET, + BLUE_HOUR_PM, + DUSK, + NAUTICAL_DUSK, + NIGHT, + NUM_RESULTS +} + +class SunCalc { + + hidden const PI = Math.PI, + RAD = Math.PI / 180.0, + PI2 = Math.PI * 2.0, + DAYS = Time.Gregorian.SECONDS_PER_DAY, + J1970 = 2440588, + J2000 = 2451545, + J0 = 0.0009; + + hidden const TIMES = [ + -18 * RAD, + -12 * RAD, + -6 * RAD, + -4 * RAD, + -0.833 * RAD, + -0.3 * RAD, + 6 * RAD, + null, + 6 * RAD, + -0.3 * RAD, + -0.833 * RAD, + -4 * RAD, + -6 * RAD, + -12 * RAD, + -18 * RAD + ]; + + var lastD, lastLng; + var n, ds, M, sinM, C, L, sin2L, dec, Jnoon; + + function initialize() { + lastD = null; + lastLng = null; + } + + function fromJulian(j) { + return new Time.Moment((j + 0.5 - J1970) * DAYS); + } + + function round(a) { + if (a > 0) { + return (a + 0.5).toNumber().toFloat(); + } else { + return (a - 0.5).toNumber().toFloat(); + } + } + + // lat and lng in radians + function calculate(moment, lat, lng, what) { + var d = moment.value().toDouble() / DAYS - 0.5 + J1970 - J2000; + if (lastD != d || lastLng != lng) { + n = round(d - J0 + lng / PI2); +// ds = J0 - lng / PI2 + n; + ds = J0 - lng / PI2 + n - 1.1574e-5 * 68; + M = 6.240059967 + 0.0172019715 * ds; + sinM = Math.sin(M); + C = (1.9148 * sinM + 0.02 * Math.sin(2 * M) + 0.0003 * Math.sin(3 * M)) * RAD; + L = M + C + 1.796593063 + PI; + sin2L = Math.sin(2 * L); + dec = Math.asin( 0.397783703 * Math.sin(L) ); + Jnoon = J2000 + ds + 0.0053 * sinM - 0.0069 * sin2L; + lastD = d; + lastLng = lng; + } + + if (what == NOON) { + return fromJulian(Jnoon); + } + + var x = (Math.sin(TIMES[what]) - Math.sin(lat) * Math.sin(dec)) / (Math.cos(lat) * Math.cos(dec)); + + if (x > 1.0 || x < -1.0) { + return null; + } + + var ds = J0 + (Math.acos(x) - lng) / PI2 + n - 1.1574e-5 * 68; + + var Jset = J2000 + ds + 0.0053 * sinM - 0.0069 * sin2L; + if (what > NOON) { + return fromJulian(Jset); + } + + var Jrise = Jnoon - (Jset - Jnoon); + + return fromJulian(Jrise); + } +}