Add two-screen UI with controller and Lucide icons
Two screens switchable by tapping the Claude logo: - Usage screen: session and weekly utilization with animation - Controller screen: touch gesture HID keyboard controls Controller screen features: - Lucide icons for ESC, DEL, left/right arrow buttons - Gestures panel with hand icon header and hint list - Session usage bar with reset timer at bottom - Hold anywhere for voice dictation (space key) - Hidden Ctrl+Space on logo hold Also fixes stuck modifier keys with releaseAll() after each keystroke. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
94d55a88d2
commit
930055170f
@@ -91,6 +91,42 @@ lv_font_conv --font assets/DejaVuSansMono.ttf \
|
|||||||
|
|
||||||
Without these patches, fonts compile but render as invisible.
|
Without these patches, fonts compile but render as invisible.
|
||||||
|
|
||||||
|
## Converting Lucide icons
|
||||||
|
|
||||||
|
The controller screen uses [Lucide](https://lucide.dev) icons (the same icon set Anthropic uses). Icons are SVGs converted to RGB565 C arrays for LVGL.
|
||||||
|
|
||||||
|
1. Get Lucide SVGs from [github.com/lucide-icons/lucide](https://github.com/lucide-icons/lucide) (`icons/` directory)
|
||||||
|
|
||||||
|
2. Convert SVG to PNG at desired size:
|
||||||
|
```bash
|
||||||
|
inkscape icons/delete.svg --export-width=32 --export-height=32 \
|
||||||
|
--export-filename=assets/icon_delete.png --export-background-opacity=0
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Convert PNG to RGB565 C array:
|
||||||
|
```python
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
img = Image.open("assets/icon_delete.png").convert("RGBA")
|
||||||
|
bg = (0x1f, 0x1f, 0x1e) # panel background color
|
||||||
|
fg = (0xb0, 0xae, 0xa5) # icon stroke color
|
||||||
|
|
||||||
|
pixels = []
|
||||||
|
for y in range(img.height):
|
||||||
|
for x in range(img.width):
|
||||||
|
r, g, b, a = img.getpixel((x, y))
|
||||||
|
alpha = a / 255.0
|
||||||
|
out_r = int(fg[0] * alpha + bg[0] * (1 - alpha))
|
||||||
|
out_g = int(fg[1] * alpha + bg[1] * (1 - alpha))
|
||||||
|
out_b = int(fg[2] * alpha + bg[2] * (1 - alpha))
|
||||||
|
rgb565 = ((out_r >> 3) << 11) | ((out_g >> 2) << 5) | (out_b >> 3)
|
||||||
|
pixels.append(rgb565)
|
||||||
|
|
||||||
|
# Write as C array to firmware/src/icons.h
|
||||||
|
```
|
||||||
|
|
||||||
|
Current icons: `delete`, `arrow-left`, `arrow-right`, `circle-arrow-out-up-left` (escape), `hand` (gestures).
|
||||||
|
|
||||||
## Licensing gray area warning
|
## Licensing gray area warning
|
||||||
|
|
||||||
The software in this repository uses and adheres to the Anthropic brand guidelines and uses the same proprietary fonts that Anthropic has a licnese for but this software uses without permission as well as using assets from Anthropic such as the copyrighted Claude Code mascot head logo so even though the code in this repo is non-proprietary I will not license it myself under a copyleft license since this repo includes proprietary fonts and copyrighted assets. Please be aware of this if you fork or copy the code from this repo. **You have been warned!**
|
The software in this repository uses and adheres to the Anthropic brand guidelines and uses the same proprietary fonts that Anthropic has a licnese for but this software uses without permission as well as using assets from Anthropic such as the copyrighted Claude Code mascot head logo so even though the code in this repo is non-proprietary I will not license it myself under a copyleft license since this repo includes proprietary fonts and copyrighted assets. Please be aware of this if you fork or copy the code from this repo. **You have been warned!**
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 353 B |
Binary file not shown.
|
After Width: | Height: | Size: 348 B |
Binary file not shown.
|
After Width: | Height: | Size: 491 B |
Binary file not shown.
|
After Width: | Height: | Size: 762 B |
Binary file not shown.
|
After Width: | Height: | Size: 511 B |
+12
-6
@@ -7,8 +7,8 @@ static USBHIDKeyboard keyboard;
|
|||||||
// Gesture-to-key mapping table. Edit this to change controls.
|
// Gesture-to-key mapping table. Edit this to change controls.
|
||||||
struct gesture_mapping_t {
|
struct gesture_mapping_t {
|
||||||
gesture_t gesture;
|
gesture_t gesture;
|
||||||
uint8_t key; // HID_KEY_* constant (for pressRaw/releaseRaw)
|
uint8_t key;
|
||||||
uint8_t modifier; // KEY_LEFT_CTRL, KEY_LEFT_SHIFT, etc. (0 = none)
|
uint8_t modifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const gesture_mapping_t mappings[] = {
|
static const gesture_mapping_t mappings[] = {
|
||||||
@@ -16,16 +16,20 @@ static const gesture_mapping_t mappings[] = {
|
|||||||
{ GESTURE_SWIPE_DOWN, HID_KEY_ARROW_DOWN, 0 },
|
{ GESTURE_SWIPE_DOWN, HID_KEY_ARROW_DOWN, 0 },
|
||||||
{ GESTURE_SWIPE_LEFT, HID_KEY_TAB, KEY_LEFT_SHIFT },
|
{ GESTURE_SWIPE_LEFT, HID_KEY_TAB, KEY_LEFT_SHIFT },
|
||||||
{ GESTURE_SWIPE_RIGHT, HID_KEY_ENTER, 0 },
|
{ GESTURE_SWIPE_RIGHT, HID_KEY_ENTER, 0 },
|
||||||
{ GESTURE_DOUBLE_TAP_LOGO, HID_KEY_SPACE, KEY_LEFT_CTRL },
|
{ GESTURE_TAP_ESCAPE, HID_KEY_ESCAPE, 0 },
|
||||||
|
{ GESTURE_TAP_BACKSPACE, HID_KEY_BACKSPACE, 0 },
|
||||||
|
{ GESTURE_TAP_CTRL_SPACE, HID_KEY_SPACE, KEY_LEFT_CTRL },
|
||||||
|
{ GESTURE_TAP_ARROW_LEFT, HID_KEY_ARROW_LEFT, 0 },
|
||||||
|
{ GESTURE_TAP_ARROW_RIGHT, HID_KEY_ARROW_RIGHT, 0 },
|
||||||
};
|
};
|
||||||
#define MAPPING_COUNT (sizeof(mappings) / sizeof(mappings[0]))
|
#define MAPPING_COUNT (sizeof(mappings) / sizeof(mappings[0]))
|
||||||
|
|
||||||
// Hold gesture uses space key (press on start, release on end)
|
|
||||||
#define HOLD_KEY HID_KEY_SPACE
|
#define HOLD_KEY HID_KEY_SPACE
|
||||||
|
|
||||||
void hid_init(void) {
|
void hid_init(void) {
|
||||||
USB.begin();
|
USB.begin();
|
||||||
keyboard.begin();
|
keyboard.begin();
|
||||||
|
keyboard.releaseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hid_on_gesture(gesture_t gesture) {
|
void hid_on_gesture(gesture_t gesture) {
|
||||||
@@ -37,14 +41,16 @@ void hid_on_gesture(gesture_t gesture) {
|
|||||||
keyboard.releaseRaw(HOLD_KEY);
|
keyboard.releaseRaw(HOLD_KEY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (gesture == GESTURE_TOGGLE_SCREEN) {
|
||||||
|
return; // handled by touch.cpp, not a keystroke
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAPPING_COUNT; i++) {
|
for (int i = 0; i < MAPPING_COUNT; i++) {
|
||||||
if (mappings[i].gesture == gesture) {
|
if (mappings[i].gesture == gesture) {
|
||||||
if (mappings[i].modifier) keyboard.press(mappings[i].modifier);
|
if (mappings[i].modifier) keyboard.press(mappings[i].modifier);
|
||||||
keyboard.pressRaw(mappings[i].key);
|
keyboard.pressRaw(mappings[i].key);
|
||||||
delay(20);
|
delay(20);
|
||||||
keyboard.releaseRaw(mappings[i].key);
|
keyboard.releaseAll();
|
||||||
if (mappings[i].modifier) keyboard.release(mappings[i].modifier);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -1,16 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
// Gesture types
|
|
||||||
enum gesture_t {
|
enum gesture_t {
|
||||||
GESTURE_NONE,
|
GESTURE_NONE,
|
||||||
GESTURE_SWIPE_UP,
|
GESTURE_SWIPE_UP,
|
||||||
GESTURE_SWIPE_DOWN,
|
GESTURE_SWIPE_DOWN,
|
||||||
GESTURE_SWIPE_LEFT,
|
GESTURE_SWIPE_LEFT,
|
||||||
GESTURE_SWIPE_RIGHT,
|
GESTURE_SWIPE_RIGHT,
|
||||||
GESTURE_DOUBLE_TAP_LOGO,
|
|
||||||
GESTURE_HOLD_START,
|
GESTURE_HOLD_START,
|
||||||
GESTURE_HOLD_END,
|
GESTURE_HOLD_END,
|
||||||
|
GESTURE_TAP_ESCAPE,
|
||||||
|
GESTURE_TAP_BACKSPACE,
|
||||||
|
GESTURE_TAP_CTRL_SPACE,
|
||||||
|
GESTURE_TAP_ARROW_LEFT,
|
||||||
|
GESTURE_TAP_ARROW_RIGHT,
|
||||||
|
GESTURE_TOGGLE_SCREEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
void hid_init(void);
|
void hid_init(void);
|
||||||
|
|||||||
@@ -0,0 +1,319 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ICON_ESCAPE_W 32
|
||||||
|
#define ICON_ESCAPE_H 32
|
||||||
|
static const uint16_t icon_escape_data[1024] = {
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x4207, 0x9CD2, 0x8C70, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEE, 0x4A49, 0x18E3, 0x18E3, 0x2104, 0x6B4C,
|
||||||
|
0x7BCE, 0x6B6D, 0x5AEB, 0x39E7, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x9CD2, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD33, 0x18E3, 0x18E3, 0x4228, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xA513, 0x736D, 0x31A6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x8C70, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD74, 0x73AE, 0x18E3, 0x18E3, 0x2945, 0x9CD2,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD54, 0x736D, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x7BEE, 0xB574, 0xB574, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x2124, 0x2965, 0x4A48, 0x6B4C, 0xA4F2, 0xB574, 0xB574, 0xB574, 0x9CD2, 0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x7BEE, 0xB574, 0xB574, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0x5289, 0x9CF2, 0xB574, 0xB574, 0xAD33, 0x4207, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x7BEE, 0xB574, 0xB574, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x7BEE, 0xB574, 0xB574, 0xAD33, 0x39C7, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x7BEE, 0xB574, 0xB574, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x736D, 0xB574, 0xB574, 0x9CD2, 0x2124, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x7BEE, 0xB574, 0xB574, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x7BEE, 0xB574, 0xB574, 0x738D, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x7BEE, 0xB574, 0xB574, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2924, 0x9CF2, 0xB574, 0xAD54, 0x3185, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x7BEE, 0xB574, 0xAD74, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xB574, 0xB574, 0x738D, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x4A49, 0xAD33, 0x73AE, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0x9CF2, 0xB574, 0xA513, 0x2103, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x6B6D, 0xB574, 0xB574, 0x39E7, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x4A48, 0xB574, 0xB574, 0x5ACA, 0x18E3,
|
||||||
|
0x18E3, 0x2104, 0x4A28, 0x2945, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74,
|
||||||
|
0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x3185, 0xB574, 0xB574, 0x738D, 0x18E3,
|
||||||
|
0x18E3, 0x6B2C, 0xB574, 0x9CD2, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574,
|
||||||
|
0xAD74, 0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0xB574, 0xB574, 0x7BAE, 0x18E3,
|
||||||
|
0x18E3, 0x7BCE, 0xB574, 0xB574, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74,
|
||||||
|
0xAD74, 0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0xB574, 0xB574, 0x7BCE, 0x18E3,
|
||||||
|
0x18E3, 0x6B6D, 0xB574, 0xB574, 0x2965, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6,
|
||||||
|
0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x3185, 0xB574, 0xB574, 0x6B6D, 0x18E3,
|
||||||
|
0x18E3, 0x5AEB, 0xB574, 0xB574, 0x4A48, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x4228, 0xB574, 0xB574, 0x5AEA, 0x18E3,
|
||||||
|
0x18E3, 0x39E7, 0xB574, 0xB574, 0x6B4C, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x6B6D, 0xB574, 0xB574, 0x39E7, 0x18E3,
|
||||||
|
0x18E3, 0x2104, 0xA513, 0xB574, 0xA4F2, 0x2103, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0xA4F2, 0xB574, 0xA513, 0x2103, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x736D, 0xB574, 0xB574, 0x5289, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x5289, 0xB574, 0xB574, 0x6B6D, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x31A6, 0xAD54, 0xB574, 0x9CF2, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0xA4F2, 0xB574, 0xAD74, 0x3185, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x738D, 0xB574, 0xB574, 0x7BEE, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x7BEF, 0xB574, 0xB574, 0x736D, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x2124, 0x9CD2, 0xB574, 0xB574, 0x736D, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x736D, 0xB574, 0xB574, 0x9CD2, 0x2124, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6, 0xAD33, 0xB574, 0xB574, 0x7BEE, 0x2924, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x7BEF, 0xB574, 0xB574, 0xAD33, 0x39A6, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x4207, 0xAD33, 0xB574, 0xB574, 0x9CF2, 0x52AA, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x5289, 0xA4F2, 0xB574, 0xB574, 0xAD33, 0x4208, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C7, 0x9CD2, 0xB574, 0xB574, 0xB574, 0x9CF2, 0x6B6D, 0x4A48, 0x3185, 0x2944,
|
||||||
|
0x2104, 0x3185, 0x4228, 0x6B6D, 0xA4F2, 0xB574, 0xB574, 0xB574, 0x9CD2, 0x39A6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x738D, 0xAD54, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD74, 0x6B6D, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x3185, 0x738D, 0xA513, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xA513, 0x6B6D, 0x3185, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0x39E7, 0x5ACA, 0x738D, 0x73AD,
|
||||||
|
0x7BCE, 0x6B6D, 0x5AEA, 0x39E7, 0x2103, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ICON_DELETE_W 32
|
||||||
|
#define ICON_DELETE_H 32
|
||||||
|
static const uint16_t icon_delete_data[1024] = {
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39A6, 0x6B4C, 0x7BEE, 0x7BEF, 0x7BEF,
|
||||||
|
0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEE, 0x632C, 0x39C6, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x630B, 0xAD54, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD54, 0x5ACA, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0x738D, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD54, 0x39A6, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x83EF, 0xB574, 0xB574, 0xAD54, 0x5269, 0x2103, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0x5AAA, 0xB574, 0xB574, 0x632C, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x8C50, 0xB574, 0xB574, 0xA533, 0x4207, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2945, 0x9491, 0xB574, 0xB574, 0xA4F2, 0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6,
|
||||||
|
0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6, 0x39C6, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x3185, 0x9CD2, 0xB574, 0xB574, 0x9CB1, 0x3165, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6, 0xAD74,
|
||||||
|
0xAD74, 0x52AA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xAD74, 0x39C6, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x39C6, 0xA4F2, 0xB574, 0xB574, 0x9491, 0x2945, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6, 0xAD74,
|
||||||
|
0xB574, 0xAD74, 0x52AA, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x39C6, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x4208, 0xAD33, 0xB574, 0xB574, 0x8C30, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA,
|
||||||
|
0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x31A6, 0xAD54, 0xB574, 0xB574, 0x7BCE, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x52AA, 0xAD74, 0xB574, 0xAD74, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x738D, 0xB574, 0xB574, 0x738D, 0x2103, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x52AA, 0xAD74, 0xB574, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x736D, 0xB574, 0xB574, 0x738D, 0x2103, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x52AA, 0xAD74, 0xB574, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x31A6, 0xAD54, 0xB574, 0xB574, 0x7BCE, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x52AA, 0xAD74, 0xB574, 0xAD74, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x4208, 0xAD33, 0xB574, 0xB574, 0x8C30, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA,
|
||||||
|
0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x5ACA, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x39C6, 0xA4F2, 0xB574, 0xB574, 0x9491, 0x2945, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6, 0xAD74,
|
||||||
|
0xB574, 0xAD74, 0x52AA, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xB574, 0xAD74, 0x39C6, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x3185, 0x9CD2, 0xB574, 0xB574, 0x9CB1, 0x3165, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6, 0xAD74,
|
||||||
|
0xAD74, 0x52AA, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x52AA, 0xAD74, 0xAD74, 0x39C6, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2945, 0x9491, 0xB574, 0xB574, 0xA4F2, 0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6,
|
||||||
|
0x39C6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C6, 0x39C6, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x8C50, 0xB574, 0xB574, 0xA533, 0x4207, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0xB574, 0xB574, 0x7BEE, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x83EF, 0xB574, 0xB574, 0xAD54, 0x5269, 0x2103, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0x5ACA, 0xB574, 0xB574, 0x632C, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2103, 0x738D, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD54, 0x31A6, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x630B, 0xAD54, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xAD54, 0x5ACA, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39A6, 0x6B2C, 0x7BEE, 0x7BEF, 0x7BEF,
|
||||||
|
0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEE, 0x632C, 0x31A6, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ICON_ARROW_LEFT_W 32
|
||||||
|
#define ICON_ARROW_LEFT_H 32
|
||||||
|
static const uint16_t icon_arrow_left_data[1024] = {
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x6B4C,
|
||||||
|
0x6B4C, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574,
|
||||||
|
0xB574, 0x4228, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574,
|
||||||
|
0xA4F2, 0x2945, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513,
|
||||||
|
0x31A6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x8C70, 0xB574, 0xB574, 0xA533, 0x5AEB, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69,
|
||||||
|
0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A48, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x8C50, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0x6B2C, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x8C50, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0x6B2C, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x8C70, 0xB574, 0xB574, 0xA533, 0x5AEB, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69,
|
||||||
|
0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A48, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513, 0x31A6,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574, 0xA513,
|
||||||
|
0x31A6, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574, 0xB574,
|
||||||
|
0xA4F2, 0x2945, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x840F, 0xB574,
|
||||||
|
0xB574, 0x4228, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x6B4C,
|
||||||
|
0x6B4C, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ICON_ARROW_RIGHT_W 32
|
||||||
|
#define ICON_ARROW_RIGHT_H 32
|
||||||
|
static const uint16_t icon_arrow_right_data[1024] = {
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x6B4C,
|
||||||
|
0x6B4C, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x4228, 0xB574,
|
||||||
|
0xB574, 0x840F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2945, 0xA4F2,
|
||||||
|
0xB574, 0xB574, 0x840F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x3186,
|
||||||
|
0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x3186, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x3186, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x3186, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x3186, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x3186, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x4A48, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69,
|
||||||
|
0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x5AEB, 0xA513, 0xB574, 0xB574, 0x9491, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x6B2C, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0x8C50, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x6B2C, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0x8C50, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x4A48, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69,
|
||||||
|
0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x4A69, 0x5AEB, 0xA533, 0xB574, 0xB574, 0x9491, 0x2124, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x31A6, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x31A6, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x31A6, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x31A6, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x31A6, 0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x31A6,
|
||||||
|
0xA4F2, 0xB574, 0xB574, 0x842F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2945, 0xA4F2,
|
||||||
|
0xB574, 0xB574, 0x840F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x4228, 0xB574,
|
||||||
|
0xB574, 0x840F, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x6B4C,
|
||||||
|
0x6B4C, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ICON_HAND_W 24
|
||||||
|
#define ICON_HAND_H 24
|
||||||
|
static const uint16_t icon_hand_data[576] = {
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x2104, 0x6B6C, 0xA4F2, 0xA4F2, 0x6B4C, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x6B4C, 0xB574, 0xB574, 0xB574, 0xB574, 0x6B4C, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x6B6C, 0xA4F2,
|
||||||
|
0xA4F2, 0xAD33, 0xB574, 0x39E7, 0x4207, 0xB574, 0xAD33, 0xA4F2, 0xA4F2, 0x6B4C, 0x2104, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x6B4C, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0xB574,
|
||||||
|
0xB574, 0xB574, 0x6B4C, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xA4F2, 0xB574, 0x39E7,
|
||||||
|
0x4207, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x39E7, 0x4207, 0xB574, 0xAD33, 0xA513, 0xA513, 0x738D, 0x2124, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x18E3, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0x736D, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x39E7, 0x39C7, 0xB574, 0xA4F2, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xAD54, 0xAD54, 0x18E3, 0x18E3, 0x8C70, 0x8C70, 0x18E3,
|
||||||
|
0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0x18E3, 0x2104, 0x4207, 0x39C7, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x18E3, 0x4A28, 0x4A28, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x8C70, 0x8C70, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x18E3, 0x31A6, 0x9CD2, 0xB574, 0xB574, 0xB574, 0xB574, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3, 0x18E3, 0x9491, 0xB574, 0x94B1, 0xA4F2, 0xB574, 0xB574, 0x2945,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0xB574, 0xB574, 0x18E3,
|
||||||
|
0x2945, 0xB574, 0xA513, 0x2104, 0x2945, 0xAD53, 0xB574, 0x9491, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0xB574, 0xAD33, 0x18E3, 0x2104, 0xAD33, 0xAD74, 0x4A48, 0x18E3, 0x2945, 0x9491, 0x8C70,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x39C7, 0xB574, 0x9CB1, 0x18E3,
|
||||||
|
0x18E3, 0x630B, 0xB574, 0xAD54, 0x4A48, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x632C, 0xB574, 0x73AD, 0x18E3, 0x18E3, 0x18E3, 0x736D, 0xB574, 0xAD54, 0x4A48, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2924, 0xA513, 0xB574, 0x4228, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x736D, 0xB574, 0xAD54, 0x4A48, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x2103, 0x840F, 0xB574, 0x8C50, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x736D, 0xB574, 0xAD54, 0x52AA,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2924, 0x840F, 0xB574, 0xA513, 0x3186, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x6B4C, 0xB574, 0xB574, 0x8C50, 0x5289, 0x3186, 0x2124, 0x18E3, 0x18E3, 0x2124, 0x39C7,
|
||||||
|
0x632C, 0xA513, 0xB574, 0xA513, 0x4207, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x5289, 0xA513,
|
||||||
|
0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0xB574, 0x8C50, 0x3186, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x2124, 0x5ACA, 0x840F, 0x9CF2, 0xAD53, 0xB574, 0xB574, 0xAD33, 0x9CB1,
|
||||||
|
0x73AD, 0x4228, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3, 0x18E3,
|
||||||
|
};
|
||||||
+69
-38
@@ -1,49 +1,65 @@
|
|||||||
#include "touch.h"
|
#include "touch.h"
|
||||||
|
#include "ui.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "display_cfg.h"
|
#include "display_cfg.h"
|
||||||
|
|
||||||
// Thresholds (easy to tune)
|
// Thresholds
|
||||||
#define SWIPE_MIN_PX 50 // minimum distance to count as swipe
|
#define SWIPE_MIN_PX 50
|
||||||
#define SWIPE_MAX_CROSS_PX 30 // max perpendicular movement for a clean swipe
|
#define SWIPE_MAX_CROSS_PX 30
|
||||||
#define HOLD_TIME_MS 500 // time before touch becomes a hold
|
#define HOLD_TIME_MS 500
|
||||||
#define DOUBLE_TAP_MS 300 // max gap between taps for double-tap
|
#define LOGO_HOLD_TIME_MS 800 // longer hold to toggle screens
|
||||||
#define DOUBLE_TAP_PX 20 // max distance between taps
|
#define TAP_MAX_MOVE_PX 15
|
||||||
#define LOGO_X_MAX 60 // logo hit region (upper-left)
|
#define LOGO_X_MAX 60
|
||||||
#define LOGO_Y_MAX 60
|
#define LOGO_Y_MAX 60
|
||||||
|
|
||||||
extern LGFX lcd; // from main.cpp
|
extern LGFX lcd;
|
||||||
|
|
||||||
enum touch_state_t {
|
enum touch_state_t {
|
||||||
TS_IDLE,
|
TS_IDLE,
|
||||||
TS_DOWN, // finger just touched, waiting to classify
|
TS_DOWN,
|
||||||
TS_HOLDING, // classified as hold, space key is pressed
|
TS_HOLDING,
|
||||||
TS_SWIPING, // movement exceeded threshold, will be swipe on release
|
TS_SWIPING,
|
||||||
|
TS_LOGO_HOLD, // holding the logo to toggle screens
|
||||||
};
|
};
|
||||||
|
|
||||||
static touch_state_t state = TS_IDLE;
|
static touch_state_t state = TS_IDLE;
|
||||||
static uint16_t start_x, start_y;
|
static uint16_t start_x, start_y;
|
||||||
static uint16_t last_x, last_y; // track last known position for swipe classification
|
static uint16_t last_x, last_y;
|
||||||
static uint32_t down_time;
|
static uint32_t down_time;
|
||||||
|
|
||||||
// Double-tap tracking
|
|
||||||
static uint32_t last_tap_time = 0;
|
|
||||||
static uint16_t last_tap_x, last_tap_y;
|
|
||||||
|
|
||||||
static gesture_t classify_swipe(int dx, int dy) {
|
static gesture_t classify_swipe(int dx, int dy) {
|
||||||
int ax = abs(dx);
|
int ax = abs(dx);
|
||||||
int ay = abs(dy);
|
int ay = abs(dy);
|
||||||
|
if (ax > ay && ax >= SWIPE_MIN_PX && ay <= SWIPE_MAX_CROSS_PX)
|
||||||
if (ax > ay && ax >= SWIPE_MIN_PX && ay <= SWIPE_MAX_CROSS_PX) {
|
|
||||||
return dx > 0 ? GESTURE_SWIPE_RIGHT : GESTURE_SWIPE_LEFT;
|
return dx > 0 ? GESTURE_SWIPE_RIGHT : GESTURE_SWIPE_LEFT;
|
||||||
}
|
if (ay > ax && ay >= SWIPE_MIN_PX && ax <= SWIPE_MAX_CROSS_PX)
|
||||||
if (ay > ax && ay >= SWIPE_MIN_PX && ax <= SWIPE_MAX_CROSS_PX) {
|
|
||||||
return dy > 0 ? GESTURE_SWIPE_DOWN : GESTURE_SWIPE_UP;
|
return dy > 0 ? GESTURE_SWIPE_DOWN : GESTURE_SWIPE_UP;
|
||||||
|
return GESTURE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool in_logo(uint16_t x, uint16_t y) {
|
||||||
|
return x < LOGO_X_MAX && y < LOGO_Y_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect which controller zone was tapped
|
||||||
|
static gesture_t classify_zone_tap(uint16_t x, uint16_t y) {
|
||||||
|
// Logo tap = ESC
|
||||||
|
// Left column: ESC top (y 56-156), < bottom (y 166-266)
|
||||||
|
if (x < 108) {
|
||||||
|
if (y >= 56 && y < 156) return GESTURE_TAP_ESCAPE;
|
||||||
|
if (y >= 166 && y < 266) return GESTURE_TAP_ARROW_LEFT;
|
||||||
|
}
|
||||||
|
// Right column: DEL top, > bottom
|
||||||
|
if (x > 372) {
|
||||||
|
if (y >= 56 && y < 156) return GESTURE_TAP_BACKSPACE;
|
||||||
|
if (y >= 166 && y < 266) return GESTURE_TAP_ARROW_RIGHT;
|
||||||
}
|
}
|
||||||
return GESTURE_NONE;
|
return GESTURE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool in_logo_region(uint16_t x, uint16_t y) {
|
// Check if point is in a tap-only zone (should not trigger hold-for-space)
|
||||||
return x < LOGO_X_MAX && y < LOGO_Y_MAX;
|
static bool is_in_tap_zone(uint16_t x, uint16_t y) {
|
||||||
|
return classify_zone_tap(x, y) != GESTURE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void touch_init(void) {
|
void touch_init(void) {
|
||||||
@@ -60,6 +76,8 @@ void touch_tick(void) {
|
|||||||
if (touching) {
|
if (touching) {
|
||||||
start_x = x;
|
start_x = x;
|
||||||
start_y = y;
|
start_y = y;
|
||||||
|
last_x = x;
|
||||||
|
last_y = y;
|
||||||
down_time = now;
|
down_time = now;
|
||||||
state = TS_DOWN;
|
state = TS_DOWN;
|
||||||
}
|
}
|
||||||
@@ -67,17 +85,19 @@ void touch_tick(void) {
|
|||||||
|
|
||||||
case TS_DOWN:
|
case TS_DOWN:
|
||||||
if (!touching) {
|
if (!touching) {
|
||||||
// Released quickly - this is a tap (check for double-tap on logo)
|
bool is_tap = abs((int)last_x - (int)start_x) < TAP_MAX_MOVE_PX &&
|
||||||
if (in_logo_region(start_x, start_y) &&
|
abs((int)last_y - (int)start_y) < TAP_MAX_MOVE_PX;
|
||||||
(now - last_tap_time) < DOUBLE_TAP_MS &&
|
|
||||||
abs((int)start_x - (int)last_tap_x) < DOUBLE_TAP_PX &&
|
if (is_tap && in_logo(start_x, start_y)) {
|
||||||
abs((int)start_y - (int)last_tap_y) < DOUBLE_TAP_PX) {
|
// Logo tap toggles screen (works on both screens)
|
||||||
hid_on_gesture(GESTURE_DOUBLE_TAP_LOGO);
|
if (ui_is_controller_shown()) ui_show_usage();
|
||||||
last_tap_time = 0; // reset so triple-tap doesn't re-trigger
|
else ui_show_controller();
|
||||||
} else {
|
} else if (is_tap && ui_is_controller_shown()) {
|
||||||
last_tap_time = now;
|
// Zone taps only on controller screen
|
||||||
last_tap_x = start_x;
|
gesture_t zone = classify_zone_tap(start_x, start_y);
|
||||||
last_tap_y = start_y;
|
if (zone != GESTURE_NONE) {
|
||||||
|
hid_on_gesture(zone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
state = TS_IDLE;
|
state = TS_IDLE;
|
||||||
} else {
|
} else {
|
||||||
@@ -86,16 +106,21 @@ void touch_tick(void) {
|
|||||||
int dx = (int)x - (int)start_x;
|
int dx = (int)x - (int)start_x;
|
||||||
int dy = (int)y - (int)start_y;
|
int dy = (int)y - (int)start_y;
|
||||||
|
|
||||||
// Check if movement qualifies as a swipe
|
// Logo hold = Ctrl+Space (controller screen only)
|
||||||
|
if (in_logo(start_x, start_y) && ui_is_controller_shown() && (now - down_time) >= LOGO_HOLD_TIME_MS) {
|
||||||
|
hid_on_gesture(GESTURE_TAP_CTRL_SPACE);
|
||||||
|
state = TS_LOGO_HOLD;
|
||||||
|
}
|
||||||
|
// Everything below only on controller screen
|
||||||
|
else if (ui_is_controller_shown()) {
|
||||||
if (abs(dx) >= SWIPE_MIN_PX || abs(dy) >= SWIPE_MIN_PX) {
|
if (abs(dx) >= SWIPE_MIN_PX || abs(dy) >= SWIPE_MIN_PX) {
|
||||||
state = TS_SWIPING;
|
state = TS_SWIPING;
|
||||||
}
|
} else if (!in_logo(start_x, start_y) && !is_in_tap_zone(start_x, start_y) && (now - down_time) >= HOLD_TIME_MS) {
|
||||||
// Check if held long enough for a hold gesture
|
|
||||||
else if ((now - down_time) >= HOLD_TIME_MS) {
|
|
||||||
hid_on_gesture(GESTURE_HOLD_START);
|
hid_on_gesture(GESTURE_HOLD_START);
|
||||||
state = TS_HOLDING;
|
state = TS_HOLDING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_HOLDING:
|
case TS_HOLDING:
|
||||||
@@ -110,7 +135,6 @@ void touch_tick(void) {
|
|||||||
last_x = x;
|
last_x = x;
|
||||||
last_y = y;
|
last_y = y;
|
||||||
} else {
|
} else {
|
||||||
// Use last known position since getTouch returns garbage on release
|
|
||||||
int dx = (int)last_x - (int)start_x;
|
int dx = (int)last_x - (int)start_x;
|
||||||
int dy = (int)last_y - (int)start_y;
|
int dy = (int)last_y - (int)start_y;
|
||||||
gesture_t g = classify_swipe(dx, dy);
|
gesture_t g = classify_swipe(dx, dy);
|
||||||
@@ -120,5 +144,12 @@ void touch_tick(void) {
|
|||||||
state = TS_IDLE;
|
state = TS_IDLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TS_LOGO_HOLD:
|
||||||
|
// Wait for finger to lift after screen toggle
|
||||||
|
if (!touching) {
|
||||||
|
state = TS_IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+256
-43
@@ -1,6 +1,7 @@
|
|||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include "logo.h"
|
#include "logo.h"
|
||||||
|
#include "icons.h"
|
||||||
|
|
||||||
// Custom fonts
|
// Custom fonts
|
||||||
LV_FONT_DECLARE(font_tiempos_34);
|
LV_FONT_DECLARE(font_tiempos_34);
|
||||||
@@ -20,42 +21,43 @@ LV_FONT_DECLARE(font_mono_18);
|
|||||||
#define COL_AMBER lv_color_hex(0xd97757)
|
#define COL_AMBER lv_color_hex(0xd97757)
|
||||||
#define COL_RED lv_color_hex(0xc0392b)
|
#define COL_RED lv_color_hex(0xc0392b)
|
||||||
#define COL_BAR_BG lv_color_hex(0x2a2a28)
|
#define COL_BAR_BG lv_color_hex(0x2a2a28)
|
||||||
|
#define COL_ZONE_BG lv_color_hex(0x252524)
|
||||||
|
#define COL_ZONE_BRD lv_color_hex(0x3a3a38)
|
||||||
|
|
||||||
// Widget handles
|
// ---- Usage screen widgets ----
|
||||||
|
static lv_obj_t* usage_container;
|
||||||
static lv_obj_t* lbl_title;
|
static lv_obj_t* lbl_title;
|
||||||
|
|
||||||
static lv_obj_t* bar_session;
|
static lv_obj_t* bar_session;
|
||||||
static lv_obj_t* lbl_session_pct;
|
static lv_obj_t* lbl_session_pct;
|
||||||
static lv_obj_t* lbl_session_label;
|
static lv_obj_t* lbl_session_label;
|
||||||
static lv_obj_t* lbl_session_reset;
|
static lv_obj_t* lbl_session_reset;
|
||||||
|
|
||||||
static lv_obj_t* bar_weekly;
|
static lv_obj_t* bar_weekly;
|
||||||
static lv_obj_t* lbl_weekly_pct;
|
static lv_obj_t* lbl_weekly_pct;
|
||||||
static lv_obj_t* lbl_weekly_label;
|
static lv_obj_t* lbl_weekly_label;
|
||||||
static lv_obj_t* lbl_weekly_reset;
|
static lv_obj_t* lbl_weekly_reset;
|
||||||
|
|
||||||
static lv_obj_t* lbl_anim;
|
static lv_obj_t* lbl_anim;
|
||||||
|
|
||||||
// Logo image descriptor for LVGL
|
// ---- Controller screen widgets ----
|
||||||
|
static lv_obj_t* ctrl_container;
|
||||||
|
static lv_obj_t* ctrl_session_bar;
|
||||||
|
static lv_obj_t* ctrl_session_lbl;
|
||||||
|
static lv_obj_t* ctrl_reset_lbl;
|
||||||
|
|
||||||
|
// ---- Shared ----
|
||||||
static lv_image_dsc_t logo_dsc;
|
static lv_image_dsc_t logo_dsc;
|
||||||
|
static bool controller_shown = false;
|
||||||
|
|
||||||
// Animation state
|
// Animation state
|
||||||
static uint32_t anim_last_ms = 0;
|
static uint32_t anim_last_ms = 0;
|
||||||
static uint8_t anim_spinner_idx = 0;
|
static uint8_t anim_spinner_idx = 0;
|
||||||
static uint8_t anim_msg_idx = 0;
|
static uint8_t anim_msg_idx = 0;
|
||||||
static uint32_t anim_msg_start = 0;
|
static uint32_t anim_msg_start = 0;
|
||||||
#define ANIM_SPIN_MS 120 // spinner frame speed
|
#define ANIM_SPIN_MS 120
|
||||||
#define ANIM_MSG_MS 4000 // how long each message stays
|
#define ANIM_MSG_MS 4000
|
||||||
|
|
||||||
// Claude's spinner characters: · ✻ ✽ ✶ ✳ ✢
|
|
||||||
// UTF-8 encoded
|
|
||||||
static const char* const spinner_frames[] = {
|
static const char* const spinner_frames[] = {
|
||||||
"\xC2\xB7", // · (U+00B7)
|
"\xC2\xB7", "\xE2\x9C\xBB", "\xE2\x9C\xBD",
|
||||||
"\xE2\x9C\xBB", // ✻ (U+273B)
|
"\xE2\x9C\xB6", "\xE2\x9C\xB3", "\xE2\x9C\xA2",
|
||||||
"\xE2\x9C\xBD", // ✽ (U+273D)
|
|
||||||
"\xE2\x9C\xB6", // ✶ (U+2736)
|
|
||||||
"\xE2\x9C\xB3", // ✳ (U+2733)
|
|
||||||
"\xE2\x9C\xA2", // ✢ (U+2722)
|
|
||||||
};
|
};
|
||||||
#define SPINNER_COUNT 6
|
#define SPINNER_COUNT 6
|
||||||
|
|
||||||
@@ -143,33 +145,87 @@ static lv_obj_t* make_bar(lv_obj_t* parent, int x, int y, int w, int h) {
|
|||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_init(void) {
|
// Create a touch zone button on the controller screen
|
||||||
lv_obj_t* scr = lv_screen_active();
|
static lv_obj_t* make_zone(lv_obj_t* parent, int x, int y, int w, int h, const char* text) {
|
||||||
lv_obj_set_style_bg_color(scr, COL_BG, 0);
|
lv_obj_t* zone = lv_obj_create(parent);
|
||||||
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
lv_obj_set_pos(zone, x, y);
|
||||||
|
lv_obj_set_size(zone, w, h);
|
||||||
|
lv_obj_set_style_bg_color(zone, COL_PANEL, 0);
|
||||||
|
lv_obj_set_style_bg_opa(zone, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_radius(zone, 8, 0);
|
||||||
|
lv_obj_set_style_border_width(zone, 0, 0);
|
||||||
|
lv_obj_clear_flag(zone, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
// ---- Logo image ----
|
lv_obj_t* lbl = lv_label_create(zone);
|
||||||
logo_dsc.header.w = LOGO_WIDTH;
|
lv_label_set_text(lbl, text);
|
||||||
logo_dsc.header.h = LOGO_HEIGHT;
|
lv_obj_set_style_text_font(lbl, &font_styrene_14, 0);
|
||||||
logo_dsc.header.cf = LV_COLOR_FORMAT_RGB565;
|
lv_obj_set_style_text_color(lbl, COL_DIM, 0);
|
||||||
logo_dsc.header.stride = LOGO_WIDTH * 2;
|
lv_obj_center(lbl);
|
||||||
logo_dsc.data = (const uint8_t*)logo_data;
|
|
||||||
logo_dsc.data_size = LOGO_WIDTH * LOGO_HEIGHT * 2;
|
|
||||||
|
|
||||||
lv_obj_t* img = lv_image_create(scr);
|
return zone;
|
||||||
lv_image_set_src(img, &logo_dsc);
|
}
|
||||||
lv_obj_set_pos(img, 10, 4);
|
|
||||||
|
|
||||||
// ---- Title (vertically centered to 48px logo) ----
|
// Icon image descriptors (initialized in init_controller_screen)
|
||||||
lbl_title = lv_label_create(scr);
|
static lv_image_dsc_t icon_escape_dsc;
|
||||||
lv_label_set_text(lbl_title, "Claude Usage Tracker");
|
static lv_image_dsc_t icon_delete_dsc;
|
||||||
|
static lv_image_dsc_t icon_arrow_left_dsc;
|
||||||
|
static lv_image_dsc_t icon_arrow_right_dsc;
|
||||||
|
|
||||||
|
static void init_icon_dsc(lv_image_dsc_t* dsc, int w, int h, const uint16_t* data) {
|
||||||
|
dsc->header.w = w;
|
||||||
|
dsc->header.h = h;
|
||||||
|
dsc->header.cf = LV_COLOR_FORMAT_RGB565;
|
||||||
|
dsc->header.stride = w * 2;
|
||||||
|
dsc->data = (const uint8_t*)data;
|
||||||
|
dsc->data_size = w * h * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a touch zone with an icon centered in it
|
||||||
|
static lv_obj_t* make_zone_icon(lv_obj_t* parent, int x, int y, int w, int h, lv_image_dsc_t* icon) {
|
||||||
|
lv_obj_t* zone = lv_obj_create(parent);
|
||||||
|
lv_obj_set_pos(zone, x, y);
|
||||||
|
lv_obj_set_size(zone, w, h);
|
||||||
|
lv_obj_set_style_bg_color(zone, COL_PANEL, 0);
|
||||||
|
lv_obj_set_style_bg_opa(zone, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_radius(zone, 8, 0);
|
||||||
|
lv_obj_set_style_border_width(zone, 0, 0);
|
||||||
|
lv_obj_clear_flag(zone, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
lv_obj_t* img = lv_image_create(zone);
|
||||||
|
lv_image_set_src(img, icon);
|
||||||
|
lv_obj_center(img);
|
||||||
|
|
||||||
|
return zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a dim hint label for swipe directions
|
||||||
|
static lv_obj_t* make_hint(lv_obj_t* parent, int x, int y, const char* text) {
|
||||||
|
lv_obj_t* lbl = lv_label_create(parent);
|
||||||
|
lv_label_set_text(lbl, text);
|
||||||
|
lv_obj_set_style_text_font(lbl, &font_styrene_14, 0);
|
||||||
|
lv_obj_set_style_text_color(lbl, COL_DIM, 0);
|
||||||
|
lv_obj_set_pos(lbl, x, y);
|
||||||
|
return lbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_usage_screen(lv_obj_t* scr) {
|
||||||
|
usage_container = lv_obj_create(scr);
|
||||||
|
lv_obj_set_size(usage_container, 480, 320);
|
||||||
|
lv_obj_set_pos(usage_container, 0, 0);
|
||||||
|
lv_obj_set_style_bg_opa(usage_container, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(usage_container, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(usage_container, 0, 0);
|
||||||
|
lv_obj_clear_flag(usage_container, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
// Title
|
||||||
|
lbl_title = lv_label_create(usage_container);
|
||||||
|
lv_label_set_text(lbl_title, "Claude Usage");
|
||||||
lv_obj_set_style_text_font(lbl_title, &font_tiempos_34, 0);
|
lv_obj_set_style_text_font(lbl_title, &font_tiempos_34, 0);
|
||||||
lv_obj_set_style_text_color(lbl_title, COL_TEXT, 0);
|
lv_obj_set_style_text_color(lbl_title, COL_TEXT, 0);
|
||||||
lv_obj_set_pos(lbl_title, 66, 12);
|
lv_obj_set_pos(lbl_title, 66, 12);
|
||||||
|
|
||||||
// ---- Session panel ----
|
// Session panel
|
||||||
// Layout: percentage -> bar -> "5-Hour Session ... Resets in ..." below
|
lv_obj_t* p_session = make_panel(usage_container, 8, 56, 464, 100);
|
||||||
lv_obj_t* p_session = make_panel(scr, 8, 56, 464, 100);
|
|
||||||
|
|
||||||
lbl_session_pct = lv_label_create(p_session);
|
lbl_session_pct = lv_label_create(p_session);
|
||||||
lv_label_set_text(lbl_session_pct, "---%");
|
lv_label_set_text(lbl_session_pct, "---%");
|
||||||
@@ -189,12 +245,10 @@ void ui_init(void) {
|
|||||||
lv_label_set_text(lbl_session_reset, "---");
|
lv_label_set_text(lbl_session_reset, "---");
|
||||||
lv_obj_set_style_text_font(lbl_session_reset, &font_styrene_16, 0);
|
lv_obj_set_style_text_font(lbl_session_reset, &font_styrene_16, 0);
|
||||||
lv_obj_set_style_text_color(lbl_session_reset, COL_DIM, 0);
|
lv_obj_set_style_text_color(lbl_session_reset, COL_DIM, 0);
|
||||||
lv_obj_set_pos(lbl_session_reset, 440, 62);
|
|
||||||
lv_obj_set_style_text_align(lbl_session_reset, LV_TEXT_ALIGN_RIGHT, 0);
|
|
||||||
lv_obj_align(lbl_session_reset, LV_ALIGN_TOP_RIGHT, 0, 62);
|
lv_obj_align(lbl_session_reset, LV_ALIGN_TOP_RIGHT, 0, 62);
|
||||||
|
|
||||||
// ---- Weekly panel ----
|
// Weekly panel
|
||||||
lv_obj_t* p_weekly = make_panel(scr, 8, 166, 464, 100);
|
lv_obj_t* p_weekly = make_panel(usage_container, 8, 166, 464, 100);
|
||||||
|
|
||||||
lbl_weekly_pct = lv_label_create(p_weekly);
|
lbl_weekly_pct = lv_label_create(p_weekly);
|
||||||
lv_label_set_text(lbl_weekly_pct, "---%");
|
lv_label_set_text(lbl_weekly_pct, "---%");
|
||||||
@@ -216,18 +270,152 @@ void ui_init(void) {
|
|||||||
lv_obj_set_style_text_color(lbl_weekly_reset, COL_DIM, 0);
|
lv_obj_set_style_text_color(lbl_weekly_reset, COL_DIM, 0);
|
||||||
lv_obj_align(lbl_weekly_reset, LV_ALIGN_TOP_RIGHT, 0, 62);
|
lv_obj_align(lbl_weekly_reset, LV_ALIGN_TOP_RIGHT, 0, 62);
|
||||||
|
|
||||||
// ---- Animation at bottom ----
|
// Animation
|
||||||
lbl_anim = lv_label_create(scr);
|
lbl_anim = lv_label_create(usage_container);
|
||||||
lv_label_set_text(lbl_anim, "");
|
lv_label_set_text(lbl_anim, "");
|
||||||
lv_obj_set_style_text_font(lbl_anim, &font_mono_18, 0);
|
lv_obj_set_style_text_font(lbl_anim, &font_mono_18, 0);
|
||||||
lv_obj_set_style_text_color(lbl_anim, COL_ACCENT, 0);
|
lv_obj_set_style_text_color(lbl_anim, COL_ACCENT, 0);
|
||||||
lv_obj_align(lbl_anim, LV_ALIGN_BOTTOM_MID, 0, -16);
|
lv_obj_align(lbl_anim, LV_ALIGN_BOTTOM_MID, 0, -16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_controller_screen(lv_obj_t* scr) {
|
||||||
|
ctrl_container = lv_obj_create(scr);
|
||||||
|
lv_obj_set_size(ctrl_container, 480, 320);
|
||||||
|
lv_obj_set_pos(ctrl_container, 0, 0);
|
||||||
|
lv_obj_set_style_bg_opa(ctrl_container, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(ctrl_container, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(ctrl_container, 0, 0);
|
||||||
|
lv_obj_clear_flag(ctrl_container, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
// Title
|
||||||
|
lv_obj_t* lbl_ctrl_title = lv_label_create(ctrl_container);
|
||||||
|
lv_label_set_text(lbl_ctrl_title, "Claude Controller");
|
||||||
|
lv_obj_set_style_text_font(lbl_ctrl_title, &font_tiempos_34, 0);
|
||||||
|
lv_obj_set_style_text_color(lbl_ctrl_title, COL_TEXT, 0);
|
||||||
|
lv_obj_set_pos(lbl_ctrl_title, 66, 12);
|
||||||
|
|
||||||
|
// Shared layout math — matches usage screen geometry
|
||||||
|
#define MARGIN 8
|
||||||
|
#define CONTENT_Y 56
|
||||||
|
#define PANEL_H 100
|
||||||
|
#define GAP 10
|
||||||
|
#define CONTENT_W (480 - 2 * MARGIN) // 464
|
||||||
|
#define CONTENT_BOT (CONTENT_Y + 2 * PANEL_H + GAP) // 266
|
||||||
|
#define CONTENT_H (CONTENT_BOT - CONTENT_Y) // 210
|
||||||
|
#define SIDE_H ((CONTENT_H - GAP) / 2) // 100 (square)
|
||||||
|
#define SIDE_W SIDE_H
|
||||||
|
|
||||||
|
// Initialize icon descriptors
|
||||||
|
init_icon_dsc(&icon_escape_dsc, ICON_ESCAPE_W, ICON_ESCAPE_H, icon_escape_data);
|
||||||
|
init_icon_dsc(&icon_delete_dsc, ICON_DELETE_W, ICON_DELETE_H, icon_delete_data);
|
||||||
|
init_icon_dsc(&icon_arrow_left_dsc, ICON_ARROW_LEFT_W, ICON_ARROW_LEFT_H, icon_arrow_left_data);
|
||||||
|
init_icon_dsc(&icon_arrow_right_dsc, ICON_ARROW_RIGHT_W, ICON_ARROW_RIGHT_H, icon_arrow_right_data);
|
||||||
|
|
||||||
|
// Left column: ESC (top), < (bottom)
|
||||||
|
make_zone_icon(ctrl_container, MARGIN, CONTENT_Y, SIDE_W, SIDE_H, &icon_escape_dsc);
|
||||||
|
make_zone_icon(ctrl_container, MARGIN, CONTENT_Y + SIDE_H + GAP, SIDE_W, SIDE_H, &icon_arrow_left_dsc);
|
||||||
|
|
||||||
|
// Right column: DEL (top), > (bottom)
|
||||||
|
make_zone_icon(ctrl_container, 480 - MARGIN - SIDE_W, CONTENT_Y, SIDE_W, SIDE_H, &icon_delete_dsc);
|
||||||
|
make_zone_icon(ctrl_container, 480 - MARGIN - SIDE_W, CONTENT_Y + SIDE_H + GAP, SIDE_W, SIDE_H, &icon_arrow_right_dsc);
|
||||||
|
|
||||||
|
// Center hints box (full content height)
|
||||||
|
int cx = MARGIN + SIDE_W + GAP;
|
||||||
|
int cw = CONTENT_W - 2 * (SIDE_W + GAP);
|
||||||
|
lv_obj_t* center = make_zone(ctrl_container, cx, CONTENT_Y, cw, CONTENT_H, "");
|
||||||
|
|
||||||
|
// Vertically centered hint list
|
||||||
|
lv_obj_t* hint_list = lv_obj_create(center);
|
||||||
|
lv_obj_set_size(hint_list, cw - 24, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_center(hint_list);
|
||||||
|
lv_obj_set_style_bg_opa(hint_list, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(hint_list, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(hint_list, 0, 0);
|
||||||
|
lv_obj_set_style_pad_row(hint_list, 6, 0);
|
||||||
|
lv_obj_set_flex_flow(hint_list, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_set_flex_align(hint_list, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
lv_obj_clear_flag(hint_list, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
// Hand icon + "Gestures" header row
|
||||||
|
static lv_image_dsc_t icon_hand_dsc;
|
||||||
|
init_icon_dsc(&icon_hand_dsc, ICON_HAND_W, ICON_HAND_H, icon_hand_data);
|
||||||
|
|
||||||
|
lv_obj_t* header_row = lv_obj_create(hint_list);
|
||||||
|
lv_obj_set_width(header_row, lv_pct(100));
|
||||||
|
lv_obj_set_height(header_row, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_bg_opa(header_row, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(header_row, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(header_row, 0, 0);
|
||||||
|
lv_obj_set_style_pad_column(header_row, 8, 0);
|
||||||
|
lv_obj_set_flex_flow(header_row, LV_FLEX_FLOW_ROW);
|
||||||
|
lv_obj_set_flex_align(header_row, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
lv_obj_set_style_pad_bottom(header_row, 8, 0);
|
||||||
|
lv_obj_clear_flag(header_row, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
lv_obj_t* hand_img = lv_image_create(header_row);
|
||||||
|
lv_image_set_src(hand_img, &icon_hand_dsc);
|
||||||
|
|
||||||
|
lv_obj_t* gestures_lbl = lv_label_create(header_row);
|
||||||
|
lv_label_set_text(gestures_lbl, "Gestures");
|
||||||
|
lv_obj_set_style_text_font(gestures_lbl, &font_styrene_16, 0);
|
||||||
|
lv_obj_set_style_text_color(gestures_lbl, COL_TEXT, 0);
|
||||||
|
|
||||||
|
// Hint entries
|
||||||
|
make_hint(hint_list, 0, 0, "Swipe up/down: Arrow keys");
|
||||||
|
make_hint(hint_list, 0, 0, "Swipe left: Toggle mode");
|
||||||
|
make_hint(hint_list, 0, 0, "Swipe right: Enter key");
|
||||||
|
make_hint(hint_list, 0, 0, "Hold: Voice dictation");
|
||||||
|
|
||||||
|
// Usage info below content area: labels then bar
|
||||||
|
int info_y = CONTENT_BOT + GAP;
|
||||||
|
|
||||||
|
ctrl_session_lbl = lv_label_create(ctrl_container);
|
||||||
|
lv_label_set_text(ctrl_session_lbl, "---% of current session");
|
||||||
|
lv_obj_set_style_text_font(ctrl_session_lbl, &font_styrene_14, 0);
|
||||||
|
lv_obj_set_style_text_color(ctrl_session_lbl, COL_DIM, 0);
|
||||||
|
lv_obj_set_pos(ctrl_session_lbl, MARGIN, info_y);
|
||||||
|
|
||||||
|
ctrl_reset_lbl = lv_label_create(ctrl_container);
|
||||||
|
lv_label_set_text(ctrl_reset_lbl, "---");
|
||||||
|
lv_obj_set_style_text_font(ctrl_reset_lbl, &font_styrene_14, 0);
|
||||||
|
lv_obj_set_style_text_color(ctrl_reset_lbl, COL_DIM, 0);
|
||||||
|
lv_obj_align(ctrl_reset_lbl, LV_ALIGN_TOP_RIGHT, -MARGIN, info_y);
|
||||||
|
|
||||||
|
int bar_y = info_y + 18;
|
||||||
|
ctrl_session_bar = make_bar(ctrl_container, MARGIN, bar_y, CONTENT_W, 16);
|
||||||
|
|
||||||
|
// Start hidden
|
||||||
|
lv_obj_add_flag(ctrl_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_init(void) {
|
||||||
|
lv_obj_t* scr = lv_screen_active();
|
||||||
|
lv_obj_set_style_bg_color(scr, COL_BG, 0);
|
||||||
|
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||||
|
|
||||||
|
// Logo (shared, always visible, on top of both containers)
|
||||||
|
logo_dsc.header.w = LOGO_WIDTH;
|
||||||
|
logo_dsc.header.h = LOGO_HEIGHT;
|
||||||
|
logo_dsc.header.cf = LV_COLOR_FORMAT_RGB565;
|
||||||
|
logo_dsc.header.stride = LOGO_WIDTH * 2;
|
||||||
|
logo_dsc.data = (const uint8_t*)logo_data;
|
||||||
|
logo_dsc.data_size = LOGO_WIDTH * LOGO_HEIGHT * 2;
|
||||||
|
|
||||||
|
init_usage_screen(scr);
|
||||||
|
init_controller_screen(scr);
|
||||||
|
|
||||||
|
// Logo on top of both containers
|
||||||
|
lv_obj_t* img = lv_image_create(scr);
|
||||||
|
lv_image_set_src(img, &logo_dsc);
|
||||||
|
lv_obj_set_pos(img, 10, 4);
|
||||||
|
}
|
||||||
|
|
||||||
void ui_update(const UsageData* data) {
|
void ui_update(const UsageData* data) {
|
||||||
if (!data->valid) return;
|
if (!data->valid) return;
|
||||||
|
|
||||||
int s_pct = (int)(data->session_pct + 0.5f);
|
int s_pct = (int)(data->session_pct + 0.5f);
|
||||||
|
|
||||||
|
// Usage screen
|
||||||
lv_label_set_text_fmt(lbl_session_pct, "%d%%", s_pct);
|
lv_label_set_text_fmt(lbl_session_pct, "%d%%", s_pct);
|
||||||
lv_bar_set_value(bar_session, s_pct, LV_ANIM_ON);
|
lv_bar_set_value(bar_session, s_pct, LV_ANIM_ON);
|
||||||
lv_obj_set_style_bg_color(bar_session, pct_color(data->session_pct), LV_PART_INDICATOR);
|
lv_obj_set_style_bg_color(bar_session, pct_color(data->session_pct), LV_PART_INDICATOR);
|
||||||
@@ -243,18 +431,27 @@ void ui_update(const UsageData* data) {
|
|||||||
|
|
||||||
format_reset_time(data->weekly_reset_mins, buf, sizeof(buf));
|
format_reset_time(data->weekly_reset_mins, buf, sizeof(buf));
|
||||||
lv_label_set_text(lbl_weekly_reset, buf);
|
lv_label_set_text(lbl_weekly_reset, buf);
|
||||||
|
|
||||||
|
// Controller screen session info
|
||||||
|
lv_bar_set_value(ctrl_session_bar, s_pct, LV_ANIM_ON);
|
||||||
|
lv_obj_set_style_bg_color(ctrl_session_bar, pct_color(data->session_pct), LV_PART_INDICATOR);
|
||||||
|
lv_label_set_text_fmt(ctrl_session_lbl, "%d%% of current session", s_pct);
|
||||||
|
|
||||||
|
char rbuf[48];
|
||||||
|
format_reset_time(data->session_reset_mins, rbuf, sizeof(rbuf));
|
||||||
|
lv_label_set_text(ctrl_reset_lbl, rbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_tick_anim(void) {
|
void ui_tick_anim(void) {
|
||||||
|
if (controller_shown) return; // no animation on controller screen
|
||||||
|
|
||||||
uint32_t now = lv_tick_get();
|
uint32_t now = lv_tick_get();
|
||||||
|
|
||||||
// Switch to next message
|
|
||||||
if (now - anim_msg_start >= ANIM_MSG_MS) {
|
if (now - anim_msg_start >= ANIM_MSG_MS) {
|
||||||
anim_msg_idx = (anim_msg_idx + 1) % ANIM_MSG_COUNT;
|
anim_msg_idx = (anim_msg_idx + 1) % ANIM_MSG_COUNT;
|
||||||
anim_msg_start = now;
|
anim_msg_start = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spin the spinner
|
|
||||||
if (now - anim_last_ms >= ANIM_SPIN_MS) {
|
if (now - anim_last_ms >= ANIM_SPIN_MS) {
|
||||||
anim_last_ms = now;
|
anim_last_ms = now;
|
||||||
anim_spinner_idx = (anim_spinner_idx + 1) % SPINNER_COUNT;
|
anim_spinner_idx = (anim_spinner_idx + 1) % SPINNER_COUNT;
|
||||||
@@ -267,6 +464,22 @@ void ui_tick_anim(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ui_show_controller(void) {
|
||||||
|
lv_obj_add_flag(usage_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
lv_obj_clear_flag(ctrl_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
controller_shown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_show_usage(void) {
|
||||||
|
lv_obj_add_flag(ctrl_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
lv_obj_clear_flag(usage_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
controller_shown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ui_is_controller_shown(void) {
|
||||||
|
return controller_shown;
|
||||||
|
}
|
||||||
|
|
||||||
void ui_set_status(const char* text) {
|
void ui_set_status(const char* text) {
|
||||||
(void)text;
|
(void)text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,6 @@ void ui_init(void);
|
|||||||
void ui_update(const UsageData* data);
|
void ui_update(const UsageData* data);
|
||||||
void ui_tick_anim(void);
|
void ui_tick_anim(void);
|
||||||
void ui_set_status(const char* text);
|
void ui_set_status(const char* text);
|
||||||
|
void ui_show_controller(void);
|
||||||
|
void ui_show_usage(void);
|
||||||
|
bool ui_is_controller_shown(void);
|
||||||
|
|||||||
Reference in New Issue
Block a user