Update code owners and remove obsolete code (#446)
This commit is contained in:
parent
920b3c3dee
commit
c880f90eb5
144
.github/CODEOWNERS
vendored
144
.github/CODEOWNERS
vendored
@ -1,116 +1,60 @@
|
||||
# who owns all the code by default
|
||||
|
||||
# Who owns all the code by default
|
||||
* @skotopes
|
||||
|
||||
# unknow applications
|
||||
|
||||
# Applications
|
||||
applications/** @skotopes
|
||||
|
||||
# assets and asset generator
|
||||
|
||||
assets/** @skotopes
|
||||
|
||||
# bootloader
|
||||
|
||||
bootloader/** @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-boot.c @skotopes
|
||||
|
||||
# debug tools
|
||||
|
||||
debug/** @skotopes
|
||||
|
||||
# Core, HAL and applocation loader
|
||||
|
||||
applications/app-loader/** @DrZlo13
|
||||
core/** @DrZlo13
|
||||
firmware/targets/api-hal-include/** @DrZlo13
|
||||
|
||||
firmware/targets/f4/api-hal/api-hal-clock.c @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-clock.h @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-delay.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-flash.c @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-flash.h @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-gpio.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-gpio.h @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-pwm.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-pwm.h @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-resources.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-resources.h @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-spi-config.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-spi-config.h @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-spi.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-spi-config.h @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-tim.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-tim.h @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-hal-timebase-timer.h @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-timebase.c @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-timebase.h @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-uuid.c @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-vcp.c @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal.c @DrZlo13
|
||||
firmware/targets/f4/api-hal/api-interrupts.c @DrZlo13
|
||||
|
||||
firmware/targets/f4/Src/i2c.c @skotopes
|
||||
firmware/targets/f5/Src/i2c.c @skotopes
|
||||
|
||||
# BLE
|
||||
|
||||
firmware/targets/f4/ble-glue/** @skotopes
|
||||
applications/accessor/** @DrZlo13
|
||||
applications/app-loader/** @gornekich
|
||||
applications/bt/** @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-bt.c @skotopes
|
||||
|
||||
# Dolphin
|
||||
|
||||
applications/dolphin/** @skotopes
|
||||
|
||||
# GUI Stuff
|
||||
|
||||
applications/cli/** @skotopes
|
||||
applications/dolphin/** @skotopes @itsyourbedtime
|
||||
applications/gpio-tester/** @skotopes
|
||||
applications/gui/** @skotopes
|
||||
applications/input/** @skotopes
|
||||
|
||||
# iButton
|
||||
|
||||
applications/gui-test/** @DrZlo13
|
||||
applications/ibutton/** @DrZlo13
|
||||
lib/cyfral/** @DrZlo13
|
||||
lib/onewire/** @DrZlo13
|
||||
|
||||
# IR
|
||||
|
||||
applications/irda/** @DrZlo13
|
||||
|
||||
# LF-Rfid
|
||||
|
||||
applications/lf-rfid/** @DrZlo13
|
||||
|
||||
# Menu
|
||||
|
||||
applications/input/** @skotopes
|
||||
applications/irda/** @DrZlo13 @albkharisov
|
||||
applications/lf-rfid/** @DrZlo13
|
||||
applications/menu/** @skotopes
|
||||
|
||||
# NFC
|
||||
|
||||
applications/nfc/** @skotopes
|
||||
lib/ST25RFAL002/** @skotopes
|
||||
|
||||
# SD Card and filesystem
|
||||
|
||||
applications/music-player/** @DrZlo13
|
||||
applications/nfc/** @skotopes @gornekich
|
||||
applications/power/** @skotopes
|
||||
applications/sd-card-test/** @DrZlo13
|
||||
applications/sd-filesystem/** @DrZlo13
|
||||
lib/common-api/filesystem-api.h @DrZlo13
|
||||
lib/fatfs/** @DrZlo13
|
||||
firmware/targets/f4/Src/fatfs/** @DrZlo13
|
||||
applications/subghz/** @skotopes
|
||||
applications/template/** @skotopes
|
||||
applications/tests/** @skotopes @DrZlo13
|
||||
|
||||
# Power control app
|
||||
# Assets and asset generator
|
||||
assets/** @skotopes
|
||||
|
||||
applications/power/** @skotopes
|
||||
lib/drivers/bq* @skotopes
|
||||
firmware/targets/f4/api-hal/api-hal-power.c @skotopes
|
||||
# Bootloader
|
||||
bootloader/** @skotopes
|
||||
|
||||
# Some applications
|
||||
# Core, HAL and applocation loader
|
||||
core/** @DrZlo13
|
||||
|
||||
applications/music-player/** @DrZlo13
|
||||
applications/floopper-bloopper/** @skotopes
|
||||
applications/gui-test/** @DrZlo13
|
||||
# Debug tools
|
||||
debug/** @skotopes
|
||||
|
||||
# Firmware
|
||||
firmware/** @skotopes
|
||||
|
||||
# Lib
|
||||
lib/app-template/** @DrZlo13
|
||||
lib/qrcode/** @DrZlo13
|
||||
lib/callback-connector/** @DrZlo13
|
||||
lib/common-api/** @DrZlo13
|
||||
lib/cyfral/** @DrZlo13
|
||||
lib/drivers/** @skotopes @gornekich
|
||||
lib/fatfs/** @DrZlo13
|
||||
lib/fnv1a-hash/** @DrZlo13
|
||||
lib/mlib/** @skotopes
|
||||
lib/onewire/** @DrZlo13
|
||||
lib/qrcode/** @DrZlo13
|
||||
lib/ST25RFAL002/** @skotopes @gornekich
|
||||
lib/STM32CubeWB/** @skotopes
|
||||
lib/u8g2/** @skotopes
|
||||
lib/version/** @skotopes
|
||||
|
||||
# Make
|
||||
make/** @skotopes
|
||||
|
@ -1,104 +0,0 @@
|
||||
#include <furi.h>
|
||||
|
||||
typedef enum {
|
||||
EventTypeTick,
|
||||
EventTypeKey,
|
||||
// add your events type
|
||||
} EventType;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
InputEvent input;
|
||||
// add your events payload
|
||||
} value;
|
||||
EventType type;
|
||||
} Event;
|
||||
|
||||
typedef struct {
|
||||
// describe state here
|
||||
} State;
|
||||
|
||||
static void render_callback(Canvas* canvas, void* ctx) {
|
||||
State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
|
||||
|
||||
canvas_clear(canvas);
|
||||
|
||||
// draw your app
|
||||
|
||||
release_mutex((ValueMutex*)ctx, state);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, void* ctx) {
|
||||
osMessageQueueId_t event_queue = (QueueHandle_t)ctx;
|
||||
|
||||
Event event;
|
||||
event.type = EventTypeKey;
|
||||
event.value.input = *input_event;
|
||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
||||
}
|
||||
|
||||
int32_t template_app(void* p) {
|
||||
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(Event), NULL);
|
||||
|
||||
State _state;
|
||||
/* init state here */
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
|
||||
printf("cannot create mutex\r\n");
|
||||
return 255;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
if(gui == NULL) {
|
||||
printf("gui is not available\r\n");
|
||||
return 255;
|
||||
}
|
||||
gui_add_view_port(gui, view_port, /* specify UI layer */);
|
||||
|
||||
Event event;
|
||||
while(1) {
|
||||
osStatus_t event_status = osMessageQueueGet(
|
||||
event_queue, &event, NULL,
|
||||
/* specify timeout */
|
||||
);
|
||||
State* state = (State*)acquire_mutex_block(&state_mutex);
|
||||
|
||||
if(event_status == osOK) {
|
||||
if(event.type == EventTypeKey) {
|
||||
// press events
|
||||
if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyBack) {
|
||||
}
|
||||
|
||||
if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyUp) {
|
||||
}
|
||||
|
||||
if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyDown) {
|
||||
}
|
||||
|
||||
if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyLeft) {
|
||||
}
|
||||
|
||||
if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyRight) {
|
||||
}
|
||||
|
||||
if(event.value.input.key == InputKeyOk) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// event timeout
|
||||
}
|
||||
|
||||
// common code, for example, force update UI
|
||||
// view_port_update(view_port);
|
||||
|
||||
release_mutex(&state_mutex, state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
0
flp/.gitignore
vendored
0
flp/.gitignore
vendored
14
flp/Pipfile
14
flp/Pipfile
@ -1,14 +0,0 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
black = "20.8b1"
|
||||
|
||||
[packages]
|
||||
pyserial = "3.4"
|
||||
click = "7.1.2"
|
||||
|
||||
[requires]
|
||||
python_version = "3.8"
|
142
flp/Pipfile.lock
generated
142
flp/Pipfile.lock
generated
@ -1,142 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "62bedeef792c73b899be0e307396e579f1af2d0c1d49dbccc252cc14e11e50d4"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.8"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
|
||||
"sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.1.2"
|
||||
},
|
||||
"pyserial": {
|
||||
"hashes": [
|
||||
"sha256:6e2d401fdee0eab996cf734e67773a0143b932772ca8b42451440cfed942c627",
|
||||
"sha256:e0770fadba80c31013896c7e6ef703f72e7834965954a78e71a3049488d4d7d8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.4"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
"sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41",
|
||||
"sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"
|
||||
],
|
||||
"version": "==1.4.4"
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea",
|
||||
"sha256:70b62ef1527c950db59062cda342ea224d772abdf6adc58b86a45421bab20a6b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==20.8b1"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
|
||||
"sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.1.2"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
|
||||
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
|
||||
],
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0",
|
||||
"sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"
|
||||
],
|
||||
"version": "==0.8.0"
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204",
|
||||
"sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162",
|
||||
"sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f",
|
||||
"sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb",
|
||||
"sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6",
|
||||
"sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7",
|
||||
"sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88",
|
||||
"sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99",
|
||||
"sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644",
|
||||
"sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a",
|
||||
"sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840",
|
||||
"sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067",
|
||||
"sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd",
|
||||
"sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4",
|
||||
"sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e",
|
||||
"sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89",
|
||||
"sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e",
|
||||
"sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc",
|
||||
"sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf",
|
||||
"sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341",
|
||||
"sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"
|
||||
],
|
||||
"version": "==2020.7.14"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f",
|
||||
"sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"
|
||||
],
|
||||
"version": "==0.10.1"
|
||||
},
|
||||
"typed-ast": {
|
||||
"hashes": [
|
||||
"sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
|
||||
"sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
|
||||
"sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
|
||||
"sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
|
||||
"sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
|
||||
"sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
|
||||
"sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
|
||||
"sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
|
||||
"sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
|
||||
"sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
|
||||
"sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
|
||||
"sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
|
||||
"sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
|
||||
"sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
|
||||
"sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
|
||||
"sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
|
||||
"sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
|
||||
"sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
|
||||
"sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
|
||||
"sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
|
||||
"sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
|
||||
],
|
||||
"version": "==1.4.1"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918",
|
||||
"sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c",
|
||||
"sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"
|
||||
],
|
||||
"version": "==3.7.4.3"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
from flipper import file
|
||||
from flipper.file import File
|
@ -1,122 +0,0 @@
|
||||
from enum import Enum
|
||||
|
||||
import serial
|
||||
|
||||
|
||||
class RemoteIOError(IOError):
|
||||
pass
|
||||
|
||||
|
||||
class UnsupportedOperation(RemoteIOError):
|
||||
# TODO: Tell more on error
|
||||
pass
|
||||
|
||||
|
||||
class ReadWriteError(RemoteIOError):
|
||||
pass
|
||||
|
||||
|
||||
class FileMode(Enum):
|
||||
READ = "r"
|
||||
WRITE = "w"
|
||||
# APPEND = "a" - Not Impl
|
||||
# READ_WRITE = "w+"
|
||||
# READ_APPEND = "a+"
|
||||
|
||||
|
||||
class File:
|
||||
opened: bool = False
|
||||
filename: str
|
||||
conn: serial.Serial
|
||||
mode = FileMode.READ
|
||||
|
||||
def _open(self):
|
||||
# Opening file on Flipper's end
|
||||
self.conn.write(f"f_open {self.filename} {self.mode}\n".encode())
|
||||
|
||||
# Checking, if everything is OK.
|
||||
self.conn.write(b"f_valid\n")
|
||||
return bool(int(self.conn.read_until().decode()))
|
||||
|
||||
def __init__(self, conn: serial.Serial, filename: str, mode=FileMode.READ):
|
||||
self.conn = conn
|
||||
self.mode = mode
|
||||
self.filename = filename
|
||||
|
||||
if not self._open():
|
||||
raise RemoteIOError
|
||||
self.opened = True
|
||||
|
||||
def lseek(self, size: int):
|
||||
self.conn.write(f"f_lseek {size}\n".encode())
|
||||
|
||||
def tell(self):
|
||||
self.conn.write(b"f_tell\n")
|
||||
return int(self.conn.read_until().decode())
|
||||
|
||||
def size(self):
|
||||
self.conn.write(b"f_size\n")
|
||||
return int(self.conn.read_until().decode())
|
||||
|
||||
def write(self, data: bytes):
|
||||
if self.mode != FileMode.WRITE:
|
||||
raise UnsupportedOperation
|
||||
self.conn.write(f"f_write {len(data)}\n".encode())
|
||||
self.conn.write(data)
|
||||
self.conn.write(b"\n")
|
||||
|
||||
if self.conn.read_until().decode().strip() != "OK":
|
||||
raise ReadWriteError
|
||||
|
||||
def read(self, size: int) -> bytes:
|
||||
self.conn.write(f"f_read {size}\n".encode())
|
||||
return self.conn.read(size)
|
||||
|
||||
def _close(self):
|
||||
self.conn.write(b"f_close\n")
|
||||
|
||||
def close(self):
|
||||
self._close()
|
||||
# TODO: Add termination of remote file process.
|
||||
del self
|
||||
|
||||
def read_all(self, block_size=128) -> bytes:
|
||||
"""
|
||||
Function to simplify reading of file over serial.
|
||||
|
||||
:return: content of file represented in `bytes`
|
||||
"""
|
||||
size = self.size()
|
||||
a = bytearray()
|
||||
seek = 0
|
||||
# Reading in blocks of block_size
|
||||
while seek < block_size * (size // block_size - 1):
|
||||
seek += block_size
|
||||
self.lseek(seek)
|
||||
a.extend(self.read(block_size))
|
||||
|
||||
seek += block_size
|
||||
self.lseek(seek)
|
||||
a.extend(self.read(size - seek)) # Appending mod
|
||||
|
||||
self.lseek(0) # Resetting seek to default-position
|
||||
|
||||
return bytes(a)
|
||||
|
||||
|
||||
def push(ser: serial.Serial, local_path, remote_path):
|
||||
with open(local_path, "rb") as local_f: # Reading local file
|
||||
a = local_f.read()
|
||||
|
||||
remote_f = File(ser, remote_path, FileMode.WRITE)
|
||||
remote_f.write(a)
|
||||
remote_f.close()
|
||||
|
||||
|
||||
def pull(ser: serial.Serial, remote_path, local_path):
|
||||
remote_f = File(ser, remote_path, FileMode.READ)
|
||||
|
||||
with open(local_path, "wb") as f:
|
||||
f.write(remote_f.read_all())
|
||||
|
||||
remote_f.close()
|
39
flp/flp.py
39
flp/flp.py
@ -1,39 +0,0 @@
|
||||
import flipper
|
||||
import serial
|
||||
import click
|
||||
|
||||
DEFAULT_TTY = "/dev/ttyUSB0"
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
|
||||
@cli.group()
|
||||
def fs():
|
||||
pass
|
||||
|
||||
|
||||
@fs.command()
|
||||
@click.argument("file_in", type=click.Path(exists=True))
|
||||
@click.argument("file_out")
|
||||
@click.option("--port", default=DEFAULT_TTY)
|
||||
def push(file_in, file_out, port):
|
||||
with serial.Serial(port, 115200, timeout=10) as p:
|
||||
flipper.file.push(p, file_in, file_out)
|
||||
print("OK.")
|
||||
|
||||
|
||||
@fs.command()
|
||||
@click.argument("file_in")
|
||||
@click.argument("file_out", type=click.Path())
|
||||
@click.option("--port", default=DEFAULT_TTY)
|
||||
def pull(file_in, file_out, port):
|
||||
with serial.Serial(port, 115200, timeout=10) as p:
|
||||
flipper.file.pull(p, file_in, file_out)
|
||||
print("OK.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
589
lib/ui/ui.cpp
589
lib/ui/ui.cpp
@ -1,589 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" {
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "u8g2_support.h"
|
||||
#include "u8g2/u8g2.h"
|
||||
}
|
||||
|
||||
#include "ui.h"
|
||||
#include "events.h"
|
||||
|
||||
// function draw basic layout -- single bmp
|
||||
void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area) {
|
||||
if(bitmap == NULL) {
|
||||
printf("[basic layout] no content\n");
|
||||
u8g2_SetFont(u8g2, u8g2_font_6x10_mf);
|
||||
u8g2_SetDrawColor(u8g2, 1);
|
||||
u8g2_SetFontMode(u8g2, 1);
|
||||
u8g2_DrawStr(u8g2, 2, 12, "no content");
|
||||
} else {
|
||||
u8g2_SetDrawColor(u8g2, 1);
|
||||
u8g2_DrawXBM(u8g2, 0, 0, area.x + area.width, area.y + area.height, (unsigned char*)bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area) {
|
||||
// TODO proper cleanup statusbar
|
||||
u8g2_SetDrawColor(u8g2, 0);
|
||||
u8g2_DrawBox(u8g2, 0, 0, area.x + area.width, area.y + area.height);
|
||||
|
||||
Block text_block = Block {
|
||||
width: area.width,
|
||||
height: area.height,
|
||||
margin_left: 0,
|
||||
margin_top: 0,
|
||||
padding_left: 3,
|
||||
padding_top: 7,
|
||||
background: 0,
|
||||
color: 1,
|
||||
font: (uint8_t*)u8g2_font_6x10_mf,
|
||||
};
|
||||
|
||||
draw_block(u8g2, text, text_block, area.x, area.y);
|
||||
}
|
||||
|
||||
// draw layout and switch between ui item by button and timer
|
||||
void LayoutComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
|
||||
switch(event->type) {
|
||||
// get button event
|
||||
case EventTypeButton:
|
||||
if(event->value.button.state) {
|
||||
for(size_t i = 0; i < this->actions_size; i++) {
|
||||
FlipperComponent* next = NULL;
|
||||
|
||||
switch(this->actions[i].action) {
|
||||
case LayoutActionUp:
|
||||
if(event->value.button.id == ButtonsUp) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
case LayoutActionDown:
|
||||
if(event->value.button.id == ButtonsDown) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
case LayoutActionLeft:
|
||||
if(event->value.button.id == ButtonsLeft) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
case LayoutActionRight:
|
||||
if(event->value.button.id == ButtonsRight) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
case LayoutActionOk:
|
||||
if(event->value.button.id == ButtonsOk) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
case LayoutActionBack:
|
||||
if(event->value.button.id == ButtonsBack) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
|
||||
// stub action
|
||||
case LayoutActionUsbDisconnect:
|
||||
if(event->value.button.id == ButtonsLeft) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
|
||||
case LayoutActionUsbConnect:
|
||||
if(event->value.button.id == ButtonsRight) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
if(next) {
|
||||
printf("[layout view] go to next item\n");
|
||||
Event send_event;
|
||||
send_event.type = EventTypeUiNext;
|
||||
next->handle(
|
||||
&send_event,
|
||||
store,
|
||||
u8g2,
|
||||
area
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EventTypeUsb: {
|
||||
printf("get usb event\n");
|
||||
|
||||
FlipperComponent* next = NULL;
|
||||
|
||||
if(event->value.usb == UsbEventConnect) {
|
||||
for(size_t i = 0; i < this->actions_size; i++) {
|
||||
if(this->actions[i].action == LayoutActionUsbConnect) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(event->value.usb == UsbEventDisconnect) {
|
||||
for(size_t i = 0; i < this->actions_size; i++) {
|
||||
if(this->actions[i].action == LayoutActionUsbDisconnect) {
|
||||
next = this->actions[i].item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(next) {
|
||||
printf("[layout view] go to next item\n");
|
||||
Event send_event;
|
||||
send_event.type = EventTypeUiNext;
|
||||
next->handle(
|
||||
&send_event,
|
||||
store,
|
||||
u8g2,
|
||||
area
|
||||
);
|
||||
}
|
||||
} break;
|
||||
|
||||
// start component from prev
|
||||
case EventTypeUiNext:
|
||||
printf("[layout view] start component %lX\n", (uint32_t)this);
|
||||
|
||||
if(this->timeout > 0) {
|
||||
// TODO start timer
|
||||
}
|
||||
|
||||
// set current item to self
|
||||
store->current_component = this;
|
||||
|
||||
this->wait_time = 0;
|
||||
|
||||
// render layout
|
||||
this->dirty = true;
|
||||
break;
|
||||
|
||||
case EventTypeTick:
|
||||
this->wait_time += event->value.tick_delta;
|
||||
|
||||
if(this->wait_time > this->timeout) {
|
||||
for(size_t i = 0; i < this->actions_size; i++) {
|
||||
if(this->actions[i].action == LayoutActionTimeout ||
|
||||
this->actions[i].action == LayoutActionEndOfCycle
|
||||
) {
|
||||
if(this->actions[i].item != NULL) {
|
||||
printf("[layout view] go to next item\n");
|
||||
Event send_event;
|
||||
send_event.type = EventTypeUiNext;
|
||||
this->actions[i].item->handle(
|
||||
&send_event,
|
||||
store,
|
||||
u8g2,
|
||||
area
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this->dirty) {
|
||||
this->draw_fn(this->data, u8g2, area);
|
||||
|
||||
store->dirty_screen = true;
|
||||
|
||||
this->dirty = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void BlinkerComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
|
||||
switch(event->type) {
|
||||
// get button event
|
||||
case EventTypeButton:
|
||||
if(event->value.button.state && event->value.button.id == ButtonsBack) {
|
||||
if(this->prev && this->prev != this) {
|
||||
printf("[blinker view] go back\n");
|
||||
|
||||
Event send_event;
|
||||
send_event.type = EventTypeUiNext;
|
||||
this->prev->handle(
|
||||
&send_event,
|
||||
store,
|
||||
u8g2,
|
||||
area
|
||||
);
|
||||
|
||||
this->prev = NULL;
|
||||
|
||||
store->led = ColorBlack;
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
this->active = false;
|
||||
} else {
|
||||
printf("[blinker view] no back/loop\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(event->value.button.state && event->value.button.id != ButtonsBack) {
|
||||
this->active = false;
|
||||
}
|
||||
|
||||
if(!event->value.button.state && event->value.button.id != ButtonsBack) {
|
||||
this->active = true;
|
||||
}
|
||||
break;
|
||||
|
||||
// start component from prev
|
||||
case EventTypeUiNext:
|
||||
printf("[blinker view] start component %lX\n", (uint32_t)this);
|
||||
|
||||
if(this->prev == NULL) {
|
||||
this->prev = store->current_component;
|
||||
}
|
||||
|
||||
// set current item to self
|
||||
store->current_component = this;
|
||||
|
||||
this->dirty = true;
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
this->active = false;
|
||||
break;
|
||||
|
||||
case EventTypeTick:
|
||||
if(this->active) {
|
||||
this->wait_time += event->value.tick_delta;
|
||||
|
||||
if(this->is_on) {
|
||||
if(this->wait_time > this->config.on_time) {
|
||||
this->wait_time = 0;
|
||||
this->is_on = false;
|
||||
}
|
||||
} else {
|
||||
if(this->wait_time > this->config.off_time) {
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
}
|
||||
}
|
||||
|
||||
store->led = this->is_on ? this->config.on_color : this->config.off_color;
|
||||
} else {
|
||||
store->led = ColorBlack;
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
}
|
||||
|
||||
if(this->dirty) {
|
||||
this->draw_fn(this->data, u8g2, area);
|
||||
|
||||
store->dirty_screen = true;
|
||||
|
||||
this->dirty = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void BlinkerComponentOnBtn::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
|
||||
switch(event->type) {
|
||||
// get button event
|
||||
case EventTypeButton:
|
||||
if(event->value.button.state && event->value.button.id == ButtonsBack) {
|
||||
if(this->prev && this->prev != this) {
|
||||
printf("[blinker view] go back\n");
|
||||
|
||||
Event send_event;
|
||||
send_event.type = EventTypeUiNext;
|
||||
this->prev->handle(
|
||||
&send_event,
|
||||
store,
|
||||
u8g2,
|
||||
area
|
||||
);
|
||||
|
||||
this->prev = NULL;
|
||||
|
||||
store->led = ColorBlack;
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
this->active = false;
|
||||
} else {
|
||||
printf("[blinker view] no back/loop\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(event->value.button.state && event->value.button.id != ButtonsBack) {
|
||||
this->active = true;
|
||||
}
|
||||
|
||||
if(!event->value.button.state && event->value.button.id != ButtonsBack) {
|
||||
this->active = false;
|
||||
}
|
||||
break;
|
||||
|
||||
// start component from prev
|
||||
case EventTypeUiNext:
|
||||
printf("[blinker view] start component %lX\n", (uint32_t)this);
|
||||
|
||||
if(this->prev == NULL) {
|
||||
this->prev = store->current_component;
|
||||
}
|
||||
|
||||
// set current item to self
|
||||
store->current_component = this;
|
||||
|
||||
this->dirty = true;
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
this->active = false;
|
||||
break;
|
||||
|
||||
case EventTypeTick:
|
||||
if(this->active) {
|
||||
this->wait_time += event->value.tick_delta;
|
||||
|
||||
if(this->is_on) {
|
||||
if(this->wait_time > this->config.on_time) {
|
||||
this->wait_time = 0;
|
||||
this->is_on = false;
|
||||
}
|
||||
} else {
|
||||
if(this->wait_time > this->config.off_time) {
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
}
|
||||
}
|
||||
|
||||
store->led = this->is_on ? this->config.on_color : this->config.off_color;
|
||||
} else {
|
||||
store->led = ColorBlack;
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
}
|
||||
|
||||
if(this->dirty) {
|
||||
this->draw_fn(this->data, u8g2, area);
|
||||
|
||||
store->dirty_screen = true;
|
||||
|
||||
this->dirty = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#define MENU_DRAW_LINES 4
|
||||
|
||||
Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y) {
|
||||
u8g2_SetDrawColor(u8g2, layout.background);
|
||||
u8g2_DrawBox(u8g2,
|
||||
x + layout.margin_left,
|
||||
y + layout.margin_top,
|
||||
layout.width, layout.height
|
||||
);
|
||||
|
||||
u8g2_SetDrawColor(u8g2, layout.color);
|
||||
u8g2_SetFont(u8g2, layout.font);
|
||||
if(text != NULL) {
|
||||
u8g2_DrawStr(u8g2,
|
||||
x + layout.margin_left + layout.padding_left,
|
||||
y + layout.margin_top + layout.padding_top,
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
x: x + layout.margin_left + layout.width,
|
||||
y: y + layout.margin_top + layout.height
|
||||
};
|
||||
}
|
||||
|
||||
void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area) {
|
||||
// u8g2_ClearBuffer(u8g2);
|
||||
// clear area
|
||||
u8g2_SetDrawColor(u8g2, 0);
|
||||
u8g2_DrawBox(u8g2, area.x, area.y, area.width, area.height);
|
||||
|
||||
u8g2_SetFontMode(u8g2, 1);
|
||||
|
||||
uint8_t list_start = ctx->current - ctx->cursor;
|
||||
uint8_t list_size = ctx->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : ctx->size;
|
||||
|
||||
// draw header
|
||||
/*
|
||||
Point next = draw_block(u8g2, (const char*)data->name, Block {
|
||||
width: 128,
|
||||
height: 14,
|
||||
margin_left: 0,
|
||||
margin_top: 0,
|
||||
padding_left: 4,
|
||||
padding_top: 13,
|
||||
background: 1,
|
||||
color: 0,
|
||||
font: (uint8_t*)u8g2_font_helvB14_tf,
|
||||
}, area.x, area.y);
|
||||
*/
|
||||
|
||||
Point next = {area.x, area.y};
|
||||
|
||||
for(size_t i = 0; i < list_size; i++) {
|
||||
next = draw_block(u8g2, (const char*)ctx->list[list_start + i].name, Block {
|
||||
width: 128,
|
||||
height: 15,
|
||||
margin_left: 0,
|
||||
margin_top: i == 0 ? 2 : 0,
|
||||
padding_left: 2,
|
||||
padding_top: 12,
|
||||
background: i == ctx->cursor ? 1 : 0,
|
||||
color: i == ctx->cursor ? 0 : 1,
|
||||
font: (uint8_t*)u8g2_font_7x14_tf,
|
||||
}, area.x, next.y);
|
||||
}
|
||||
|
||||
// u8g2_font_7x14_tf
|
||||
// u8g2_font_profont12_tf smallerbut cute
|
||||
// u8g2_font_samim_12_t_all орочий
|
||||
}
|
||||
|
||||
void MenuCtx::handle(MenuEvent event) {
|
||||
uint8_t menu_size = this->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : this->size;
|
||||
|
||||
switch(event) {
|
||||
case MenuEventDown: {
|
||||
if(this->current < (this->size - 1)) {
|
||||
this->current++;
|
||||
|
||||
if(this->cursor < menu_size - 2 || this->current == this->size - 1) {
|
||||
this->cursor++;
|
||||
}
|
||||
} else {
|
||||
this->current = 0;
|
||||
this->cursor = 0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case MenuEventUp: {
|
||||
if(this->current > 0) {
|
||||
this->current--;
|
||||
|
||||
if(this->cursor > 1 || this->current == 0) {
|
||||
this->cursor--;
|
||||
}
|
||||
|
||||
} else {
|
||||
this->current = this->size - 1;
|
||||
this->cursor = menu_size - 1;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void MenuCtx::reset() {
|
||||
this->current = 0;
|
||||
this->cursor = 0;
|
||||
}
|
||||
|
||||
// draw numenu and handle navigation
|
||||
void MenuComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
|
||||
switch(event->type) {
|
||||
// get button event
|
||||
case EventTypeButton: {
|
||||
if(event->value.button.id == ButtonsOk && event->value.button.state) {
|
||||
if(this->ctx.current < this->ctx.size) {
|
||||
FlipperComponent* next_item = (FlipperComponent*)this->ctx.list[this->ctx.current].item;
|
||||
|
||||
if(next_item) {
|
||||
store->is_fullscreen = false;
|
||||
|
||||
printf("[layout view] go to %d item\n", this->ctx.current);
|
||||
Event send_event;
|
||||
send_event.type = EventTypeUiNext;
|
||||
|
||||
next_item->handle(
|
||||
&send_event,
|
||||
store,
|
||||
u8g2,
|
||||
area
|
||||
);
|
||||
} else {
|
||||
printf("[menu view] no item at %d\n", this->ctx.current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(event->value.button.id == ButtonsDown && event->value.button.state) {
|
||||
this->ctx.handle(MenuEventDown);
|
||||
this->dirty = true;
|
||||
}
|
||||
|
||||
if(event->value.button.id == ButtonsUp && event->value.button.state) {
|
||||
this->ctx.handle(MenuEventUp);
|
||||
this->dirty = true;
|
||||
}
|
||||
|
||||
// go back item
|
||||
if(event->value.button.id == ButtonsBack && event->value.button.state) {
|
||||
if(this->prev && this->prev != this) {
|
||||
store->is_fullscreen = false;
|
||||
|
||||
printf("[menu view] go back\n");
|
||||
|
||||
this->ctx.reset();
|
||||
|
||||
Event send_event;
|
||||
send_event.type = EventTypeUiNext;
|
||||
this->prev->handle(
|
||||
&send_event,
|
||||
store,
|
||||
u8g2,
|
||||
area
|
||||
);
|
||||
|
||||
this->prev = NULL;
|
||||
} else {
|
||||
printf("[menu view] no back/loop\n");
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
// start component from prev
|
||||
case EventTypeUiNext:
|
||||
printf("[menu view] start component %lX (size %d)\n", (uint32_t)this, this->ctx.size);
|
||||
|
||||
// set prev item
|
||||
if(this->prev == NULL) {
|
||||
printf("[menu view] set prev element to %lX\n", (uint32_t)store->current_component);
|
||||
this->prev = store->current_component;
|
||||
}
|
||||
// set current item to self
|
||||
store->current_component = this;
|
||||
|
||||
store->is_fullscreen = true;
|
||||
|
||||
// render menu
|
||||
this->dirty = true;
|
||||
break;
|
||||
|
||||
case EventTypeTick:
|
||||
if(this->dirty) {
|
||||
draw_menu(&this->ctx, u8g2, area);
|
||||
store->dirty_screen = true;
|
||||
this->dirty = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
218
lib/ui/ui.h
218
lib/ui/ui.h
@ -1,218 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "u8g2_support.h"
|
||||
#include "u8g2/u8g2.h"
|
||||
}
|
||||
|
||||
#include "events.h"
|
||||
|
||||
typedef struct {
|
||||
void* item;
|
||||
const char* name;
|
||||
} MenuItem;
|
||||
|
||||
#include "vendor.h"
|
||||
|
||||
typedef enum {
|
||||
LayoutActionUp,
|
||||
LayoutActionDown,
|
||||
LayoutActionLeft,
|
||||
LayoutActionRight,
|
||||
LayoutActionOk,
|
||||
LayoutActionBack,
|
||||
LayoutActionTimeout,
|
||||
LayoutActionUsbConnect,
|
||||
LayoutActionUsbDisconnect,
|
||||
LayoutActionEndOfCycle
|
||||
} LayoutAction;
|
||||
|
||||
typedef struct {
|
||||
FlipperComponent* item;
|
||||
LayoutAction action;
|
||||
} ActionItem;
|
||||
|
||||
void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area);
|
||||
void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
class LayoutComponent: FlipperComponent {
|
||||
public:
|
||||
LayoutComponent(void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), ActionItem* actions, size_t actions_size, uint32_t timeout, const char* data) {
|
||||
this->data = data;
|
||||
this->actions = actions;
|
||||
this->actions_size = actions_size;
|
||||
this->timeout = timeout;
|
||||
this->draw_fn = draw_fn;
|
||||
|
||||
this->dirty = true;
|
||||
|
||||
this->wait_time = 0;
|
||||
}
|
||||
|
||||
virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
private:
|
||||
const char* data;
|
||||
ActionItem* actions;
|
||||
size_t actions_size;
|
||||
uint32_t timeout;
|
||||
|
||||
void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
uint32_t wait_time;
|
||||
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t on_time;
|
||||
Color on_color;
|
||||
uint32_t off_time;
|
||||
Color off_color;
|
||||
} BlinkerComponentConfig;
|
||||
|
||||
class BlinkerComponent: FlipperComponent {
|
||||
public:
|
||||
BlinkerComponent(
|
||||
void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area),
|
||||
BlinkerComponentConfig config,
|
||||
const char* data
|
||||
) {
|
||||
this->data = data;
|
||||
this->draw_fn = draw_fn;
|
||||
this->config = config;
|
||||
|
||||
this->dirty = true;
|
||||
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
this->active = false;
|
||||
this->prev = NULL;
|
||||
}
|
||||
|
||||
virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
private:
|
||||
const char* data;
|
||||
BlinkerComponentConfig config;
|
||||
|
||||
void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
uint32_t wait_time;
|
||||
|
||||
bool is_on;
|
||||
bool active;
|
||||
|
||||
bool dirty;
|
||||
FlipperComponent* prev;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t on_time;
|
||||
Color on_color;
|
||||
uint32_t off_time;
|
||||
Color off_color;
|
||||
} BlinkerComponentOnBtnConfig;
|
||||
|
||||
class BlinkerComponentOnBtn: FlipperComponent {
|
||||
public:
|
||||
BlinkerComponentOnBtn(
|
||||
void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area),
|
||||
BlinkerComponentOnBtnConfig config,
|
||||
const char* data
|
||||
) {
|
||||
this->data = data;
|
||||
this->draw_fn = draw_fn;
|
||||
this->config = config;
|
||||
|
||||
this->dirty = true;
|
||||
|
||||
this->wait_time = 0;
|
||||
this->is_on = true;
|
||||
this->active = false;
|
||||
this->prev = NULL;
|
||||
}
|
||||
|
||||
virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
private:
|
||||
const char* data;
|
||||
BlinkerComponentOnBtnConfig config;
|
||||
|
||||
void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
uint32_t wait_time;
|
||||
|
||||
bool is_on;
|
||||
bool active;
|
||||
|
||||
bool dirty;
|
||||
FlipperComponent* prev;
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
MenuEventUp,
|
||||
MenuEventDown
|
||||
} MenuEvent;
|
||||
|
||||
class MenuCtx {
|
||||
public:
|
||||
size_t size;
|
||||
size_t current;
|
||||
uint8_t cursor;
|
||||
MenuItem* list;
|
||||
|
||||
void handle(MenuEvent event);
|
||||
void reset();
|
||||
};
|
||||
|
||||
void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area);
|
||||
|
||||
class MenuComponent: FlipperComponent {
|
||||
public:
|
||||
MenuComponent(MenuItem* list, size_t size, const char* name) {
|
||||
this->ctx.size = size;
|
||||
this->ctx.current = 0;
|
||||
this->ctx.cursor = 0;
|
||||
|
||||
this->ctx.list = list;
|
||||
|
||||
this->name = name;
|
||||
this->prev = NULL;
|
||||
|
||||
this->dirty = true;
|
||||
}
|
||||
|
||||
|
||||
const char* name;
|
||||
FlipperComponent* prev;
|
||||
MenuCtx ctx;
|
||||
|
||||
|
||||
bool dirty;
|
||||
|
||||
virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} Point;
|
||||
|
||||
typedef struct {
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
uint8_t margin_left;
|
||||
uint8_t margin_top;
|
||||
uint8_t padding_left;
|
||||
uint8_t padding_top;
|
||||
uint8_t background;
|
||||
uint8_t color;
|
||||
uint8_t* font;
|
||||
} Block;
|
||||
|
||||
Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y);
|
Loading…
Reference in New Issue
Block a user