ZWI?vU0=PYdcpSX_2)}|{bp=EQ?xE1^v#6L7nu5(R8o!1Q!Uey zlXa8Q%nfx-3@lT1lZ?|$bd!?Pl8us$)6C4w(k3^tuHZ2+H#amkFgGzbH!+=T##YE> z5CV_ojch7N+|Bpd#8^~-%8XJilTvgIEG!IkO)OKBbS(`GO?6XE&CJYA&CE?KED|Rd zaCl8_;9_G1Czj25+<6>!>+Vil2uw_DN#5=*4F5rJ!QSPQfg+p*9+AZi40_5S%viD1 zz6>bHUgGKN%Kn0xi&s*voO9jf$xcd2>pU|M~&y0^njP|&7fW@6l_t2SQ_ zym;IBqU=J)jtr;Vm(?ATgS$2pB)Q|DJj4n-juX4d3#!j@<8Ax$1xhi_smPmiNya sWqVat?9G{Q>q%eOn_MNMhWpGh`7Um{Yy3PFfbM1RboFyt=akR{0812JcK`qY diff --git a/firmware/keira/src/apps/icons/battery_danger.h b/firmware/keira/src/apps/icons/battery_danger.h index a36ea3d5..b7e13249 100644 --- a/firmware/keira/src/apps/icons/battery_danger.h +++ b/firmware/keira/src/apps/icons/battery_danger.h @@ -1,7 +1,7 @@ // This is a generated file, do not edit. // clang-format off #include -const uint16_t battery_danger_width = 32; +const uint16_t battery_danger_width = 16; const uint16_t battery_danger_height = 24; const uint16_t battery_danger[] = { 0xf81f, @@ -42,6 +42,10 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf81f, 0xf81f, + 0xf800, + 0xf800, + 0xf800, + 0xf800, 0xf81f, 0xf81f, 0xf81f, @@ -53,172 +57,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf81f, 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, 0xf800, 0xf800, 0xf800, @@ -232,6 +70,7 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf81f, 0xf81f, + 0xf81f, 0xf800, 0xf800, 0xf800, @@ -242,6 +81,11 @@ const uint16_t battery_danger[] = { 0xf800, 0xf800, 0xf800, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, 0xf800, 0xf800, 0xf800, @@ -254,12 +98,6 @@ const uint16_t battery_danger[] = { 0xf800, 0xf800, 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf81f, - 0xf81f, 0xf81f, 0xf81f, 0xf81f, @@ -274,28 +112,12 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, 0xf800, 0xf800, 0xf81f, 0xf81f, 0xf81f, 0xf81f, - 0xf81f, - 0xf800, 0xf800, 0xf800, 0x0000, @@ -306,20 +128,6 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, 0xf800, 0xf800, 0xf81f, @@ -328,14 +136,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf800, 0xf800, - 0xf800, - 0xf800, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, @@ -344,6 +144,14 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, + 0xf800, + 0xf800, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf800, + 0xf800, 0x0000, 0x0000, 0x0000, @@ -360,14 +168,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf800, 0xf800, - 0xf800, - 0xf800, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, @@ -376,6 +176,14 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, + 0xf800, + 0xf800, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf800, + 0xf800, 0x0000, 0x0000, 0x0000, @@ -392,14 +200,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf800, 0xf800, - 0xf800, - 0xf800, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, @@ -408,6 +208,14 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, + 0xf800, + 0xf800, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf800, + 0xf800, 0x0000, 0x0000, 0x0000, @@ -424,14 +232,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf800, 0xf800, - 0xf800, - 0xf800, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, @@ -440,6 +240,14 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, + 0xf800, + 0xf800, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf800, + 0xf800, 0x0000, 0x0000, 0x0000, @@ -454,8 +262,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf81f, 0xf81f, - 0xf81f, - 0xf800, 0xf800, 0xf800, 0x0000, @@ -466,12 +272,14 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xf800, + 0xf800, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf800, + 0xf800, 0x0000, 0x0000, 0x0000, @@ -486,8 +294,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf81f, 0xf81f, - 0xf81f, - 0xf81f, 0xf800, 0xf800, 0x0000, @@ -498,12 +304,14 @@ const uint16_t battery_danger[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xf800, + 0xf800, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf81f, + 0xf800, + 0xf800, 0x0000, 0x0000, 0x0000, @@ -518,11 +326,6 @@ const uint16_t battery_danger[] = { 0xf81f, 0xf81f, 0xf81f, - 0xf81f, - 0xf81f, - 0xf800, - 0xf800, - 0xf800, 0xf800, 0xf800, 0xf800, @@ -535,27 +338,11 @@ const uint16_t battery_danger[] = { 0xf800, 0xf800, 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf81f, 0xf81f, 0xf81f, 0xf81f, 0xf81f, 0xf81f, - 0xf81f, - 0xf800, - 0xf800, - 0xf800, 0xf800, 0xf800, 0xf800, @@ -566,177 +353,6 @@ const uint16_t battery_danger[] = { 0xf800, 0xf800, 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf800, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, - 0xf81f, 0xf81f, 0xf81f, 0xf81f, diff --git a/firmware/keira/src/apps/icons/battery_danger.png b/firmware/keira/src/apps/icons/battery_danger.png index 5c89db5c446513a14e8e4b5241a8f318bd4a4667..e4094f1a9b4c6dc911025c35bb244d198c226e6f 100644 GIT binary patch delta 698 zcmZ3bxkOX3Gr-TCmrII^fq{Y7)59eQNDBb51P2?C{Jfx+XQHAMqrgO)U`D2i6P$T< z7#SFVhyhGbd?3YXq+n=jWo&L`Jeir%ibYYXGiI_Qqaxc QTjd9wuO`ne#CT+ZP*o%L2*GfTu;p3sc%WD+hZ#-4my*Vs< z!#UfZ+=pFjQ)j+5ai4fhX_|s#OB36w`V|M=n!@Iaa7W(q|M|l`X1|MGYfPv?k z-c7IB|2N;i8?|($r@rPKreE XS39Bu1g|bst^A5>|4pebC;<(J1&22?HoG>%U4>(%rY`e zkHu3@#eJ{*?vS7Vf8NV4- g-DFEk6Z0gaR6|o!gUL;-D|n1d4b038Oiav8%`7LIu@!O}g}?%S1Dh&>xA`8M zIE#v@QF5A5s;Pypv7wQfu8DD?p{|8-nz^oFnt76OVv?b8s!8JH0uC>3Lzpop2AlJ^ z^Em9{X4NeP#xGlvx4R3F27;f?yX%1zXMsm#F$061G6*wPEVVBK3bL1Y`ns~eVCLaf z)p(~Zn>krZL?g-9)5S5w;`H0e2l*HbSe!%u{MRr4KC{QO>`~i_>0ALGnJr$%I(dnw zBNZJsJ>w`~Y+HQs&xgv1PaTrgZ-q-V3Q9CSkpAfxAeriN;J=(susD~+{HN?SAg6e` L`njxgN@xNADNFSm delta 702 zcmZ3Yxk^*9Gr-TCmrII^fq{Y7)59eQNGkxb1P2?CoE`k%WTK)Jqrya+U`FPN6P$Vf zXfiNF17*PU#0OHG1`39zRz@aPMw6KttynBp)OSyIWK?8x)zsxH)0mvW7+lZ1o 1(eg z%&q<;-q!u=l+pFfKBZn)9mggPR^E{Mz~)|-wN{#9o3_mV^s#?OU1to}&Q%FdA{=C; zQm*s=W8c4ft5@*kxF8GGFZ(Ud9hWfJz`bR5-{;yl7H@?We(=P+jIH0xdZupDy*F7O zl@l_gckFnVbxN*aC-aecJU6GrYI+1~Ol|mX{A(GLK@E4ywLSN&ep}Qs6kQ2@#%5u` za!ma6l)djhzdLyE-ap&RFW<9UtSstZHAA*(^980pCKa>P6qD4HBokeuRP!WV6N{u2 zU5k_?OI@I#Sz4lDim{P-^5iDg6+8y!<_2b#rWVG=#zvFP*a|rfLSO;EflU>`+kB5r zoJGYrDJjh~#l%9_%+k +const uint16_t ram_width = 24; +const uint16_t ram_height = 24; +const uint16_t ram[] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}; +// clang-format on diff --git a/firmware/keira/src/apps/icons/ram.png b/firmware/keira/src/apps/icons/ram.png new file mode 100644 index 0000000000000000000000000000000000000000..e7f26dee84d1e27d7c01c521663660375428769d GIT binary patch literal 4553 zcmeHLe{dAl9p6hLq}K!ys8T`L*-#pYd%L&0celH}1HxUBTjA(6xnhVFySMu`*(P_p zx!cQKLV-*atkVuy#ZhalOpCOlrGryOG^60u0BvJ+##aBZSOg0=)xlIMIJKqU-Mjpn zI@8It{Fl9X_rCky_xpL@@8^BrcW>{$_=cux_swn$!>Xldq#62!cB`BP->37TE6}}; zS|v@AR$`TK1DdW1%w_99b4`-VT;*6fjO~Or4`f@%Za2HGbNU~Eyr?Aa0lBuMW7~LL zWmq-zgU}d|7eIdintpF_t(QQyuS(}*J2e~HSl=YY;yB~+(jL|i_B6wZG%I=;-0Kq= z5PYz{Ywv_dHqvOdFAo0Qt%t*LDICVljG^gW2*V14TYnge{(8;g;k#O%B*-}%=XRfr zKmNg)n|8JBAQF{_*FHUG`NP}lAKbZYc=#J8$zM6tnlroK{Nu~toLjMa&EPGA3+~+a z%GIyzxY4_0@#V9pUOaK?Yil|Zk7&79%YKx8?0t3Z$hnQfuh$J!)(p7T|7L_aw`|3A ze;&>4#_qa!CiuIne|nd!PC ztXp!l+w;P$AC3I{QR%h$P4^8aXV={_a@+pKptQKf_xRs-Jab~@dGhydPabc({2o Lm+*`n^YT=T8_^wsa4U7Gplyyq8W9(wuYq5hTJ$%9Kj zyM9}~^GnN*zqrpVyRfZ$aQ6-PufE9rb=SvRKj2@Tk6)?!*88dLhg~DzePFZEd8lTu zvFON=bmwoEn9rA2t@`q_D~6iy-yg5VF1BBa345>Jc;U{E`#L{7d&zY&e*064PM@B; zkZk_sh1Z6*h+F<~dHvHzmktIp&*^u(a|FZY+@U90t=8CjQ87{;Sv8W#Q%ITieqq7Y z1yfc!k%cEwyPgga7l)1#xUPnX+kG)QW` |n5r5kD7#*~vr z&I%C(%;RJJrOa4t96p^bu>gEf1=*y$9-2y}sL2*ttDy%#N)COlMK;lEBB~i>ja)`S z4LvAr)l7y^m2rDBm+5lCQ56bxp%kcQVO8&xCG7(@Zedf uM00;wR@M{)}9Ck4OPPb#cmO(s>I zqy54ph_7dK$V$0uvR5{g3Q&y9COJm-lS!n4H=I``WtNdipP+EOf@C(J@eY)#h>b=j zCBt^=DY+d{X1d*(un8CI<5GxVJoLm!yi2w;FbEOr^>nT WD J zj*}`|azwTefR2~p#8?@wqZyGdx^Kh93{}^9|C_dbc<> 8mQ3+gW3 z6>qzA=P2R0b0|bvDTa`hdywk*30TD`r9)1)Bd8vwbR8SlKQ9$%FAd!Bq|9ppk`w48 z$@?^x {~f#LZ8$!fCZ^D11D_Mxdx|L-B%k7obW5QCIm z7RNR RCu4yqaE#;Z)`oGcTo_J$KY51X+hxft8#4p~2cgb1FbxjfHtrGh*JhUC8FPPCy zS@;j+ExWna);?B%!P%A+YnXkZysG-9xpkXH?LRi|ks|ep=!p;ayzM@QSB2+~UfnKi zxqr@cy-M4{k%8;opDcWP4_0yFdl>#H9bMj^+PE_$9uxeh@5ZF_2Xe G_1)Y0?z#hQx1HL0Y~N }(l}$C(hoAb{K>25Ebookd&5#{|)UY9PaP7AT{tfqq0*(Lx literal 0 HcmV?d00001 diff --git a/firmware/keira/src/apps/icons/wifi_0.h b/firmware/keira/src/apps/icons/wifi_0.h index a0a90362..c43888d5 100644 --- a/firmware/keira/src/apps/icons/wifi_0.h +++ b/firmware/keira/src/apps/icons/wifi_0.h @@ -35,6 +35,16 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -47,6 +57,8 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, + 0xffff, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -57,6 +69,8 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, + 0xffff, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -65,22 +79,8 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xffff, + 0xffff, 0x0000, 0x0000, 0x10a2, @@ -95,14 +95,14 @@ const uint16_t wifi_0[] = { 0x1082, 0x0020, 0x0000, + 0xffff, + 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xffff, 0x0000, 0x0020, 0x18e3, @@ -121,11 +121,11 @@ const uint16_t wifi_0[] = { 0x18e3, 0x0020, 0x0000, + 0xffff, 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, + 0xffff, 0x0020, 0x18e3, 0x2945, @@ -146,11 +146,11 @@ const uint16_t wifi_0[] = { 0x2945, 0x18e3, 0x0020, + 0xffff, 0x0000, 0x0000, 0x0000, - 0x0861, - 0x2124, + 0xffff, 0x2945, 0x2945, 0x2945, @@ -169,12 +169,12 @@ const uint16_t wifi_0[] = { 0x2945, 0x2945, 0x2945, - 0x2124, - 0x0841, + 0xffff, 0x0000, 0x0000, - 0x18e3, - 0x2945, + 0x0000, + 0x0000, + 0xffff, 0x2945, 0x2945, 0x2104, @@ -193,13 +193,13 @@ const uint16_t wifi_0[] = { 0x2104, 0x2945, 0x2945, - 0x2945, - 0x18e3, + 0xffff, 0x0000, 0x0000, - 0x18e3, - 0x2945, - 0x2945, + 0x0000, + 0x0000, + 0x0000, + 0xffff, 0x18c3, 0x0000, 0x0861, @@ -216,15 +216,15 @@ const uint16_t wifi_0[] = { 0x0841, 0x0000, 0x18c3, - 0x2945, - 0x2945, - 0x18e3, + 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xffff, + 0x0000, 0x18c3, 0x2945, 0x2945, @@ -240,6 +240,7 @@ const uint16_t wifi_0[] = { 0x2945, 0x10a2, 0x0000, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -247,8 +248,7 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x10a2, + 0xffff, 0x2945, 0x2945, 0x2945, @@ -263,7 +263,7 @@ const uint16_t wifi_0[] = { 0x2945, 0x2945, 0x2945, - 0x10a2, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -272,8 +272,8 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x18e3, - 0x2945, + 0x0000, + 0xffff, 0x2945, 0x2945, 0x10a2, @@ -286,8 +286,7 @@ const uint16_t wifi_0[] = { 0x10a2, 0x2945, 0x2945, - 0x2945, - 0x18e3, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -298,6 +297,7 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, + 0xffff, 0x0000, 0x0000, 0x0861, @@ -310,6 +310,7 @@ const uint16_t wifi_0[] = { 0x0841, 0x0000, 0x0000, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -321,8 +322,7 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, + 0xffff, 0x10a2, 0x2945, 0x2945, @@ -333,6 +333,7 @@ const uint16_t wifi_0[] = { 0x2945, 0x2945, 0x10a2, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -345,8 +346,7 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, + 0xffff, 0x18e3, 0x2945, 0x2945, @@ -357,6 +357,7 @@ const uint16_t wifi_0[] = { 0x2945, 0x2945, 0x18e3, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -370,6 +371,7 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -378,6 +380,7 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -393,16 +396,14 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xffff, 0x0000, 0x5acb, 0xad55, 0xad55, 0x5acb, 0x0000, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -419,14 +420,14 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, + 0xffff, 0x7bef, 0xffdf, 0xffff, 0xffff, 0xf7be, 0x7bef, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -444,13 +445,12 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0xe73c, 0xffff, 0xffff, 0xffff, 0xffff, - 0xe71c, + 0xffff, + 0xffff, 0x0000, 0x0000, 0x0000, @@ -469,12 +469,13 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffdf, + 0xffff, + 0xffff, + 0x0000, 0x0000, 0x0000, 0x0000, @@ -493,12 +494,10 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0xe73c, 0xffff, 0xffff, 0xffff, 0xffff, - 0xe71c, 0x0000, 0x0000, 0x0000, @@ -517,12 +516,12 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x7bef, - 0xf7be, + 0x0000, + 0x0000, + 0xffff, + 0xffff, 0xffff, 0xffff, - 0xf7be, - 0x7bef, 0x0000, 0x0000, 0x0000, @@ -542,10 +541,11 @@ const uint16_t wifi_0[] = { 0x0000, 0x0000, 0x0000, - 0x52aa, - 0xad55, - 0xad55, - 0x52aa, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0x0000, 0x0000, 0x0000, 0x0000, diff --git a/firmware/keira/src/apps/icons/wifi_0.png b/firmware/keira/src/apps/icons/wifi_0.png index dd4a2e78da2db2d1baf75506a48385469c451c91..a9a8c9d818e0d12e96e5c2fd88e1ba14ae7bf38d 100644 GIT binary patch literal 4705 zcmeHLdsGuw8czg85%958C}rz7;)>uTnaSien G2n6B!bZs{1qxm*`82D^;YaW8GiOJKO^!fzBaPR;u zg~0+LZv&dJpFBhuBnSe!m7t9UGH=7T7~xQV{|=B}>6X_6IlkM5_d$h21mU3H1{wzB zNYL*Eja?O(>nM=<*Kq%v4=Mz-o<2=)$bv8tDiKNLz+ZylghWc97=+3QiHwlR!2H4w z`y%3znuo6W0K~VPO-aepr=&o3ht0&A8G*pFt!%9({X|mq%Imu_bosGeP}{pz#ARKD z^4o;Ss^mQ{<+~(b{A1J>JZ_4}=PjzQ-|^MnWfcc%B5J(Q!=SdV){i^kN#z?O^G|y0 z?ooHj?liWzmp1K1&-^fR$QJ9?%Us6ksJUM?C3=TXOfE_`y^l`Tzx>d*@6F(c 0m*3EOI z8@EsPjjg!(>fA+}UYk{^oDrKN+y3_zhZ_<)kU!^F*AowJh{K}pZ(wRJ#HPel F?Dy+sC_}j{PFi@ml?<&zBPTshaUmMwLJKHo-8vRR5RArsr+S z@$E^4QH6?Mc09gR{N3cFyDuL)U;Av)$W2e iuT(4<$ghZEObWX`9 zkfADf$hEVbTSJfCMI?v*dcWG~yAT4U9r@E$LCC6O+Rgi$%dTmft{hxaL_B>gG@o{S zT$15E1#-~C=H_vEhFJt LffG*pEv9nOBQp$Zx_G zY2ZANM=3T31K}cEBtdi@wgiKxg+givZ6dO@sofCZNdp&hoShJh-EOzYEfv`u1!7dC zQi&y)7{d@?fjCR89O*%<&WSuk07J_-DF v*<>>=%9R3s5wEaLtiPEJ<>K)M6^Ne^dkshtsLGftb!K{2`##>!3X4?$DC{&ttc z>|YK|i5W9v0j5qcD>`6G{>1fq@DvoV7Q5dIkUhYXV@-Wz4Ty~&@h_);Ai%vBcYt-z z+Wp4B%3vV0Hp<0^r`Kv=etv?sQ7ldPMHxk^Xp>Qj;21_BxDitzDkH8yq$-t(Mokp0 zl&ktd>8(zVv{DQY1;9ltz%feXG_8_L5lTs#5S*4#2#HCh2uU#vqhKhd5;OLLnC)Oe zR+8raQSneTfRZa@CR&ae5eB6h1XoZDqM{WzB4cP&ssw@3@&FV~5vewZg#_ElTF3%M zY_}Hp=imt^W@PC#FeZ}pX|l{DX95lycou7QdHM!&SqqcHkvyBI0tFROsgTJODydST z=rfwjIGi98c}#!p^pEh{LV(2pVo5$v0f1i*) 7?QI&a&0!V2JWr8y~74@oM@6G zwIs&?(B3+n+f#=VB^V(IgwMknY&2^s{a@Dn;eph^9&C9!>jd+c`c;7wmBSPVo&t|% z)_;^B$bTpZk_s%rNtQ6QKTd!Z7@`VEYXJkQM|ZmR=-Ho01tlY+Nu!cPq>L0ra2z)w zN=zw1WGd8%GN=MKNdqMHqC0IS&P_U)83lkxz!gYO|2GsA@875?17mR)GW;$8!VrlR zL9zcNOx(R-F<&!!R;(8P7bj}JLBApc`~o^qyg)4!_ZGu$&Op3B=c{`!e$FW%XmFAj z;&+g)LAqXuffq6!%&tMYUWkDgG9JvX{~KMQeb*_*3VsE-!DVUQp|%Kc(Hdr)nWhyy z=ieV5*}V>EM%dHmJHhR&nQy}6_^lqG4B_+!T}Wq8Sol!IKX>EPz-{`OUOOW l_46C9jyRaP zJt5+oIZN*@tE#JwoYGLe{$KAviBBT( Tju1Q z@yBt4Xk+6{cmoT;@t=G)wc_=CX@AInTIh{`J8xgJduQ11j{a@v3CUgcsD|Q Mo|UfXhLfoSTuk%Ii{ah0h-7w{c*pEW#B(sn+0JayyD zAMO*?b4NDrZ^CciOw?akuk`&`wgY^q*Iaz#e*TTLD$Uswu9h|02=CG}rgguFPI`QA z)tE6cm8qgBh8$nRL^68p$_WkaYjK0~km wCnJd+vm;l zIT<&XBf57d)z(zp`ts5r%a)YXwxqweyv3RpshhpYHUdl9eW9ww8ui8mxU1yXi?54M zpS!mD!6nzZ_YPPdKZO?`tf~0=SzKCKN67rQ&J~`tD}xuxx1!rKXUdM*yvHZP*ydR` zI6^ @oLz5Lj*qx)Lq6|{c{Kf3p8fTs!aiMp>iO6@0Tlh} UnCoY&_& EX>4Tx04R}tkv&MmKpe$iQ^g_`1v7{^ zWN4l2q9Ts93Pq?8YK2xEOfLO`CM`*di=*ILaPVWX>fqw6tAnc`2!4P#J2)x2NQwVT z3N2zhIPS;0dyl(!fY7Wk-Rg-0x?!8?WJ1d3R;9jI1QCLWD1U|&X4U3oIR)SGb&mjF z?_xa5|J TzX znMuzRi^Ni~i`6b>B~vG!CXQ&jLHR<~V~z6`XT4Hq?R)YUhV#bCGS_L2A&EsSL52hs zb(B$ojTo&4DSsByw4d +gyR`~alU`Cd0rb8&&PNpJ z+XY$;$N4^XoYn~td tb0Jx~`+^I+~^dpp@e4 z>kBC*S(dR{t=Mk2m439JJrF{0e}7M>( pDRYU|Cje$5o*9 zdQB8XB}fBQx7+36;Q_-ijtq9Y9a)x<=Q%}Duz%TX05A*#Aq2f%4 ~!rYQh-cXv3BL#x#)eXQ4O!Z18; zvQmoGYQ=m$r`PK-7z_|X&}dW-oA3MNc}^V1e0+Qm1Oc{fAC*|EI%riJFV#LxQ=%xk zJb$LX@8dYm(c1S&?shxA2cq3>mzimrhU>a0rC2VP=K(^9qsTr#KTnJfgK=HA%=FOq zY>5tK+cvgsW142^XusdH*=$IXge=R>mhUXU^E^Dy`?VKJDUu{1Ns{aCqQj^wqti4@ z)4V=|n_hN5H6D){4u=3tr&C^EU+Z5XmubGIrza()RNu<;TumkuRmZj#U^bhnp9;h9 z?*K(noB)cVs0FC?qQ!B1vi95IyXwh&ett$uS^i5Yd3kxM1*koykB^UxMk4^;-`{zA ed;43!wfYC4c|yWTF2z3p0000 2$-I>}&g(b4Ym8S@l<}$m}3sbNUb_aGL zCn`P@E}TZ<1EL9HjAc$J^H8JlK{SVV>VaqZL=Yj0UZ~Sc&cd9JT+b{Z+@ ^@O zRB!im|Gr;;{p+v4+I~BA(SqQ>seuTB1RIkK>97tHigXP8?eyp$!KxKx8?8oT3?hXe z5GnCTBmxE&$&j|6WE3(A_N{{@1hxf?P^L;oi}mkd`{n+2HEc)qV+0#q;)evo`U6-9 z*basDK3KT*zPXOWw(v;BS8yr-mVtVK(UdA96gZ|(#X@_GAZbiR hD%6DH6|p;oGyozD+CDQ{b2bfebT9UVe4-0NlwfS@0E3JtfQ|b zR%$QDgx1CHos?UQef7`rHDpAzqN<{xsp-RS_pPq{ykT5Jh3wI&uHMewcjdFnw}$4P z_BuV|?=Qc9w%xO`bsv8IZ?F5+*lVxx$>%0#ecL*_LOL_PAl|wKk2FqsRMq&F|D*EB zJvq;cS5$4t{UU6_gts@J!)#r_UE57 K#9<{kl1(2mMR#{wBKbJ7v)1hwp=ii{S}VE3+&7 zCk9U4yKBtLMc0ed=dky5x4WkoKMnaR)U~+j%z>3Od8T3dlkw$!mt#yRrNKtv`2Z zr+3fGpPa9GrRVY0qU(|K9!xp>*Q3wMUfT9F;@GuI<^?BPW1U6qm#X!hu7I#og3T!T zSZ1or^y_H3TN`-t0g4^I^Kier>SBOw!LdKzKmyjEG;IIu%JL3 *V m%6uT@Su>{!pnL{a9%b>lp z*i|SlhqWj{A+SNH8_tRkn^HJ&gBF4Wd7RBDT0yagA$iXFT&!Wf2_xcihB^Yx2YH8~ z2i7ivA BnmK=L`e(AqFTmmMPoH;Ov9M9 zm_|(wp)%UtJY%;2feMl Y5E!MQ%qT?>EJ|9{7;2_SD~b^esWwwq65y&K6e%ta zMkP}?)GL9Cg;Z*dH5ONE0gA)qgpyhSP_xFWg?_PC) 58%CnQDdtYmT-X*GE(QwA2yqGt#D2III>7}P-r>r0I12T0fkMo>gTp3x zoLGiu3=9t->0lnt9LU47F@nZ??hAA#2g_MY{});~JTe``!!1wZ+;IL y-bciB1FzNixvR*9Vgq%!SIqWZ18nkam8>r++Vg#Tg*=$RsbM z?}%I@a=nlOF9aTmt`WIjNP!muk3`r1O|HP_*C}9!|AIX5vh?w|wbAgRHOBn<0t521 z@P2gclg+SatTQRc4R2>xgd&NLs`bLo0N!Xy47fWgD0qxtB~{-6Z__u8hWVLE&F8by z&hDBQs#j6t*!S28@rIUXM?3z7Uzi?P);r#?Y4p_hYHHklx9ZQ32io6lf9c1r8}7gB zr}b0?A-5{))V7c>KRqAz_zx#{93Fc$_BU^BJwr7+wQHELRx-F|k6yY#njF2fafu<# zf7z8yJ*Bo8C4DP5oD5rC9a4Wm+HUWgIXW%$mQ$+>Y(LPO_n~af%5E(dRIe^tR(JNc zU(1gh!IUry7~Syw7UWP{a9ZdLW5{mqojGR_Bwm^n&D6ZQyLv)=wX^p8oeS*#KXEm3 zsh|IRWQKpxsd 664!)(BUCN|^M>9cOUiS6CEBvj}5?ucT8^!WX5uP*Dz<>FVi00s+NiDwZ9 zzv(-2x99W(q^70ki#HnY{WdORXHRtx_0#c`PcOY={X7S~11`ly$amd#8Iz;SCMTw~ znh)g5BRkj*mf*-5chx=qx=vdA$A>q!?Rnx^Wpitfhd)W73+o@;obA2Bwc$Ukh}ye! i_4K7ly=^DZ6UgR&L@is_8)JaGj~Ejd85-i>toSz~+iwp5 delta 985 zcmV;~119{!B%273BYy#dX+uL$Nkc;*aB^>EX>4Tx04R}tkv&MmKpe$iQ^g_`2Qw6L z$WS}kMMWHI6^c+H)C#RSm|Xe=O URyS?p4dR(iyUux^SY%~IBR(gdFzJHCk6c$he&bwnS>TzX zna#`-i^Ni?ht(ctWm6}fCXQ;lLHR+gyS0i_lU`Cd3G}}>&c`?~ zunV-Cj`Mx&IPDW4_zYYbU4N|w%zl#I>}t^?V0at2xbAA|9&ot>M4sx3skl;*rcf*b z?`QN)d0^xg7+mvu>+Iw70mxEU=^NnS5Qvp1d)?>Vp%C8Q{yo#_?+1nWa;}hK_^*=@ z5Hf!V6ekbmg2gBR00J3FL_t(Y$F-HwYU)4`hQFjqRvM)tf~^-8pQ(k?*XUiZ>U*eo zErNZKLSG^ZTB#{$$fi-}TpSvX$25jg2lgV%%zT-de|HT)IH8%G*iH_xz9pL`zVG9@ zE|z6sSr&$203aglc007zL{Y?QwIWT^+&q8A|1(fZad~;k`T2R4@R*4RQ4}$o%?>~r zz_Kiw%_gqvmQI`pTCdm4=kp9?08*`1xw^W-w(Y%u&1ORsMZ|GTk|cb7ega_IHcBaK zwHivP+_)eJ&|3cmv|25y)oSLDBne>{5{4nRZR5Hwj^l84b_T$9yCqFi!Y~A&Uax=S zc^;1AWI5LBH9-*U4_QQ5tyWB@Q);yu?RFcb6sDOkwnn2t9LFpc3*O(~X*Qc&TwLt6 z*vLC*d5*_=ABG|G`TV#{8;u5@=k4u%NpiE<@Fj>!rIJ-<7zV!YBO<)Ly%htLQhR^4 zTrLlS0364`^E`at&no>lcCW&s_4t4ID6g-t^6~K@X_`u!rm|cv<>lo?9v&X#SbQO1 zFc`>gx0CN|yWL8^-!B9d-bL5f*M);NO_O%JT_^zK)Yr9D*75%So|~H+0G^+p84ic# zuaIM_)9HxTI_rHL$MW>_RA#_Z3NV>W4h9?q!S4Z*Bsl;iNm2?>>P1^D76(0hd57=E zPiD8 y} zT3XsFwME;io$lJD1!sM%b(B?GSnX;p) }(8q8sI1qeyd2|Dy>!6B^w9z ` zr7%Ds -k1pJ4vsf(im{xX(12av`Z0MZ_{C@JFO_43S}|6hajkqQqoUFu!o; zXha;+-x{OtgZS1ndVQ`@uZJ8?JIz=qfx!Fj>Nj;+pQpsse)s3>^y2uNQ1=_Vu#4$+ z>htp>ccpz4RqRF%-3{L+pEFNfUsHbk_>T6bm+SVmOlzru2K>8kc71q5G RYF-c-D0^p S9bMSokz5m;kXD{XZ$%T0u> KAYH33hB z#C`NZ;LM6k?z{zLpSHJWwtFz*P^9yj<0t>R4wIj3nf-J4ng{3So0e7?zmM#A(ygA| zlTsF4rkZvA(Ki*B5>sx+e){#{$JM`kXK+sI#ZGhPu@0r9;!0 9tGbTM2iKNkgO7xk)6Neo zvujR*9P}~;MQo8N2P5oOF;3del-O%^a2qDjF7i5XqMTwOGgZpibfQ~_kBT6M)QOfW zOo+*$r^=YDYA2Ony`+GsE+;gkXwkwDtrr6TR*J kmxcyWgW6(bU>RWjDY#imyRkfDHn)x%X#<)9>al*{gR5>$F6Wn&Y@LXgCWzr*dc z@XH|y31y+Iz|;k1MaNCaowyMXj)GFg>fpTq+2br(h8`trTx{G3znrmw0QV8xan{3Y z=Z%4t$%Gl~gqsV`XwZqc`7zQ?FeJu{gj}JLk(3%%qqGK=(@F)5BN`>FF_WZ%Rw_{$ zPLF{y+FUGdBPb3EfQuP`BSTTMiY8FtNXucl8I{4fMoq)CQbQ6XjVhD`ItF5?lL1+Y zTgFDkL6HDTp;XFf1x>@a5|zSor3yr&F)LsaM-_;MRFbrm;GswY%dk7GIM`0cikDIn zhpm(!;0VW3bB#KYRE&&jaxFMZ0|%Wbhq1Z6qXPwumC9#vj!jgBf{LhCX=I36Ayvyp zjS4BJ3uGdP$=6PPgxeMjECvvZb9o8?cs*DPrgu^}Yj+md?G~MAr0R|go4|1*aTYh= zECoPE>Ttnu9Zp817~%_`gEQGlhOYWw*4*KNw7?#0c^2aW^H=dI--*hnDtvFgR|~@* zB?#gV1%?y8CAjcPisa)2SiT{m47Zh1pn43Y>#&~rl~j BBG;6%$Cj43j}&!+>$3)Di%NHHAZ48;3eeunnqx10ikCMTH? zzms%L(lsFlCS*LBU6XW8h=B l9@J|AIW=vecS9s})?d0?msv4T2}! zv$J*g7ND8x$Xek7x3dde6Q(6?_X1@QYc!-S7_$3;g}Om0y1XZqw_GhSY+r6JKsc z>-$qeYmdgxjolRdQb5EjT>+XIif(O5P3@|V+}yJrsZk*rZy;@Zil$iar&jJwzWe^% z<;0^0_OEul>bG81+`%SwZ)k3KAt*P>mVNiN@Rd_uXpWt>p{*ikdO$$x?IcLlKz(tq zy1jUDWcs(ZgS%6jF1@sIXTxVPpO?u$IM=t|{Csn-L# }9#BeCip^CkINz(RZ}FlR^ZaA#E}GgO}T5^f9#uj{H#hsO(PP z<{!0*r=)uqB$)EA{ixaU#rl Dd<#>|JoSSS5Wjqf6Dp#4p?aoV>k%#~&X4qwK2X zp=#Dc EX>4Tx04R}tkv&MmKpe$iQ>8^J4h9r) z$WV2$i;6gE6^c+H)C#RSm|Xe=O&XFE7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx z6k5c3aNLh~_a1le0HI!Hy4^Jk=!RpZ5^*V$U6n$w2qFv-V}BS>m~GC Le(*o|-L0LUobZz(aiIIfbw5Uc z&@RxZx$gI|>o!h+;4^S#wEUGiF!M=zt))eefWB?u;<}}&d%)!mF!*FDmf}f4nnFGg zyr0oGWr6-%pl8kRt+|iW2Ov#dC2xR(LtwN(+3OwN9T9Ht?cX!a{(b<3`f{#sgdL2N z5fCze2oxv CZ*h5f zX&W9BNeCe@7z`XB8=$HxLZJ|RKA&sjU7-1Vj^S` %ufmR{&Qx+IT#6yc>;1r@Jz9xg4aF_Op}{`F!3L u!1ZsMN~Q4l_y_=~)oQ3#tEUD0uYLdqe@J1cSZU?}0000 _~e>jBdHva!Lh>UuOc`b%h>Erh-WxnWb7i#5v)UGoFXs4`qnMO85u~| zH`_Nrepjm=PnFN(A!1roQA5~bNo`(xtGn`*#f8^?wtZ=N!_2RVz71Q&qvf5#`wI%T zmOVVJA;Ikaaq>O<1@moP9nJgp-G5-mRh_%K&+6_V2D19T?%j5Ryl~xJ1r7UCvE=0b zwf(Pul3d@jgMH(xOD5bC*>qH2dU*QE13e2na_5vamnnC$bA2-gx}Lal;=sD;$LoJj zw0B+K@O0tXXWww!VJ6&{-?!2KQSS>YX5wk}7cQE6AOB^?{##bnmaIFrs-?bn C76(y+2&@!odZ{sW%%Q-zWb3U;51HKiz@5kIeKGb=GxE zoRU}c@B`WBt@$ufeUbcS$>+yrCr(b?U7%gI@6c20MgCCt?B6D@`}zF^{uQmh{}l9` z>Jw%kTii6g$@S0Uzy5p8hjSNyH{-c?p8vh=A9tU;V9(L_f)#svoUt{Zym!01SIa4E z<>Z={2MPbyz=TiVI #(`N%E>6Xe)Qoi^h#S?2o9uu7 zC6Z8OH(BfOGya$dH>s6v8m?(u9+29arDB=9cu`(SN(6u~))A2khazz? B3Q65pE$%oJk0lgXqlX}3kS zMw%@yE~Xid<~RyGsCa8cM=2^2pJPCzF}ye~X=+SYqY=WuM8Rl6catQ{6NCAMV}Ab- zd?cP>0r;R(C`Pk3h7O16kr8pdyahlq3H@nAJkT1$bTy7g6Pkp}TX005GZI3UhT>xh zEo5#-mS`NpVQ`JZs_dvGjT<) x*(!Qf1LpQP3p`GICIgT?kUVBncF9$_#~Eic7Y0ic*a6 z2q<49uA_*A4JZJ&set3;7@lJ!o?@LrMDdJMrUW_2Qe4oEoQ%TRoyEZs5GynlsuG1p zW@SLh0L43kF5andl#4-5ibq_KLJp3loOa$R!(5QTk_jbC;*zKqMsS>J7&T%#7HKpm z48q0IDxaI=Y|OBwDui?e0^H;>HIhgTPXyF3uF;XfChKCMBMJf|I5^H(%nv)Q#9ACG z(ZDo&r#WLBiwK(mVv$j&0ASi-FQP}oNRMiPXf)&|hq~_2v>&dMjCABhItI|8J{%bA z!wVTsWYXyyaQ>*QDy@IzZCoCr1pML1E7drx-)frDH>w7&Nk63@L#la|2*SJ+B9hWu zh@%!Pn|T6OdP-_Skwy&NBU7$}cJ)t6L2xO^jvP+PWtVx1$C#&(z&j|3Lk TmM3aHIv<;dU^g?>58D=;$+RkbGWX|F=t^m;Ei;Riiak|Fo8WRI!avra)ak|FD zz?huJtLty0D{uI93P<3-pd`F3?b;%^;YBMucu9rVa?1E_+4InCV3`!FtdGOn*$0ML z%jRuLfiXw-`O9-oWSyCx&3L~3;R-Od`@E%r%7bs*Svqwuk(+h?kyGs(?|VH^G;P}z zckC}O3`}9?ud01oeYN$`uTuRtub-yeG%Nejmv5c2^T3{SK_ ~&R4l&o<=*bH)gAu>lSa$G delta 1030 zcmV+h1o`{oA;<`jBYy#eX+uL$Nkc;*aB^>EX>4Tx04R}tkv&MmKpe$iTg9Rk2Q!E` zWT@g`7Zq`=RVYG*P%E_RU~=gfG-*guTpR`0f`cE6RR hT)2yyIpy{@mPA0@`ZdL4gMF?RC7=K5f%q(M0l2Y&;U-t;` z^)AM<{LlS4`qjL}fPhFGXNGALZxGLH+6L!+Vu6)pmH3=^!lVllKXP61_>FVX p|*19KuVI;4wEOVXa2$ERD5+sOF zP(v9N*oe`plYe3%P5TKS|FG+q$fc003`ULxRG~q3{osG_yIZR;HR&Zq5 ;acMz|fN+o3bl~Xa)-f z;QfrgDF+PR0=;WqZ>@ctJ^&f&Ds=-K90FrS%3k+*cM-U=w|~#H`uhQDopPhvj4$Am z5fCze2oxwHC&h)50006-Nkl C5z6oy~5n{x$0N~a9gMe#5A2P{f)bQ5&w z=AteYT>Jx8T#}&_ETZ7#ATBDk4x%8PDwY-$q#d-;MBfgV>#bTfz0?=ZkT2gkPjXK3 zemVfe0j0-*b#TDZwi_;&3m%ULcDo&Bvl&KzqY*}<5e9<+vMl5M{T;nt5A}K-nM?+) zR% #S<1yRqHY=5X3M-Wg+wC^T 3WBha zC 2N#bNO`L6HV0qYSChuLg4`S$ikMNz0I3P+<6@9*z
o!1={eJ)V0N>fgbUM`p&~%~=hr^Av!C>%vM`kLOf-K9+ zYgv|;R=iJ|KU1&Qi}Uky06;dI#qI6w?*jf;pExJ>zH{$)p8x;=07*qoM6N<$g1;N% ArT_o{ diff --git a/firmware/keira/src/apps/icons/wifi_offline.h b/firmware/keira/src/apps/icons/wifi_offline.h index c49f2e9f..2f255698 100644 --- a/firmware/keira/src/apps/icons/wifi_offline.h +++ b/firmware/keira/src/apps/icons/wifi_offline.h @@ -35,6 +35,16 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, 0x0000, 0x0000, 0x0000, @@ -47,6 +57,8 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, + 0xa800, + 0xa800, 0x0000, 0x0000, 0x0000, @@ -57,6 +69,8 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, + 0xa800, + 0xa800, 0x0000, 0x0000, 0x0000, @@ -65,22 +79,8 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xa800, + 0xa800, 0x0000, 0x1000, 0x4000, @@ -95,14 +95,14 @@ const uint16_t wifi_offline[] = { 0x4000, 0x1000, 0x0000, + 0xa800, + 0xa800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xa800, 0x0000, 0x2000, 0x5000, @@ -121,11 +121,11 @@ const uint16_t wifi_offline[] = { 0x5000, 0x2000, 0x0000, + 0xa800, 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, + 0xa800, 0x1800, 0x5000, 0x6800, @@ -146,11 +146,11 @@ const uint16_t wifi_offline[] = { 0x6800, 0x5000, 0x1800, + 0xa800, 0x0000, 0x0000, 0x0000, - 0x2000, - 0x6000, + 0xa800, 0x6800, 0x6800, 0x6800, @@ -169,12 +169,12 @@ const uint16_t wifi_offline[] = { 0x6800, 0x6800, 0x6800, - 0x6000, - 0x2000, + 0xa800, 0x0000, - 0x2800, - 0x6000, - 0x6800, + 0x0000, + 0x0000, + 0x0000, + 0xa800, 0x6800, 0x6800, 0x5800, @@ -193,13 +193,13 @@ const uint16_t wifi_offline[] = { 0x6000, 0x6800, 0x6800, - 0x6800, - 0x6000, - 0x2800, - 0x6000, - 0x6800, - 0x6800, - 0x6800, + 0xa800, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xa800, 0x4800, 0x0000, 0x0000, @@ -216,14 +216,14 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x4800, - 0x6800, - 0x6800, - 0x6800, - 0x6000, - 0x6000, - 0x6800, - 0x6800, - 0x3000, + 0xa800, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xa800, 0x0000, 0x0000, 0x0000, @@ -240,16 +240,16 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x3000, - 0x6800, - 0x6800, - 0x6000, - 0x2000, - 0x4800, - 0x2000, + 0xa800, + 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, + 0x0000, + 0xa800, + 0x0000, 0x2000, 0x5800, 0x6800, @@ -263,17 +263,17 @@ const uint16_t wifi_offline[] = { 0x5800, 0x2000, 0x0000, + 0xa800, 0x0000, 0x0000, - 0x2000, - 0x4800, - 0x2000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2800, + 0x0000, + 0x0000, + 0xa800, 0x6000, 0x6800, 0x6800, @@ -286,7 +286,7 @@ const uint16_t wifi_offline[] = { 0x6800, 0x6800, 0x6000, - 0x2800, + 0xa800, 0x0000, 0x0000, 0x0000, @@ -296,8 +296,8 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x2000, - 0x6800, + 0x0000, + 0xa800, 0x6800, 0x6800, 0x6800, @@ -310,8 +310,7 @@ const uint16_t wifi_offline[] = { 0x6800, 0x6800, 0x6800, - 0x6800, - 0x2000, + 0xa800, 0x0000, 0x0000, 0x0000, @@ -320,9 +319,10 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x4800, - 0x6800, - 0x6800, + 0x0000, + 0x0000, + 0x0000, + 0xa800, 0x6800, 0x3000, 0x0000, @@ -333,9 +333,10 @@ const uint16_t wifi_offline[] = { 0x0000, 0x3000, 0x5000, - 0x5800, - 0x6800, - 0x4800, + 0xa800, + 0x0000, + 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, @@ -344,11 +345,9 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x2800, - 0x6000, - 0x6000, - 0x3000, 0x0000, + 0xa800, + 0x3000, 0x0000, 0x0000, 0x0000, @@ -358,6 +357,7 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, + 0xa800, 0x4000, 0x2800, 0x0000, @@ -371,7 +371,7 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x0000, + 0xa800, 0x0000, 0x0000, 0x5000, @@ -396,7 +396,7 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x0000, + 0xa800, 0x5000, 0x6800, 0x6800, @@ -404,13 +404,13 @@ const uint16_t wifi_offline[] = { 0x5000, 0x0000, 0xa800, - 0xb000, - 0xb000, + 0xf800, + 0xf800, 0x8800, 0x1800, 0x8800, - 0xb000, - 0xb000, + 0xf800, + 0xf800, 0xa800, 0x0000, 0x0000, @@ -420,7 +420,7 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x0000, + 0xa800, 0x6000, 0x6800, 0x6800, @@ -428,13 +428,13 @@ const uint16_t wifi_offline[] = { 0x5800, 0x0000, 0x8800, - 0xb000, - 0xb000, - 0xb000, + 0xf800, + 0xf800, + 0xf800, 0xa000, - 0xb000, - 0xb000, - 0xb000, + 0xf800, + 0xf800, + 0xf800, 0x8800, 0x0000, 0x0000, @@ -445,19 +445,19 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x6000, + 0xa800, 0x6800, 0x6800, 0x6800, 0x6800, - 0x4000, + 0xa800, 0x0000, 0x8800, - 0xb000, - 0xb000, - 0xb000, - 0xb000, - 0xb000, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, 0x8800, 0x0000, 0x0000, @@ -469,18 +469,18 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x5000, - 0x6800, - 0x6800, - 0x6800, - 0x6800, - 0x4800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, + 0xa800, 0x0000, 0x1800, 0xa000, - 0xb000, - 0xb000, - 0xb000, + 0xf800, + 0xf800, + 0xf800, 0xa000, 0x1800, 0x0000, @@ -494,18 +494,18 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x5000, - 0x6000, - 0x6000, - 0x5000, + 0xa800, + 0xa800, + 0xa800, + 0xa800, 0x0000, 0x0000, 0x8800, - 0xb000, - 0xb000, - 0xb000, - 0xb000, - 0xb000, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, 0x8800, 0x0000, 0x0000, @@ -518,19 +518,19 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0xa800, + 0xa800, + 0xa800, + 0xa800, 0x0000, 0x8800, - 0xb000, - 0xb000, - 0xb000, + 0xf800, + 0xf800, + 0xf800, 0xa000, - 0xb000, - 0xb000, - 0xb000, + 0xf800, + 0xf800, + 0xf800, 0x8800, 0x0000, 0x0000, @@ -543,18 +543,18 @@ const uint16_t wifi_offline[] = { 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, + 0xa800, + 0xa800, 0x0000, 0x0000, 0xa800, - 0xb000, - 0xb000, + 0xf800, + 0xf800, 0x8800, 0x1800, 0x8800, - 0xb000, - 0xb000, + 0xf800, + 0xf800, 0xa800, 0x0000, 0x0000, diff --git a/firmware/keira/src/apps/icons/wifi_offline.png b/firmware/keira/src/apps/icons/wifi_offline.png index c11c0dac7fefbe321573ce0758e366693741ba93..d5b08aa7df03a4a1148e501e05a74ec10945280e 100644 GIT binary patch literal 4667 zcmeHKdsGuw8c#q0vm)Zsf=FvNVg>9Zlg#8bCCDQbf<}2n1?BWO$xL8MUL=zTsZU(7 z9u{ )vW z-wztKzJINHFlIhM?3W2D5VXNQO{2}^ON3%rh{%9HEI~0C!Nd~2Sc<_4OezKIbKf71 zh+&$yd3_&~hbUN~R_yg>SQ4jg*Pxa6CI!{8^QLDlww$=H86dB~f?yZJVmG=G1aU zQ(Rbea?Nu~obb^HA=}aDSYc&pQA5LD&g@@X{ (6Wq4=a zQ|GG6H 9|l{ zWX-OCX~ox_*)J2f 5oHJK5B~7E-2BohBfxJDW=~_ zEDSG{ztGuxt@!$^#O|q|e0}Vx_jm6;i9XSMRiAdUQD!Ut?&{krpFJ?5L_*}a_VBgU zI=>s2x~h05yCL|Kj)%35%FBWLv=d*na01t#RBt={&59eU#&7?=st9}1%QaoF?{;OB zo(DPTp>(-)u67<~u$qN9VbzmDkJ-i?7$<&?$A%k V@pi(9WvgEupa4%QK_N}sFp 5(pq5M~Q{TJ&?sQgQ4i>P?HXWowCuC)xu{ualO?^s{{ft&mWA>Y}0Co=q-)` z6@VTh4{j5Qg|NtM7LD|9(5Ws!G7!+OdN_0?Hd2&LI;>8+flPIg7J9}=3c@htZ*$sB z>~;u)h%}LA0Cj*>#iN#FZrqRuBS8UWwy|D7>`_RXG7gJ1DmG?@-Ok8Bfcp^dDD>do zSuj9pwV2v!a5CX()G7h9K1Ns#6oIirQce(v0#-l>sYD?ZmmrW*saHUxlu#NF)Tq~^ z$OtNp#X;j11IbVUav=qH3^<~YNhKsCm!o0`mC0m~LM%fe1px|-82lhIbOgl$I|Z^5 zH;s&np&|g41V{9!1eZa2k^s@5VgkYu2@Xk>22^1naYSxZuvCNrd(~<; ^C*kcGd!WA%w!IYGir+EVi2%GiAW`KxdN3A zgBFo?2gpQ*ldYZX409|P*bERBXYv#fuy(K)EX7XZwAHS&T1_g!P}Lop)`IIq;54qr zX%dhQ)nVOW9i9zKFt|T_hE8iGC}YY0LNk|#9}n>0$kQnYSigid_1~x*vbg`L|ItLT zSBcMOF9n7h`nTY~T_nNA3Ap;F428I*fCSZJAYBLT)UTuh42xlf7*RmD!YGGOC9H=O zQX>MPMma2jalKKZl#OP0SdFwBx06W)Ku4ezNKf`J6hDSNsMyhHcOl7~0uT&>5lAfg zrC_3g4U3qXF}UM+(SK efoB4bW!L{rF5d9#6lnqf1-Ze?(rbsS5%8iFpr4zj=JYY& z_fPzFGq6msrRO=o+u1iv<0i*cd4MsH)@V}$yZk2x2gy?=WPo|@HH|t+mwxWZ)dN;t zQdmIu&BJ>p#IE7 }WAY+_T(&$M)9eElR{u|8q}A%kvq1S!c`4&j(k~Y2#xe^G)9REqh~B zo{0s;VZV<^d*z?KU9GPqv;}`0z`4r_J5)Rc!98Kk|Cnov{@BIgwIl}S^yOaBe$ZOH z`f+H(>#m-_gjWB0-_ov-w#k*Zf+i7_Tf3SYWbPo^KS2>>+tpt(+|FG;qB&0n|7%DxpA918=k!M^{GAF z5c9GF5tkJ88!q)s-Drz521o6Ka+6AS+Fj{c1+mAZ>%Ka>Z1uLXJFzjHF`_GXj+7nw zaetvX|17cGs;;=_i@(w4dQc;~*M`1!x2f(J_owKhKU`glg`Zsb!ac+I^6K6r(-LQH zZuSZ~+#4+7$oAx2OQ)+Zf2yl(dQdgn^JbOQ{UUyp8n>kZ`?o6S)4lJ_sh}SovL5{G z^nuW)*~a`27Vq*I-niSlqUBWWg`d~$e(A*C(Dp3d&C7Wgx9aQKuhfLL@AK~baGy8u g%hrF Kl2BA9{>OV delta 922 zcmV;L17-ZXB;5y)BYy#eX+uL$Nkc;*aB^>EX>4Tx04R}tkv&MmKpe$iQ>8^J4pxxj zkfA!Yi;6hbDionYs1;guFuC*#nzSS-E{=k0!NHHks)LKOt`4q(Aou~|?BJy6A|?JW zDYS_3;J6>}?mh0_0Ya -dRXaURyH)^Y2v7=>69 O5XqnhrmRMve!M{9TDv9?cXz<{(b T*i~}b)+;8JFrf~|R7(p%e_Rzt1Y-1gNTYc;lc?=r39ESe~TX>0fKY}x8Vq!>1 zHt`f6%LENv!?En=pZFX<@8VmmA4ff$I*Fs%xgU5Ew<%`nHbdit9c (f=+^>{WPjqz=k91mhl*x2uTFczBM4kHQm zED@Hg5^VQatA~uOXoO|#;(o-W62U`!h=S_G_oGOJ#mw_Wek getService (); + lilka::Canvas iconCanvas(240, 24); while (1) { canvas->fillScreen(lilka::display.color565(0, 0, 0)); - int16_t xOffset = 144; - // Print counter for debug purpose // TODO: Replace with actual time from NTP canvas->setTextColor(lilka::display.color565(255, 255, 255), lilka::display.color565(0, 0, 0)); canvas->setFont(FONT_9x15); - canvas->setCursor(32, 17); + canvas->setCursor(24, 17); canvas->print("Час: " + String(counter++)); - // Draw WiFi signal strength - if (networkService != NULL) { - if (networkService->getNetworkState() == NETWORK_STATE_OFFLINE) { - canvas->draw16bitRGBBitmapWithTranColor(144, 0, wifi_offline, 0, 24, 24); - } else if (networkService->getNetworkState() == NETWORK_STATE_CONNECTING) { - canvas->draw16bitRGBBitmapWithTranColor(144, 0, wifi_connecting, 0, 24, 24); - } else if (networkService->getNetworkState() == NETWORK_STATE_ONLINE) { - canvas->draw16bitRGBBitmapWithTranColor(144, 0, icons[networkService->getSignalStrength()], 0, 24, 24); - } - } - xOffset += 8 + 24; - - // Draw battery - int level = lilka::battery.readLevel(); - if (level == -1) { - canvas->draw16bitRGBBitmapWithTranColor( - xOffset, 0, battery_absent, lilka::display.color565(255, 0, 255), 32, 24 - ); - } else { - int16_t x1 = 6, y1 = 8; - int16_t fullWidth = 22, h = 8; - int filledWidth = fullWidth * level / 100; - if (filledWidth < 1) filledWidth = 1; - int16_t color = - level > 50 ? lilka::display.color565(0, 255, 0) - : (level > 20 ? lilka::display.color565(255, 255, 0) : lilka::display.color565(255, 0, 0)); - canvas->draw16bitRGBBitmapWithTranColor( - xOffset, 0, level > 10 ? battery : battery_danger, lilka::display.color565(255, 0, 255), 32, 24 - ); - canvas->fillRect(xOffset + x1 + (fullWidth - filledWidth), y1, filledWidth, h, color); - } - xOffset += 8 + 32; - canvas->setCursor(xOffset, 17); - canvas->print(String(level) + "%"); + // Draw icons + int16_t xOffset = drawIcons(&iconCanvas); + canvas->draw16bitRGBBitmap(canvas->width() - xOffset - 16, 0, iconCanvas.getFramebuffer(), 240, 24); // Draw everything queueDraw(); vTaskDelay(1000 / portTICK_PERIOD_MS); } } + +int16_t StatusBarApp::drawIcons(lilka::Canvas* iconCanvas) { + NetworkService* networkService = ServiceManager::getInstance()->getService (); + + int16_t xOffset = 0; + + iconCanvas->fillScreen(lilka::display.color565(0, 0, 0)); + iconCanvas->setFont(FONT_9x15); + + // Draw RAM usage + uint32_t freeRAM = ESP.getFreeHeap(); + uint32_t totalRAM = ESP.getHeapSize(); + int16_t padding = 1; + int16_t barWidth = 24 - padding * 2; + int16_t barHeight = barWidth; + int16_t barWidthUsed = barWidth * (totalRAM - freeRAM) / totalRAM; + iconCanvas->fillRect(xOffset + padding, padding, barWidthUsed, barHeight, lilka::display.color565(255, 0, 0)); + iconCanvas->draw16bitRGBBitmapWithTranColor(xOffset, 0, ram, lilka::display.color565(0, 0, 0), 24, 24); + xOffset += 4 + 24; + + // Draw WiFi signal strength + if (networkService != NULL) { + if (networkService->getNetworkState() == NETWORK_STATE_OFFLINE) { + iconCanvas->draw16bitRGBBitmapWithTranColor(xOffset, 0, wifi_offline, 0, 24, 24); + } else if (networkService->getNetworkState() == NETWORK_STATE_CONNECTING) { + iconCanvas->draw16bitRGBBitmapWithTranColor(xOffset, 0, wifi_connecting, 0, 24, 24); + } else if (networkService->getNetworkState() == NETWORK_STATE_ONLINE) { + iconCanvas->draw16bitRGBBitmapWithTranColor( + xOffset, 0, icons[networkService->getSignalStrength()], 0, 24, 24 + ); + } + xOffset += 4 + 24; + } + + // Draw battery + int level = lilka::battery.readLevel(); + if (level == -1) { + iconCanvas->draw16bitRGBBitmapWithTranColor( + xOffset, 0, battery_absent, lilka::display.color565(255, 0, 255), 16, 24 + ); + xOffset += 4 + 16; + } else { + int16_t x1 = 4, y1 = 6; + int16_t width = 8, fullHeight = 14; + int filledHeight = fullHeight * level / 100; + if (filledHeight < 1) filledHeight = 1; + int emptyHeight = fullHeight - filledHeight; + int16_t color = level > 50 + ? lilka::display.color565(0, 255, 0) + : (level > 20 ? lilka::display.color565(255, 255, 0) : lilka::display.color565(255, 0, 0)); + iconCanvas->draw16bitRGBBitmapWithTranColor( + xOffset, 0, level > 10 ? battery : battery_danger, lilka::display.color565(255, 0, 255), 16, 24 + ); + iconCanvas->fillRect(xOffset + x1, y1 + emptyHeight, width, filledHeight, color); + xOffset += 4 + 16; + iconCanvas->setCursor(xOffset, 17); + iconCanvas->print(String(level) + "%"); + xOffset += 36; + } + + return xOffset; +} diff --git a/firmware/keira/src/apps/statusbar.h b/firmware/keira/src/apps/statusbar.h index 42c54681..40ae2029 100644 --- a/firmware/keira/src/apps/statusbar.h +++ b/firmware/keira/src/apps/statusbar.h @@ -8,4 +8,5 @@ class StatusBarApp : public App { private: void run() override; + int16_t drawIcons(lilka::Canvas* canvas); }; diff --git a/firmware/keira/assets/keira_splash.png b/firmware/keira/src/keira_splash.png similarity index 100% rename from firmware/keira/assets/keira_splash.png rename to firmware/keira/src/keira_splash.png diff --git a/sdk/lib/lilka/assets/default_splash.png b/sdk/lib/lilka/src/lilka/default_splash.png similarity index 100% rename from sdk/lib/lilka/assets/default_splash.png rename to sdk/lib/lilka/src/lilka/default_splash.png diff --git a/sdk/lib/lilka/src/lilka/display.cpp b/sdk/lib/lilka/src/lilka/display.cpp index b4c2dd8d..bd05c812 100644 --- a/sdk/lib/lilka/src/lilka/display.cpp +++ b/sdk/lib/lilka/src/lilka/display.cpp @@ -105,15 +105,19 @@ void Display::drawImageTransformed(Image* image, int16_t destX, int16_t destY, T // Transform image around its pivot. // Draw the rotated image at the specified position. + int32_t imageWidth = image->width; + int32_t imageHeight = image->height; + // Calculate the coordinates of the four corners of the destination rectangle. - IntVector v1 = transform.apply(IntVector(-image->pivotX, -image->pivotY)); - IntVector v2 = transform.apply(IntVector(image->width - image->pivotX, -image->pivotY)); - IntVector v3 = transform.apply(IntVector(-image->pivotX, image->height - image->pivotY)); - IntVector v4 = transform.apply(IntVector(image->width - image->pivotX, image->height - image->pivotY)); + int_vector_t v1 = transform.apply(int_vector_t{-image->pivotX, -image->pivotY}); + int_vector_t v2 = transform.apply(int_vector_t{imageWidth - image->pivotX, -image->pivotY}); + int_vector_t v3 = transform.apply(int_vector_t{-image->pivotX, imageHeight - image->pivotY}); + int_vector_t v4 = transform.apply(int_vector_t{imageWidth - image->pivotX, imageHeight - image->pivotY}); // Find the bounding box of the transformed image. - IntVector topLeft = IntVector(min(min(v1.x, v2.x), min(v3.x, v4.x)), min(min(v1.y, v2.y), min(v3.y, v4.y))); - IntVector bottomRight = IntVector(max(max(v1.x, v2.x), max(v3.x, v4.x)), max(max(v1.y, v2.y), max(v3.y, v4.y))); + int_vector_t topLeft = int_vector_t{min(min(v1.x, v2.x), min(v3.x, v4.x)), min(min(v1.y, v2.y), min(v3.y, v4.y))}; + int_vector_t bottomRight = + int_vector_t{max(max(v1.x, v2.x), max(v3.x, v4.x)), max(max(v1.y, v2.y), max(v3.y, v4.y))}; // Create a new image to hold the transformed image. Image destImage(bottomRight.x - topLeft.x, bottomRight.y - topLeft.y, image->transparentColor, 0, 0); @@ -122,7 +126,7 @@ void Display::drawImageTransformed(Image* image, int16_t destX, int16_t destY, T Transform inverse = transform.inverse(); for (int y = topLeft.y; y < bottomRight.y; y++) { for (int x = topLeft.x; x < bottomRight.x; x++) { - IntVector v = inverse.apply(IntVector(x, y)); + int_vector_t v = inverse.apply(int_vector_t{x, y}); // Apply pivot offset v.x += image->pivotX; v.y += image->pivotY; @@ -184,34 +188,44 @@ void Canvas::drawImageTransformed(Image* image, int16_t destX, int16_t destY, Tr // Draw the rotated image at the specified position. // Calculate the coordinates of the four corners of the destination rectangle. - IntVector v1 = transform.apply(IntVector(-image->pivotX, -image->pivotY)); - IntVector v2 = transform.apply(IntVector(image->width - image->pivotX, -image->pivotY)); - IntVector v3 = transform.apply(IntVector(-image->pivotX, image->height - image->pivotY)); - IntVector v4 = transform.apply(IntVector(image->width - image->pivotX, image->height - image->pivotY)); + int32_t imageWidth = image->width; + int32_t imageHeight = image->height; + + // Calculate the coordinates of the four corners of the destination rectangle. + int_vector_t v1 = transform.apply(int_vector_t{-image->pivotX, -image->pivotY}); + int_vector_t v2 = transform.apply(int_vector_t{imageWidth - image->pivotX, -image->pivotY}); + int_vector_t v3 = transform.apply(int_vector_t{-image->pivotX, imageHeight - image->pivotY}); + int_vector_t v4 = transform.apply(int_vector_t{imageWidth - image->pivotX, imageHeight - image->pivotY}); // Find the bounding box of the transformed image. - IntVector topLeft = IntVector(min(min(v1.x, v2.x), min(v3.x, v4.x)), min(min(v1.y, v2.y), min(v3.y, v4.y))); - IntVector bottomRight = IntVector(max(max(v1.x, v2.x), max(v3.x, v4.x)), max(max(v1.y, v2.y), max(v3.y, v4.y))); + int_vector_t topLeft = int_vector_t{min(min(v1.x, v2.x), min(v3.x, v4.x)), min(min(v1.y, v2.y), min(v3.y, v4.y))}; + int_vector_t bottomRight = + int_vector_t{max(max(v1.x, v2.x), max(v3.x, v4.x)), max(max(v1.y, v2.y), max(v3.y, v4.y))}; // Create a new image to hold the transformed image. Image destImage(bottomRight.x - topLeft.x, bottomRight.y - topLeft.y, image->transparentColor, 0, 0); // Draw the transformed image to the new image. Transform inverse = transform.inverse(); - for (int y = topLeft.y; y < bottomRight.y; y++) { - for (int x = topLeft.x; x < bottomRight.x; x++) { - IntVector v = inverse.apply(IntVector(x, y)); + uint64_t start = esp_timer_get_time(); + int_vector_t point{0, 0}; + for (point.y = topLeft.y; point.y < bottomRight.y; point.y++) { + for (point.x = topLeft.x; point.x < bottomRight.x; point.x++) { + int_vector_t v = inverse.apply(point); // Apply pivot offset v.x += image->pivotX; v.y += image->pivotY; if (v.x >= 0 && v.x < image->width && v.y >= 0 && v.y < image->height) { - destImage.pixels[x - topLeft.x + (y - topLeft.y) * destImage.width] = + destImage.pixels[point.x - topLeft.x + (point.y - topLeft.y) * destImage.width] = image->pixels[v.x + v.y * image->width]; } else { - destImage.pixels[x - topLeft.x + (y - topLeft.y) * destImage.width] = image->transparentColor; + destImage.pixels[point.x - topLeft.x + (point.y - topLeft.y) * destImage.width] = + image->transparentColor; } } } + uint64_t end = esp_timer_get_time(); + Serial.println("Transformed image in " + String(end - start) + " us"); // TODO: Draw directly to the canvas? drawImage(&destImage, destX + topLeft.x, destY + topLeft.y); @@ -348,12 +362,12 @@ Transform Transform::inverse() { return t; } -IntVector Transform::apply(IntVector v) { +inline int_vector_t Transform::apply(int_vector_t v) { // Apply this transform to a vector - return IntVector(matrix[0][0] * v.x + matrix[0][1] * v.y, matrix[1][0] * v.x + matrix[1][1] * v.y); -} - -IntVector::IntVector(int32_t x, int32_t y) : x(x), y(y) { + return int_vector_t{ + static_cast (matrix[0][0] * v.x + matrix[0][1] * v.y), + static_cast (matrix[1][0] * v.x + matrix[1][1] * v.y) + }; } Display display; diff --git a/sdk/lib/lilka/src/lilka/display.h b/sdk/lib/lilka/src/lilka/display.h index 823543ae..aec1ace3 100644 --- a/sdk/lib/lilka/src/lilka/display.h +++ b/sdk/lib/lilka/src/lilka/display.h @@ -22,7 +22,10 @@ namespace lilka { class Canvas; class Image; class Transform; -class IntVector; +typedef struct int_vector_t { + int32_t x; + int32_t y; +} int_vector_t; /// Клас для роботи з дисплеєм. /// @@ -387,19 +390,12 @@ class Transform { /// @note Інвертне перетворення - це таке перетворення, яке скасує це перетворення, тобто є зворотнім до цього. Transform inverse(); - IntVector apply(IntVector vector); + int_vector_t apply(int_vector_t vector); // Матриця перетворення float matrix[2][2]; // [рядок][стовпець] }; -class IntVector { -public: - IntVector(int32_t x, int32_t y); - int32_t x; - int32_t y; -}; - /// Екземпляр класу `Display`, який можна використовувати для роботи з дисплеєм. /// Вам не потрібно інстанціювати `Display` вручну. extern Display display; diff --git a/sdk/lib/lilka/src/lilka/ui.cpp b/sdk/lib/lilka/src/lilka/ui.cpp index 8ce0866c..68f0ad29 100644 --- a/sdk/lib/lilka/src/lilka/ui.cpp +++ b/sdk/lib/lilka/src/lilka/ui.cpp @@ -255,4 +255,193 @@ void ProgressDialog::draw(Arduino_GFX* canvas) { canvas->print(buf); } +#define K_L0 1 +#define K_L1 2 +#define K_L2 3 +#define K_BS 8 + +// 2 layers, 4 rows, 12 columns +const uint8_t keyboard[LILKA_KB_LAYERS][LILKA_KB_ROWS * LILKA_KB_COLS] = { + // Layer 0 + { + ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ' ', // R1 + ' ', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', ' ', // R2 + K_L1, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', K_BS, ' ', // R3 + K_L2, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', ' ', ' ', // R4 + }, + // Layer 1 (shifted layer 0) + { + ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', ' ', // R1 + ' ', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', ' ', // R2 + K_L0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', K_BS, ' ', // R3 + K_L2, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', ' ', ' ', // R4 + }, + // Layer 2 (special keys - braces, slashes, etc) + { + ' ', '{', '}', '[', ']', '|', '\\', ':', ';', '\'', '"', ' ', // R1 + ' ', '<', '>', '?', '/', '!', '@', '#', '$', '%', '^', ' ', // R2 + ' ', '(', ')', '-', '_', '=', '+', ':', ';', '\'', K_BS, ' ', // R3 + K_L0, '<', '>', '?', '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // R4 + }, +}; + +InputDialog::InputDialog(String title) { + this->title = title; + this->masked = false; + + this->done = false; + this->value = ""; + + this->layer = 0; + this->cx = 0; + this->cy = 0; + + this->lastBlink = 0; + this->blinkPhase = true; +} + +void InputDialog::setMasked(bool masked) { + this->masked = masked; +} + +void InputDialog::update() { + if (millis() - lastBlink > 300) { + lastBlink = millis(); + blinkPhase = !blinkPhase; + } + + State state = controller.getState(); + if (state.a.justPressed) { + // TODO: Handle key press + const uint8_t* layerKeys = keyboard[layer]; + uint8_t key = layerKeys[cy * LILKA_KB_COLS + cx]; + if (key == K_L0) { + layer = 0; + } else if (key == K_L1) { + layer = 1; + } else if (key == K_L2) { + layer = 2; + } else if (key == K_BS) { + if (value.length() > 0) { + value.remove(value.length() - 1); + } + } else if (key) { + value += (char)key; + } + resetBlink(); + } else if (state.b.justPressed) { + if (value.length() > 0) { + value.remove(value.length() - 1); + } + resetBlink(); + } else if (state.start.justPressed) { + done = true; + } else if (state.up.justPressed) { + cy--; + if (cy < 0) { + cy = LILKA_KB_ROWS - 1; + } + } else if (state.down.justPressed) { + cy++; + if (cy > LILKA_KB_ROWS - 1) { + cy = 0; + } + } else if (state.left.justPressed) { + cx--; + if (cx < 0) { + cx = LILKA_KB_COLS - 1; + } + } else if (state.right.justPressed) { + cx++; + if (cx > LILKA_KB_COLS - 1) { + cx = 0; + } + } +} + +void InputDialog::draw(Arduino_GFX* canvas) { + // Draw keyboard + int16_t kbTop = canvas->height() / 2 - 32; + int16_t kbHeight = canvas->height() / 2; + int16_t kbWidth = canvas->width(); + + canvas->fillRect(0, 0, canvas->width(), canvas->height(), canvas->color565(0, 0, 0)); + canvas->setTextColor(canvas->color565(255, 255, 255)); + canvas->setFont(FONT_10x20); + + canvas->setTextBound(4, 4, canvas->width() - 8, canvas->height() - 8); + canvas->setCursor(4, 20); + canvas->println(title); + + canvas->setTextBound(16, 16, canvas->width() - 32, canvas->height() - 32); + canvas->setCursor(16, 48); + if (masked) { + for (int i = 0; i < value.length(); i++) { + canvas->print("*"); + } + } else { + canvas->print(value); + } + if (blinkPhase) { + canvas->print("|"); + } + + // canvas->setTextBound(0, kbTop + kbHeight, canvas->width(), canvas->height()); + + const uint8_t* layerKeys = keyboard[layer]; + + for (int i = 0; i < LILKA_KB_ROWS; i++) { + for (int j = 0; j < LILKA_KB_COLS; j++) { + // Draw rect if key is focused + if (i == cy && j == cx) { + canvas->fillRect( + j * kbWidth / LILKA_KB_COLS, + kbTop + i * kbHeight / LILKA_KB_ROWS, + kbWidth / LILKA_KB_COLS, + kbHeight / LILKA_KB_ROWS, + canvas->color565(255, 64, 0) + ); + } + uint8_t key = layerKeys[i * LILKA_KB_COLS + j]; + if (key) { + String caption; + if (key == K_L0 || key == K_L1 || key == K_L2) { + caption = key == K_L0 ? "ab" : key == K_L1 ? "AB" : "!@"; + } else if (key == K_BS) { + caption = "<-"; + } else { + caption = (char)key; + } + int16_t x1, y1; + uint16_t w, h; + // Calculate text top-left corner and size + canvas->getTextBounds(caption, 0, 0, &x1, &y1, &w, &h); + // Print centered text + canvas->setCursor( + j * kbWidth / LILKA_KB_COLS + (kbWidth / LILKA_KB_COLS - w) / 2, + kbTop + i * kbHeight / LILKA_KB_ROWS + (kbHeight / LILKA_KB_ROWS - h) / 2 - y1 + ); + canvas->print(caption); + } + } + } +} + +bool InputDialog::isDone() { + if (done) { + done = false; + return true; + } + return false; +} + +String InputDialog::getValue() { + return value; +} + +void InputDialog::resetBlink() { + lastBlink = millis(); + blinkPhase = true; +} + } // namespace lilka diff --git a/sdk/lib/lilka/src/lilka/ui.h b/sdk/lib/lilka/src/lilka/ui.h index f2d43ca1..80a00cc5 100644 --- a/sdk/lib/lilka/src/lilka/ui.h +++ b/sdk/lib/lilka/src/lilka/ui.h @@ -201,6 +201,37 @@ class ProgressDialog { int16_t progress; }; +#define LILKA_KB_LAYERS 3 +#define LILKA_KB_ROWS 4 +#define LILKA_KB_COLS 12 + +/// Клас для відображення діалогового вікна введення. +/// +/// Малює вікно введення та екранну клавіатуру, дозволяє вводити текст та підтверджувати введення. +class InputDialog { +public: + explicit InputDialog(String title); + void setMasked(bool masked); + void update(); + void draw(Arduino_GFX* canvas); + bool isDone(); + String getValue(); + +private: + void resetBlink(); + + String title; + bool masked; + String value; + bool done; + + int16_t layer; + int16_t cx; + int16_t cy; + int64_t lastBlink; + bool blinkPhase; +}; + } // namespace lilka #endif // LILKA_UI_H diff --git a/sdk/tools/image2code/ship.h b/sdk/tools/image2code/ship.h new file mode 100644 index 00000000..248e5869 --- /dev/null +++ b/sdk/tools/image2code/ship.h @@ -0,0 +1,1032 @@ +// This is a generated file, do not edit. +// clang-format off +#include +const uint16_t ship_width = 32; +const uint16_t ship_height = 32; +const uint16_t ship[] = { + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xe800, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xe800, + 0xe800, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xe800, + 0xe800, + 0xe800, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xe800, + 0xe800, + 0xe800, + 0xe800, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xe800, + 0xe800, + 0xe800, + 0xe800, + 0xe800, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0xffea, + 0x0000, + 0xaaa0, + 0x0000, + 0x0000, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0xffea, + 0x0000, + 0xaaa0, + 0xaaa0, + 0x0000, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0xffea, + 0x0000, + 0xaaa0, + 0x0000, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0x0000, + 0x57ff, + 0x57ff, + 0x57ff, + 0x52bf, + 0x52bf, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0xf800, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0x0000, + 0x57ff, + 0x57ff, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xf800, + 0xf800, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0x0000, + 0x57ff, + 0x57ff, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x57ff, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x57ff, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x0000, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffea, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x0000, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x5000, + 0x5000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0xffea, + 0x0000, + 0xaaa0, + 0x0000, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x0000, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x52bf, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0xffea, + 0x0000, + 0xaaa0, + 0xaaa0, + 0x0000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0xffea, + 0x0000, + 0xaaa0, + 0x0000, + 0x0000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffea, + 0x0000, + 0x0000, + 0xffff, + 0x0000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x5000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x8000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x8000, + 0x8000, + 0x8000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x8000, + 0x8000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x8000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0x0000, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, +}; +// clang-format on From 3e572d77816ba958f5796f86eaf7a891ab18e6b9 Mon Sep 17 00:00:00 2001 From: Andrew Dunai Date: Tue, 12 Mar 2024 21:55:27 +0200 Subject: [PATCH 7/8] lib: update docs on display transforms & pivots --- sdk/lib/lilka/src/lilka/display.h | 47 +++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/sdk/lib/lilka/src/lilka/display.h b/sdk/lib/lilka/src/lilka/display.h index aec1ace3..ccc50602 100644 --- a/sdk/lib/lilka/src/lilka/display.h +++ b/sdk/lib/lilka/src/lilka/display.h @@ -176,8 +176,8 @@ class Display : public Arduino_ST7789 { /// Намалювати зображення. /// @param image Вказівник на зображення (об'єкт класу `lilka::Image`). - /// @param x Координата X лівого верхнього кута зображення. - /// @param y Координата Y лівого верхнього кута зображення. + /// @param x Координата X осі зображення. + /// @param y Координата Y осі зображення. /// /// Приклад використання: /// @@ -194,8 +194,8 @@ class Display : public Arduino_ST7789 { void drawImage(Image* image, int16_t x, int16_t y); /// Намалювати зображення з афінними перетвореннями. /// @param image Вказівник на зображення (об'єкт класу `lilka::Image`). - /// @param x Координата X лівого верхнього кута зображення. - /// @param y Координата Y лівого верхнього кута зображення. + /// @param x Координата X осі зображення. + /// @param y Координата Y осі зображення. /// @param transform Об'єкт класу `lilka::Transform`, який містить матрицю перетворення. /// @note Зверніть увагу, що перетворення - це повільніше, ніж звичайне малювання зображення, оскільки обчислює координати пікселів "на льоту". Використовуйте його лише тоді, коли не можете заздалегідь створити обернені копії зображеня за допомогою методів `lilka::Image::rotate`, `lilka::Image::flipX` та `lilka::Image::flipY`. /// @see lilka::Transform @@ -251,14 +251,15 @@ class Display : public Arduino_ST7789 { /// Клас для роботи з графічним буфером. /// -/// При частому перемальовуванні екрану без використання буфера, може спостерігатися мерехтіння. +/// При частому перемальовуванні екрану без використання буфера може спостерігатися мерехтіння. /// Наприклад, якщо використовувати метод `fillScreen` для очищення екрану перед кожним викликом `print`, /// то текст буде мерехтіти. /// /// Щоб уникнути цього, можна використовувати буфер. Цей клас дозволяє малювати графічні об'єкти на буфері, /// а потім відобразити його на екрані за допомогою методу `lilka::display.renderCanvas`. /// -/// Такий підхід дозволяє зменшити мерехтіння, але збільшує використання пам'яті. Він називається "буферизація". +/// Такий підхід дозволяє зменшити мерехтіння, але збільшує використання пам'яті. Він називається "буферизація", +/// оскільки ми спершу малюємо на буфері, а тоді відображаємо буфер на екрані. /// /// Цей клас, як і `Display`, є підкласом `Arduino_GFX` з бібліотеки `Arduino_GFX_Library`. /// Це означає, що майже всі методи, які доступні в `Display`, також доступні в `Canvas`. @@ -273,11 +274,11 @@ class Display : public Arduino_ST7789 { /// } /// /// void loop() { -/// lilka::Canvas canvas; +/// lilka::Canvas canvas; // Створити новий Canvas зі стандартним розміром (розмір дисплею) /// int y = 100; /// while (1) { /// canvas.fillScreen(lilka::display.color565(0, 0, 0)); // Заповнити буфер чорним кольором -/// canvas.setCursor(32, 0); +/// canvas.setCursor(32, y); /// canvas.setTextColor(lilka::display.color565(0, 0, 0)); // Білий текст /// canvas.print("Привіт, Лілка!"); /// lilka::display.renderCanvas(&canvas); // Відобразити буфер на екрані - жодного мерехтіння! @@ -312,6 +313,8 @@ class Canvas : public Arduino_Canvas { /// Містить розміри, прозорий колір та пікселі зображення (в 16-бітному форматі, 5-6-5). /// Пікселі зберігаються в рядку зліва направо, зверху вниз. /// +/// Вісь зображення - це точка, яка вказує на центр зображення. Це дозволяє вам встановити точку, відносно якої буде відображатися зображення, а також навколо якої буде відбуватися перетворення зображення. +/// /// @note Основна відмінність Image від поняття "bitmap" погялає в тому, що Image містить масив пікселів, розміри зображення і прозорий колір, в той час як "bitmap" - це просто масив пікселів. class Image { public: @@ -319,6 +322,10 @@ class Image { ~Image(); /// Обернути зображення на заданий кут (в градусах) і записати результат в `dest`. /// + /// Цей метод, а також методи `flipX` та `flipY`, зручно використовувати для створення обернених та віддзеркалених копій зображення, якщо ви заздалегідь знаєте, які варіанти зображення вам знадобляться. + /// + /// Замість них можна використовувати клас `lilka::Transform` та його методи, які дозволяють виконувати та комбінувати складніші перетворення "на льоту", але такі перетворення є повільнішими. + /// /// @param angle Кут обертання в градусах. /// @param dest Вказівник на Image, в яке буде записано обернуте зображення. /// @param blankColor 16-бітний колір (5-6-5), який буде використаний для заповнення пікселів, які виходять за межі зображення. @@ -339,6 +346,7 @@ class Image { /// delete image; /// delete rotatedImage; /// @endcode + /// @see Display::drawImageTransformed, Canvas::drawImageTransformed, Transform void rotate(int16_t angle, Image* dest, int32_t blankColor); /// Віддзеркалити зображення по горизонталі і записати результат в `dest`. void flipX(Image* dest); @@ -358,7 +366,9 @@ class Image { /// Афінні перетворення - це перетворення, які зберігають паралельність ліній. /// Вони включають в себе обертання, масштабування та віддзеркалення. /// -/// Наприклад, ось цей код обертає зображення на 30 градусів та віддзеркалює його по горизонталі: +/// Перетворення - це всього лиш матриця 2x2. Застосування перетворення до вектора - це множення цього вектора на матрицю перетворення. Магія! +/// +/// Наприклад, ось цей код обертає зображення на 30 градусів і тоді віддзеркалює його по горизонталі: /// /// @code /// lilka::Transform transform = lilka::Transform().rotate(30).flipX(); @@ -374,23 +384,38 @@ class Transform { /// /// Оскільки на екрані вісь Y вказує вниз, обертання буде здійснено за годинниковою стрілкою. /// @param angle Кут обертання в градусах. + /// @return Нове перетворення. Transform rotate(int16_t angle); /// Масштабувати по X та Y. /// /// Щоб віддзеркалити зображення, використайте від'ємні значення (наприклад, -1). /// @param scaleX Масштаб по X. /// @param scaleY Масштаб по Y. + /// @return Нове перетворення. Transform scale(float scaleX, float scaleY); - /// Застосувати інше перетворення до цього. + /// Помножити це перетворення на інше. + /// + /// @note Зверніть увагу: при комбінації перетворень порядок важливий, і він є оберненим до порядку множення матриць! В результаті цього, перетворення other буде виконано **перед** поточним перетворенням. Тобто якщо в вас є деякі перетворення `A` та `B`, то перетворення `A.multiply(B)` утворить нове перетворення, в якому спочатку виконається перетворення `B`, а потім `A`. + /// @note Для уникнення плутанини рекомендуємо використовувати більш високорівневі методи, такі як `rotate` та `scale`. /// @param other Інше перетворення. + /// @return Перетворення, яке є результатом застосування цього перетворення після `other` перетворення. + /// @code + /// lilka::Transform rotate30 = lilka::Transform().rotate(30); // обернути на 30 градусів + /// lilka::Transform scale2x = lilka::Transform().scale(2, 2); // збільшити в 2 рази + /// lilka::Transform scaleThenRotate = rotate30.multiply(scale2x); // результат - це перетворення "спочатку збільшити, а потім обернути", а не навпаки! + /// @endcode Transform multiply(Transform other); /// Інвертувати перетворення. /// @note Інвертне перетворення - це таке перетворення, яке скасує це перетворення, тобто є зворотнім до цього. + /// @return Інвертоване перетворення. Transform inverse(); - int_vector_t apply(int_vector_t vector); + /// Перетворити вектор, використовуючи це перетворення. + /// @param vector Вхідний вектор. + /// @return Результат перетворення. + int_vector_t transform(int_vector_t vector); // Матриця перетворення float matrix[2][2]; // [рядок][стовпець] From 6273723b2090ea9c8c15ec3fe9bbd47ca837de79 Mon Sep 17 00:00:00 2001 From: Andrew Dunai Date: Tue, 12 Mar 2024 22:42:35 +0200 Subject: [PATCH 8/8] lib: fix typo in transform method --- sdk/lib/lilka/src/lilka/display.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sdk/lib/lilka/src/lilka/display.cpp b/sdk/lib/lilka/src/lilka/display.cpp index bd05c812..97c72705 100644 --- a/sdk/lib/lilka/src/lilka/display.cpp +++ b/sdk/lib/lilka/src/lilka/display.cpp @@ -109,10 +109,10 @@ void Display::drawImageTransformed(Image* image, int16_t destX, int16_t destY, T int32_t imageHeight = image->height; // Calculate the coordinates of the four corners of the destination rectangle. - int_vector_t v1 = transform.apply(int_vector_t{-image->pivotX, -image->pivotY}); - int_vector_t v2 = transform.apply(int_vector_t{imageWidth - image->pivotX, -image->pivotY}); - int_vector_t v3 = transform.apply(int_vector_t{-image->pivotX, imageHeight - image->pivotY}); - int_vector_t v4 = transform.apply(int_vector_t{imageWidth - image->pivotX, imageHeight - image->pivotY}); + int_vector_t v1 = transform.transform(int_vector_t{-image->pivotX, -image->pivotY}); + int_vector_t v2 = transform.transform(int_vector_t{imageWidth - image->pivotX, -image->pivotY}); + int_vector_t v3 = transform.transform(int_vector_t{-image->pivotX, imageHeight - image->pivotY}); + int_vector_t v4 = transform.transform(int_vector_t{imageWidth - image->pivotX, imageHeight - image->pivotY}); // Find the bounding box of the transformed image. int_vector_t topLeft = int_vector_t{min(min(v1.x, v2.x), min(v3.x, v4.x)), min(min(v1.y, v2.y), min(v3.y, v4.y))}; @@ -126,7 +126,7 @@ void Display::drawImageTransformed(Image* image, int16_t destX, int16_t destY, T Transform inverse = transform.inverse(); for (int y = topLeft.y; y < bottomRight.y; y++) { for (int x = topLeft.x; x < bottomRight.x; x++) { - int_vector_t v = inverse.apply(int_vector_t{x, y}); + int_vector_t v = inverse.transform(int_vector_t{x, y}); // Apply pivot offset v.x += image->pivotX; v.y += image->pivotY; @@ -192,10 +192,10 @@ void Canvas::drawImageTransformed(Image* image, int16_t destX, int16_t destY, Tr int32_t imageHeight = image->height; // Calculate the coordinates of the four corners of the destination rectangle. - int_vector_t v1 = transform.apply(int_vector_t{-image->pivotX, -image->pivotY}); - int_vector_t v2 = transform.apply(int_vector_t{imageWidth - image->pivotX, -image->pivotY}); - int_vector_t v3 = transform.apply(int_vector_t{-image->pivotX, imageHeight - image->pivotY}); - int_vector_t v4 = transform.apply(int_vector_t{imageWidth - image->pivotX, imageHeight - image->pivotY}); + int_vector_t v1 = transform.transform(int_vector_t{-image->pivotX, -image->pivotY}); + int_vector_t v2 = transform.transform(int_vector_t{imageWidth - image->pivotX, -image->pivotY}); + int_vector_t v3 = transform.transform(int_vector_t{-image->pivotX, imageHeight - image->pivotY}); + int_vector_t v4 = transform.transform(int_vector_t{imageWidth - image->pivotX, imageHeight - image->pivotY}); // Find the bounding box of the transformed image. int_vector_t topLeft = int_vector_t{min(min(v1.x, v2.x), min(v3.x, v4.x)), min(min(v1.y, v2.y), min(v3.y, v4.y))}; @@ -211,7 +211,7 @@ void Canvas::drawImageTransformed(Image* image, int16_t destX, int16_t destY, Tr int_vector_t point{0, 0}; for (point.y = topLeft.y; point.y < bottomRight.y; point.y++) { for (point.x = topLeft.x; point.x < bottomRight.x; point.x++) { - int_vector_t v = inverse.apply(point); + int_vector_t v = inverse.transform(point); // Apply pivot offset v.x += image->pivotX; v.y += image->pivotY; @@ -362,7 +362,7 @@ Transform Transform::inverse() { return t; } -inline int_vector_t Transform::apply(int_vector_t v) { +inline int_vector_t Transform::transform(int_vector_t v) { // Apply this transform to a vector return int_vector_t{ static_cast (matrix[0][0] * v.x + matrix[0][1] * v.y),