mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-20 15:35:05 +00:00
UX improvements
This commit is contained in:
parent
f8030b6dc2
commit
ac4190c29c
@ -83,10 +83,18 @@ class BootApp : public App {
|
|||||||
static int32_t bootThreadCallback() {
|
static int32_t bootThreadCallback() {
|
||||||
const auto start_time = kernel::getTicks();
|
const auto start_time = kernel::getTicks();
|
||||||
|
|
||||||
kernel::publishSystemEvent(kernel::SystemEvent::BootSplash);
|
// Give the UI some time to redraw
|
||||||
|
// If we don't do this, various init calls will read files and block SPI IO for the display
|
||||||
|
// This would result in a blank/black screen being shown during this phase of the boot process
|
||||||
|
// This works with 5 ms on a T-Lora Pager, so we give it 10 ms to be safe
|
||||||
|
kernel::delayMillis(10);
|
||||||
|
|
||||||
setupDisplay(); // Set backlight
|
setupDisplay(); // Set backlight
|
||||||
|
|
||||||
|
// This event will likely block as other systems are initialized
|
||||||
|
// e.g. Wi-Fi reads AP configs from SD card
|
||||||
|
kernel::publishSystemEvent(kernel::SystemEvent::BootSplash);
|
||||||
|
|
||||||
if (!setupUsbBootMode()) {
|
if (!setupUsbBootMode()) {
|
||||||
initFromBootApp();
|
initFromBootApp();
|
||||||
waitForMinimalSplashDuration(start_time);
|
waitForMinimalSplashDuration(start_time);
|
||||||
|
|||||||
@ -168,7 +168,7 @@ class CalculatorApp : public App {
|
|||||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||||
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
|
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
lv_obj_t* toolbar = tt::lvgl::toolbar_create(parent, context);
|
lv_obj_t* toolbar = lvgl::toolbar_create(parent, context);
|
||||||
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
||||||
|
|
||||||
lv_obj_t* wrapper = lv_obj_create(parent);
|
lv_obj_t* wrapper = lv_obj_create(parent);
|
||||||
@ -209,10 +209,10 @@ class CalculatorApp : public App {
|
|||||||
lv_obj_set_style_pad_all(btnm, 5, LV_PART_MAIN);
|
lv_obj_set_style_pad_all(btnm, 5, LV_PART_MAIN);
|
||||||
lv_obj_set_style_pad_row(btnm, 10, LV_PART_MAIN);
|
lv_obj_set_style_pad_row(btnm, 10, LV_PART_MAIN);
|
||||||
lv_obj_set_style_pad_column(btnm, 5, LV_PART_MAIN);
|
lv_obj_set_style_pad_column(btnm, 5, LV_PART_MAIN);
|
||||||
lv_obj_set_style_border_width(btnm, 0, LV_PART_MAIN);
|
lv_obj_set_style_border_width(btnm, 2, LV_PART_MAIN);
|
||||||
lv_obj_set_style_bg_color(btnm, lv_palette_main(LV_PALETTE_BLUE), LV_PART_ITEMS);
|
lv_obj_set_style_bg_color(btnm, lv_palette_main(LV_PALETTE_BLUE), LV_PART_ITEMS);
|
||||||
|
|
||||||
lv_obj_set_style_border_width(btnm, 0, LV_PART_MAIN);
|
// lv_obj_set_style_border_width(btnm, 0, LV_PART_MAIN);
|
||||||
if (lv_display_get_horizontal_resolution(nullptr) <= 240 || lv_display_get_vertical_resolution(nullptr) <= 240) { //small screens
|
if (lv_display_get_horizontal_resolution(nullptr) <= 240 || lv_display_get_vertical_resolution(nullptr) <= 240) { //small screens
|
||||||
lv_obj_set_size(btnm, lv_pct(100), lv_pct(60));
|
lv_obj_set_size(btnm, lv_pct(100), lv_pct(60));
|
||||||
} else { //large screens
|
} else { //large screens
|
||||||
|
|||||||
@ -33,28 +33,15 @@ class ChatApp : public App {
|
|||||||
lv_obj_scroll_to_y(msg_list, lv_obj_get_scroll_y(msg_list) + 20, LV_ANIM_ON);
|
lv_obj_scroll_to_y(msg_list, lv_obj_get_scroll_y(msg_list) + 20, LV_ANIM_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onQuickSendClicked(lv_event_t* e) {
|
|
||||||
auto* self = static_cast<ChatApp*>(lv_event_get_user_data(e));
|
|
||||||
auto* btn = static_cast<lv_obj_t*>(lv_event_get_target(e));
|
|
||||||
const char* message = lv_label_get_text(lv_obj_get_child(btn, 0));
|
|
||||||
|
|
||||||
if (message) {
|
|
||||||
self->addMessage(message);
|
|
||||||
if (!service::espnow::send(BROADCAST_ADDRESS, (const uint8_t*)message, strlen(message))) {
|
|
||||||
TT_LOG_E(TAG, "Failed to send message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onSendClicked(lv_event_t* e) {
|
static void onSendClicked(lv_event_t* e) {
|
||||||
auto* self = static_cast<ChatApp*>(lv_event_get_user_data(e));
|
auto* self = static_cast<ChatApp*>(lv_event_get_user_data(e));
|
||||||
auto* msg = lv_textarea_get_text(self->input_field);
|
auto* msg = lv_textarea_get_text(self->input_field);
|
||||||
auto msg_len = strlen(msg);
|
const auto msg_len = strlen(msg);
|
||||||
|
|
||||||
if (self->msg_list && msg && msg_len) {
|
if (self->msg_list && msg && msg_len) {
|
||||||
self->addMessage(msg);
|
self->addMessage(msg);
|
||||||
|
|
||||||
if (!service::espnow::send(BROADCAST_ADDRESS, (const uint8_t*)msg, msg_len)) {
|
if (!service::espnow::send(BROADCAST_ADDRESS, reinterpret_cast<const uint8_t*>(msg), msg_len)) {
|
||||||
TT_LOG_E(TAG, "Failed to send message");
|
TT_LOG_E(TAG, "Failed to send message");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,14 +51,14 @@ class ChatApp : public App {
|
|||||||
|
|
||||||
void onReceive(const esp_now_recv_info_t* receiveInfo, const uint8_t* data, int length) {
|
void onReceive(const esp_now_recv_info_t* receiveInfo, const uint8_t* data, int length) {
|
||||||
// Append \0 to make it a string
|
// Append \0 to make it a string
|
||||||
char* buffer = (char*)malloc(length + 1);
|
auto buffer = static_cast<char*>(malloc(length + 1));
|
||||||
memcpy(buffer, data, length);
|
memcpy(buffer, data, length);
|
||||||
buffer[length] = 0x00;
|
buffer[length] = 0x00;
|
||||||
std::string message_prefixed = std::string("Received: ") + buffer;
|
const std::string message_prefixed = std::string("Received: ") + buffer;
|
||||||
|
|
||||||
tt::lvgl::getSyncLock()->lock();
|
lvgl::getSyncLock()->lock();
|
||||||
addMessage(message_prefixed.c_str());
|
addMessage(message_prefixed.c_str());
|
||||||
tt::lvgl::getSyncLock()->unlock();
|
lvgl::getSyncLock()->unlock();
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
@ -82,7 +69,7 @@ public:
|
|||||||
// TODO: Move this to a configuration screen/app
|
// TODO: Move this to a configuration screen/app
|
||||||
static const uint8_t key[ESP_NOW_KEY_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
static const uint8_t key[ESP_NOW_KEY_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
auto config = service::espnow::EspNowConfig(
|
auto config = service::espnow::EspNowConfig(
|
||||||
(uint8_t*)key,
|
const_cast<uint8_t*>(key),
|
||||||
service::espnow::Mode::Station,
|
service::espnow::Mode::Station,
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
@ -105,58 +92,39 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onShow(AppContext& context, lv_obj_t* parent) override {
|
void onShow(AppContext& context, lv_obj_t* parent) override {
|
||||||
|
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
// Create toolbar
|
lvgl::toolbar_create(parent, context);
|
||||||
auto* toolbar = tt::lvgl::toolbar_create(parent, context);
|
|
||||||
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
|
||||||
const int toolbar_height = lv_obj_get_height(toolbar);
|
|
||||||
|
|
||||||
// Message list
|
// Message list
|
||||||
msg_list = lv_list_create(parent);
|
msg_list = lv_list_create(parent);
|
||||||
lv_obj_set_size(msg_list, lv_pct(75), lv_pct(43));
|
lv_obj_set_flex_grow(msg_list, 1);
|
||||||
lv_obj_align(msg_list, LV_ALIGN_TOP_LEFT, 5, toolbar_height + 45);
|
lv_obj_set_width(msg_list, LV_PCT(100));
|
||||||
|
lv_obj_set_flex_grow(msg_list, 1);
|
||||||
lv_obj_set_style_bg_color(msg_list, lv_color_hex(0x262626), 0);
|
lv_obj_set_style_bg_color(msg_list, lv_color_hex(0x262626), 0);
|
||||||
lv_obj_set_style_border_width(msg_list, 1, 0);
|
lv_obj_set_style_border_width(msg_list, 1, 0);
|
||||||
lv_obj_set_style_pad_all(msg_list, 5, 0);
|
lv_obj_set_style_pad_ver(msg_list, 0, 0);
|
||||||
|
lv_obj_set_style_pad_hor(msg_list, 4, 0);
|
||||||
// Quick message panel
|
|
||||||
auto* quick_panel = lv_obj_create(parent);
|
|
||||||
lv_obj_set_size(quick_panel, lv_pct(20), lv_pct(58));
|
|
||||||
lv_obj_align(quick_panel, LV_ALIGN_TOP_RIGHT, -5, toolbar_height + 15); // Adjusted to match
|
|
||||||
lv_obj_set_flex_flow(quick_panel, LV_FLEX_FLOW_COLUMN);
|
|
||||||
lv_obj_set_flex_align(quick_panel, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
|
||||||
lv_obj_set_style_pad_all(quick_panel, 5, 0);
|
|
||||||
|
|
||||||
// Quick message buttons
|
|
||||||
const char* quick_msgs[] = {":-)", "+1", ":-("};
|
|
||||||
for (size_t i = 0; i < sizeof(quick_msgs)/sizeof(quick_msgs[0]); i++) {
|
|
||||||
lv_obj_t* btn = lv_btn_create(quick_panel);
|
|
||||||
lv_obj_set_size(btn, lv_pct(75), 25);
|
|
||||||
lv_obj_add_event_cb(btn, onQuickSendClicked, LV_EVENT_CLICKED, this);
|
|
||||||
|
|
||||||
lv_obj_t* label = lv_label_create(btn);
|
|
||||||
lv_label_set_text(label, quick_msgs[i]);
|
|
||||||
lv_obj_center(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input panel
|
// Input panel
|
||||||
auto* input_panel = lv_obj_create(parent);
|
auto* bottom_wrapper = lv_obj_create(parent);
|
||||||
lv_obj_set_size(input_panel, lv_pct(95), 60);
|
lv_obj_set_flex_flow(bottom_wrapper, LV_FLEX_FLOW_ROW);
|
||||||
lv_obj_align(input_panel, LV_ALIGN_BOTTOM_MID, 0, -5);
|
lv_obj_set_size(bottom_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
lv_obj_set_flex_flow(input_panel, LV_FLEX_FLOW_ROW);
|
lv_obj_set_style_pad_all(bottom_wrapper, 0, 0);
|
||||||
lv_obj_set_flex_align(input_panel, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
lv_obj_set_style_pad_column(bottom_wrapper, 4, 0);
|
||||||
lv_obj_set_style_pad_all(input_panel, 5, 0);
|
lv_obj_set_style_border_opa(bottom_wrapper, 0, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
// Input field
|
// Input field
|
||||||
input_field = lv_textarea_create(input_panel);
|
input_field = lv_textarea_create(bottom_wrapper);
|
||||||
lv_obj_set_flex_grow(input_field, 1);
|
lv_obj_set_flex_grow(input_field, 1);
|
||||||
lv_obj_set_height(input_field, LV_PCT(100));
|
|
||||||
lv_textarea_set_placeholder_text(input_field, "Type a message...");
|
lv_textarea_set_placeholder_text(input_field, "Type a message...");
|
||||||
lv_textarea_set_one_line(input_field, true);
|
lv_textarea_set_one_line(input_field, true);
|
||||||
|
|
||||||
// Send button
|
// Send button
|
||||||
auto* send_btn = lv_btn_create(input_panel);
|
auto* send_btn = lv_button_create(bottom_wrapper);
|
||||||
lv_obj_set_size(send_btn, 80, LV_PCT(100));
|
lv_obj_set_style_margin_all(send_btn, 0, LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_margin_top(send_btn, 2, LV_STATE_DEFAULT); // Hack to fix alignment
|
||||||
lv_obj_add_event_cb(send_btn, onSendClicked, LV_EVENT_CLICKED, this);
|
lv_obj_add_event_cb(send_btn, onSendClicked, LV_EVENT_CLICKED, this);
|
||||||
|
|
||||||
auto* btn_label = lv_label_create(send_btn);
|
auto* btn_label = lv_label_create(send_btn);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user