Assets, Icons, UI toolkit. Part 1. (#202)

* Assets: import from gdrive
* Assets: fully working build pipeline and registry
* NFC: menu icon
* Gui: layers. Irukagotchi: base app to handle input on idle screen. Makefile: reboot after flash in dfu mode.
* ValueMutex: with lambda
* Assets: proper animation frames sorting
* ValueMutex: proper furi_open usage
* Assets,GUI: split icon into icon data and icon state.
* Format source code
* Docker: add python3 and imagemagic
* Irukagotchi: cleanup
* GUI: event lock moved to gui.
* Rfid: proper gui layer
* GUI: elements. Menu: frame and scroll
* GUI, Menu: format code.
* Menu: dual font main menu
* Menu: format sources
* GUI: 0 total scrollbar
* CI: enable lfs
* Menu: pixel perfect main menu

Co-authored-by: Aleksandr Kutuzov <aku@plooks.com>
Co-authored-by: aanper <mail@s3f.ru>
This commit is contained in:
あく
2020-10-26 20:00:17 +03:00
committed by GitHub
parent e699c4a31e
commit 665f6d7d9c
116 changed files with 1057 additions and 184 deletions

1
assets/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/headers

17
assets/ReadMe.md Normal file
View File

@@ -0,0 +1,17 @@
# Asset naming rules
## Images and Animations
`NAME_VARIANT_SIZE`
- `NAME` - mandatory - Asset name in CamelCase. [A-Za-z0-9], special symbols not allowed
- `VARIANT` - optional - icon variant: can relate to state or rendering conditions. Examples: active, inactive, inverted.
- `SIZE` - mandatory - size in px. Example squere 10, 20, 24, etc. Example rectangular: 10x8, 19x5, etc.
Image names will be automatically prefixed with `I_`, animation names with `A_`.
Icons and Animations will be gathered into `icon.h` and `icon.c`.
# Important notes
Don't include assets that you are not using, compiller is not going to strip unusued assets.

10
assets/assets.mk Normal file
View File

@@ -0,0 +1,10 @@
ASSETS_DIR := $(PROJECT_ROOT)/assets
ASSETS_COMPILLER := $(ASSETS_DIR)/assets.py
ASSETS_OUTPUT_DIR := $(ASSETS_DIR)/output
ASSETS_SOURCE_DIR := $(ASSETS_DIR)/icons
ASSETS_SOURCES += $(shell find $(ASSETS_SOURCE_DIR) -type f -iname '*.png' -or -iname 'frame_rate')
ASSETS += $(ASSETS_OUTPUT_DIR)/assets_icons.c
CFLAGS += -I$(ASSETS_OUTPUT_DIR)
C_SOURCES += $(ASSETS_OUTPUT_DIR)/assets_icons.c

184
assets/assets.py Executable file
View File

@@ -0,0 +1,184 @@
#!/usr/bin/env python3
import logging
import argparse
import subprocess
import io
import os
import sys
ICONS_SUPPORTED_FORMATS = ["png"]
ICONS_TEMPLATE_H_HEADER = """#pragma once
#include <gui/icon.h>
typedef enum {
"""
ICONS_TEMPLATE_H_ICON_NAME = "\t{name},\n"
ICONS_TEMPLATE_H_FOOTER = """} IconName;
Icon * assets_icons_get(IconName name);
"""
ICONS_TEMPLATE_C_HEADER = """#include \"assets_icons.h\"
#include <gui/icon_i.h>
"""
ICONS_TEMPLATE_C_FRAME = "const uint8_t {name}[] = {data};\n"
ICONS_TEMPLATE_C_DATA = "const uint8_t *{name}[] = {data};\n"
ICONS_TEMPLATE_C_ICONS_ARRAY_START = "const IconData icons[] = {\n"
ICONS_TEMPLATE_C_ICONS_ITEM = "\t{{ .width={width}, .height={height}, .frame_count={frame_count}, .frame_rate={frame_rate}, .frames=_{name} }},\n"
ICONS_TEMPLATE_C_ICONS_ARRAY_END = "};"
ICONS_TEMPLATE_C_FOOTER = """
Icon * assets_icons_get(IconName name) {
return icon_alloc(&icons[name]);
}
"""
class Assets:
def __init__(self):
# command args
self.parser = argparse.ArgumentParser()
self.parser.add_argument("-d", "--debug", action="store_true", help="Debug")
self.subparsers = self.parser.add_subparsers(help="sub-command help")
self.parser_icons = self.subparsers.add_parser(
"icons", help="Process icons and build icon registry"
)
self.parser_icons.add_argument(
"-s", "--source-directory", help="Source directory"
)
self.parser_icons.add_argument(
"-o", "--output-directory", help="Output directory"
)
self.parser_icons.set_defaults(func=self.icons)
# logging
self.logger = logging.getLogger()
def __call__(self):
self.args = self.parser.parse_args()
if "func" not in self.args:
self.parser.error("Choose something to do")
# configure log output
self.log_level = logging.DEBUG if self.args.debug else logging.INFO
self.logger.setLevel(self.log_level)
self.handler = logging.StreamHandler(sys.stdout)
self.handler.setLevel(self.log_level)
self.formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
self.handler.setFormatter(self.formatter)
self.logger.addHandler(self.handler)
# execute requested function
self.args.func()
def icons(self):
self.logger.debug(f"Converting icons")
icons_c = open(os.path.join(self.args.output_directory, "assets_icons.c"), "w")
icons_c.write(ICONS_TEMPLATE_C_HEADER)
icons = []
# Traverse icons tree, append image data to source file
for dirpath, dirnames, filenames in os.walk(self.args.source_directory):
self.logger.debug(f"Processing directory {dirpath}")
if not filenames:
continue
if "frame_rate" in filenames:
self.logger.debug(f"Folder contatins animation")
icon_name = "A_" + os.path.split(dirpath)[1].replace("-", "_")
width = height = None
frame_count = 0
frame_rate = 0
frame_names = []
for filename in sorted(filenames):
fullfilename = os.path.join(dirpath, filename)
if filename == "frame_rate":
frame_rate = int(open(fullfilename, "r").read().strip())
continue
elif not self.iconIsSupported(filename):
continue
self.logger.debug(f"Processing animation frame {filename}")
temp_width, temp_height, data = self.icon2header(fullfilename)
if width is None:
width = temp_width
if height is None:
height = temp_height
assert width == temp_width
assert height == temp_height
frame_name = f"_{icon_name}_{frame_count}"
frame_names.append(frame_name)
icons_c.write(
ICONS_TEMPLATE_C_FRAME.format(name=frame_name, data=data)
)
frame_count += 1
assert frame_rate > 0
assert frame_count > 0
icons_c.write(
ICONS_TEMPLATE_C_DATA.format(
name=f"_{icon_name}", data=f'{{{",".join(frame_names)}}}'
)
)
icons_c.write("\n")
icons.append((icon_name, width, height, frame_rate, frame_count))
else:
# process icons
for filename in filenames:
if not self.iconIsSupported(filename):
continue
self.logger.debug(f"Processing icon {filename}")
icon_name = "I_" + "_".join(filename.split(".")[:-1]).replace(
"-", "_"
)
fullfilename = os.path.join(dirpath, filename)
width, height, data = self.icon2header(fullfilename)
frame_name = f"_{icon_name}_0"
icons_c.write(
ICONS_TEMPLATE_C_FRAME.format(name=frame_name, data=data)
)
icons_c.write(
ICONS_TEMPLATE_C_DATA.format(
name=f"_{icon_name}", data=f"{{{frame_name}}}"
)
)
icons_c.write("\n")
icons.append((icon_name, width, height, 0, 1))
# Create array of images:
self.logger.debug(f"Finalizing source file")
icons_c.write(ICONS_TEMPLATE_C_ICONS_ARRAY_START)
for name, width, height, frame_rate, frame_count in icons:
icons_c.write(
ICONS_TEMPLATE_C_ICONS_ITEM.format(
name=name,
width=width,
height=height,
frame_rate=frame_rate,
frame_count=frame_count,
)
)
icons_c.write(ICONS_TEMPLATE_C_ICONS_ARRAY_END)
icons_c.write(ICONS_TEMPLATE_C_FOOTER)
icons_c.write("\n")
# Create Header
self.logger.debug(f"Creating header")
icons_h = open(os.path.join(self.args.output_directory, "assets_icons.h"), "w")
icons_h.write(ICONS_TEMPLATE_H_HEADER)
for name, width, height, frame_rate, frame_count in icons:
icons_h.write(ICONS_TEMPLATE_H_ICON_NAME.format(name=name))
icons_h.write(ICONS_TEMPLATE_H_FOOTER)
self.logger.debug(f"Done")
def icon2header(self, file):
output = subprocess.check_output(["convert", file, "xbm:-"])
assert output
f = io.StringIO(output.decode().strip())
width = int(f.readline().strip().split(" ")[2])
height = int(f.readline().strip().split(" ")[2])
data = f.read().strip().replace("\n", "").replace(" ", "").split("=")[1][:-1]
return width, height, data
def iconIsSupported(self, filename):
extension = filename.lower().split(".")[-1]
return extension in ICONS_SUPPORTED_FORMATS
if __name__ == "__main__":
Assets()()

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e3b8745f1c3cf2b3b5023d40cb2fde21afdb44f4eff3e456e2bd4eafbccb17f1
size 257

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6d24e445214cfc96ed699ad7f6fc5966e6fef08a7fe36add479e7b02e1458b4c
size 257

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:27f19713ab1d7b6113fb2f8a0402c93a763652e6b2c28693a858f26cce1acb6d
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:37271fbd71ebe1561fb4a292504d8692367c588688c534c3b9ce7122439bdca0
size 255

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:470df999ccb281350e21e86f5f21235f23ceed5fd2391d435af3b073403962ad
size 252

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:22b29a0bc9a2aa4c5258edd18def520813eefe6a028036b0f95629217565e814
size 251

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:67fd7032e3b6bad02a2d8e58b1f9c3d10a77e3c8ed48b5819047ae35e98b405e
size 251

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:969215f7462ad2d4fdf053bf67ee3a912d46debe87815e10554b58399f2c4d20
size 248

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c1154e6634b065ab40849236a3172284ce1e7dd4fd7212a1ca4bdc5b48a26ffa
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:811a93e5b8770c2578be16c5cedce9663aa8608f7061c29cba949daf94a93b48
size 251

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dbe853e0056d3b93e7beba725a660a6a8186562c2be20745aea3b2f30bcbbf91
size 254

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7076f51c03ad1e5f2f9ab00679b1142a37224caa3a44b3ea272fec94a806cf5
size 255

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:db95faeadfd4aeb9d7b56cb10f67a945d56f6d3c7199d066903d436ef2f0ceaa
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:267da4a3a640c4a75aa2d06ffd057c9ec10308137e0f73378a638ce96c3e9f19
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c88f44fcffc7ade9cfb1bcfc9dbd687776211a3d57e8278e75fbf19376d462fa
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:160e99941884fd6ac6ce19830a3b39cdc7197881689b8cbc0b3761be561c1cf7
size 237

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c88f44fcffc7ade9cfb1bcfc9dbd687776211a3d57e8278e75fbf19376d462fa
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:267da4a3a640c4a75aa2d06ffd057c9ec10308137e0f73378a638ce96c3e9f19
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:db95faeadfd4aeb9d7b56cb10f67a945d56f6d3c7199d066903d436ef2f0ceaa
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7076f51c03ad1e5f2f9ab00679b1142a37224caa3a44b3ea272fec94a806cf5
size 255

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9ab102ccd1b92236bed296eb3cdb4dc088fca6fa7e32e72d752b49e4012ffcff
size 242

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:588fabc1c63bd8815aaf61c8b8b6a7e88ef12a210f8ce04ecec6a75c4eaa48dd
size 237

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:66d2f7c971c180f7ea27c90aaf1ffeb8f62584c8fbd7c390fcda3165ecd9cdb2
size 236

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d4a40f59194adb698cac9472a14ac34a7e0b56e6251f157d11982bdff0f88745
size 235

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4ad47da62b20627fd428ec857cbadb14803d41702b639c72e820aa8759fbf424
size 231

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ededf42eb58de6082fc9f97abc73b053417f2421c547cd2f3aa9814d0eb985ab
size 235

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:44ef494e78d60728791a632dedad8a374fcd863e4a1d409c565bd7f11e142e52
size 235

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:05e946f15d71eae155c5a6438cea4f5ad56ef310577fb894ebe5c3b41f9e2e24
size 237

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b101d691964aa96546bb70bb08f638b48c6000230ded6597ac533b0bd36a8c86
size 250

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5322b1c4366b8931d132292c71318f02e6756536dd38165a1f65dea5c9dfb7b2
size 247

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:da8a0d2055a7a835be42bde6f71ba2d17710ad308201946fb07d97207c32e3c4
size 243

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:04bb17687f4b0572b4ffd7c7220cb0070456b95df9849fb55e620d02fd7fee94
size 235

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1eafe712679be62faa958b2a648a514a461c08ae846ae942888cf7f22d6c3deb
size 235

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e58c3bbcfec585b2f920b06b7464dba32686571156c59a46265d599222c7331a
size 243

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3430783069a7fa3763bc1cbe6d251540128237249ab8268c666ee180715b6d36
size 256

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:95ed4aa304cb3e7de4aa536fb67df8cd5b6413cb67f77924729d31015f298262
size 250

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2cb767e8560b1b7f25226aa1a0fc2c46625bbf94df77fcdbdb4b14834616e762
size 244

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:00cac0303198a2baa9243b0466e755d98a408587d73c1899532a86aeb75a80c5
size 247

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:227acbe3f7482e1efefc11b0cf8734f01062540db99accb969a521907d58c693
size 249

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ebe14fca1ff8d5093a05d4d452c9ee55eb7bf48d8b8fc71f98a74476e703d030
size 248

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b1b5373cf67c493b77dfcc5821754c8ec0c41eee633f81059e9507ce8102a27
size 242

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b12e03c09e699a5446bac1ad67bdf34e299b65e49995664e30bc8e14500dd26f
size 228

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9592833f1c810b9939e5a213f448c090f86dbf75bf7721ca85a6c166ebc79a6c
size 231

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:950f24058fd92684f1665e280f740ce662e078d03c0e59a546d21d4569f691a8
size 242

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:68bda2a589f180b9e5231d74eab098cdaedc08ad44d74b37f3a69e6570799c42
size 258

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dfd4f583da99e73e11abb5acbb1235cf49acf6d61e337ad6c702cba1d8ff5ed6
size 258

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:77ba2d0d27048bdc0d1b8faaef530e019c5ca2a7966c6d2e84bc4206c220a3a4
size 258

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bcb7b3c96a531cea583ec917a26037bce04e1704c0e96c096d88bd164891d3b8
size 258

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2ee856a02fb0c0b7e9f59825ce80d008bbdfde10d733db25ae2accac3cae7fb4
size 258

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:159ed78bae7c6ba8b91dbd5fc72475478852c667bdece15f68f318bfdfd7a0fc
size 258

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:11043601935b50e020ea672ed8aa8dddbec56a6925abd2cb6cfedf965c54e73b
size 256

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:abd8be6bfec3facb698a2c248f6ef75f0411d4ee75a0fc653959c5d07b4dab5e
size 255

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:75000555e5119e163d9b3afd28861e78347acfb1bf2f704e731a26d994edd1ff
size 254

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:abd8be6bfec3facb698a2c248f6ef75f0411d4ee75a0fc653959c5d07b4dab5e
size 255

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:22cbd3b5f4c41d2ede7b89d1d4212f3da0b7da815d2bc219f95106d06424f3f2
size 256

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6f75d8bb8a4c2c67855053ca7eedf2ce724937b246a3b5a5cf95b8df6122116c
size 260

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:527ebea445642be096f4bd5209af3b7b74c53e688cea5d29de6d40dad31d08ca
size 256

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ee6e95dbe9aae5a16504d42d94b24f8c3ef44108ddb726c43faec09d3cbedb7e
size 260

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2b12ea1162db6e239562eff4cc434f4aaf86fe00b5c371805d801780a1e54258
size 252

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:93c876d79ec21c394233392f6356d24078904a81f46e354ae591757287f074e7
size 255

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:901b67368cd1df6f767200c021e180427830168496fe5dcc48b05bf51fcc0f38
size 262

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bead5a67650297f99797447f7b2cb4260cb13e8310da8ae57de6e42fa39e9cf6
size 235

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:763ddd423ae9f32b3f49f8cb5b6cbc9ffe0663462bebb8d41a4777bd6bf2922e
size 233

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a01140f9e3bf9354d755f6bbc733e7b25757bae52dc5f0ecfeab0f82a7fab67f
size 231

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5099612a708c449fc633effc4ad5bda68b5f507f17d4f7cd410ae6ce9388c2d9
size 233

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c6fb3a5877db7d36e2056d48a577896aa6c58524e079a2e8d8b8c5bcf1b55892
size 226

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fd239b159734ddb22a2efd940c83f819384be18aca1a51e16341cfe55d989109
size 237

1
assets/output/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*