diff --git a/build.yaml b/build.yaml index 527c527..eb70f48 100644 --- a/build.yaml +++ b/build.yaml @@ -5,6 +5,6 @@ include: - board: nice_nano_v2 shield: sweeple_right - board: nice_nano_v2 - shield: sweeple_dongle + shield: sweeple_dongle dongle_display - board: nice_nano_v2 shield: settings_reset diff --git a/config/boards/shields/dongle_display/CMakeLists.txt b/config/boards/shields/dongle_display/CMakeLists.txt new file mode 100644 index 0000000..dd4e60f --- /dev/null +++ b/config/boards/shields/dongle_display/CMakeLists.txt @@ -0,0 +1,18 @@ +if(CONFIG_ZMK_DISPLAY AND CONFIG_ZMK_DISPLAY_STATUS_SCREEN_CUSTOM AND ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)) + zephyr_library() + zephyr_library_sources(${ZEPHYR_BASE}/misc/empty_file.c) + zephyr_library_include_directories(${ZEPHYR_LVGL_MODULE_DIR}) + zephyr_library_include_directories(${ZEPHYR_BASE}/lib/gui/lvgl/) + zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) + zephyr_library_include_directories(${CMAKE_SOURCE_DIR}/include) + zephyr_library_sources(custom_status_screen.c) + zephyr_library_sources(widgets/battery_status.c) + zephyr_library_sources(widgets/bongo_cat.c) + zephyr_library_sources(widgets/bongo_cat_images.c) + target_sources_ifdef(CONFIG_ZMK_HID_INDICATORS app PRIVATE widgets/hid_indicators.c) + zephyr_library_sources(widgets/layer_status.c) + zephyr_library_sources(widgets/modifiers.c) + zephyr_library_sources(widgets/modifiers_sym.c) + zephyr_library_sources(widgets/output_status.c) + zephyr_library_sources(widgets/output_status_sym.c) +endif() diff --git a/config/boards/shields/dongle_display/Kconfig.defconfig b/config/boards/shields/dongle_display/Kconfig.defconfig new file mode 100644 index 0000000..f023d54 --- /dev/null +++ b/config/boards/shields/dongle_display/Kconfig.defconfig @@ -0,0 +1,48 @@ +# Copyright (c) 2024 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_DONGLE_DISPLAY + +choice ZMK_DISPLAY_STATUS_SCREEN + default ZMK_DISPLAY_STATUS_SCREEN_CUSTOM +endchoice + +config ZMK_DISPLAY_STATUS_SCREEN_CUSTOM + select LV_USE_LABEL + select LV_USE_IMG + select LV_USE_CANVAS + select LV_USE_ANIMIMG + select LV_USE_ANIMATION + select LV_USE_LINE + select LV_FONT_UNSCII_8 + select ZMK_WPM + imply ZMK_HID_INDICATORS + +config ZMK_DONGLE_DISPLAY_DONGLE_BATTERY + bool "Show also the battery level of the dongle" + depends on BT && (!ZMK_SPLIT_BLE || ZMK_SPLIT_ROLE_CENTRAL) + +config ZMK_DONGLE_DISPLAY_MAC_MODIFIERS + bool "Use MacOS modifier symbols instead of the Windows symbols" + +choice ZMK_DISPLAY_WORK_QUEUE + default ZMK_DISPLAY_WORK_QUEUE_DEDICATED +endchoice + +config LV_Z_MEM_POOL_SIZE + default 8192 + +config LV_Z_VDB_SIZE + default 64 + +config LV_DPI_DEF + default 148 + +config LV_Z_BITS_PER_PIXEL + default 1 + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_1 +endchoice + +endif \ No newline at end of file diff --git a/config/boards/shields/dongle_display/Kconfig.shield b/config/boards/shields/dongle_display/Kconfig.shield new file mode 100644 index 0000000..d99dd81 --- /dev/null +++ b/config/boards/shields/dongle_display/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2024 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_DONGLE_DISPLAY + def_bool $(shields_list_contains,dongle_display) \ No newline at end of file diff --git a/config/boards/shields/dongle_display/custom_status_screen.c b/config/boards/shields/dongle_display/custom_status_screen.c new file mode 100644 index 0000000..98f152f --- /dev/null +++ b/config/boards/shields/dongle_display/custom_status_screen.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "custom_status_screen.h" +#include "widgets/battery_status.h" +// #include "widgets/modifiers.h" +// #include "widgets/bongo_cat.h" +// #include "widgets/layer_status.h" +// #include "widgets/output_status.h" +// #include "widgets/hid_indicators.h" + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +// static struct zmk_widget_output_status output_status_widget; +// static struct zmk_widget_layer_status layer_status_widget; +static struct zmk_widget_dongle_battery_status dongle_battery_status_widget; +// static struct zmk_widget_modifiers modifiers_widget; +// static struct zmk_widget_bongo_cat bongo_cat_widget; + +// #if IS_ENABLED(CONFIG_ZMK_HID_INDICATORS) +// static struct zmk_widget_hid_indicators hid_indicators_widget; +// #endif + +lv_style_t global_style; + +lv_obj_t *zmk_display_status_screen() { + lv_obj_t *screen; + + screen = lv_obj_create(NULL); + + lv_style_init(&global_style); + lv_style_set_text_font(&global_style, &lv_font_unscii_8); + lv_style_set_text_letter_space(&global_style, 1); + lv_style_set_text_line_space(&global_style, 1); + lv_obj_add_style(screen, &global_style, LV_PART_MAIN); + + // zmk_widget_output_status_init(&output_status_widget, screen); + // lv_obj_align(zmk_widget_output_status_obj(&output_status_widget), LV_ALIGN_TOP_LEFT, 0, 0); + +// zmk_widget_bongo_cat_init(&bongo_cat_widget, screen); +// lv_obj_align(zmk_widget_bongo_cat_obj(&bongo_cat_widget), LV_ALIGN_BOTTOM_RIGHT, 0, -7); + +// zmk_widget_modifiers_init(&modifiers_widget, screen); +// lv_obj_align(zmk_widget_modifiers_obj(&modifiers_widget), LV_ALIGN_BOTTOM_LEFT, 0, 0); + +// #if IS_ENABLED(CONFIG_ZMK_HID_INDICATORS) +// zmk_widget_hid_indicators_init(&hid_indicators_widget, screen); +// lv_obj_align_to(zmk_widget_hid_indicators_obj(&hid_indicators_widget), zmk_widget_modifiers_obj(&modifiers_widget), LV_ALIGN_OUT_TOP_LEFT, 0, -2); +// #endif + +// zmk_widget_layer_status_init(&layer_status_widget, screen); +// // lv_obj_align(zmk_widget_layer_status_obj(&layer_status_widget), LV_ALIGN_BOTTOM_LEFT, 2, -18); +// lv_obj_align_to(zmk_widget_layer_status_obj(&layer_status_widget), zmk_widget_bongo_cat_obj(&bongo_cat_widget), LV_ALIGN_BOTTOM_LEFT, 0, 5); + + zmk_widget_dongle_battery_status_init(&dongle_battery_status_widget, screen); + lv_obj_align(zmk_widget_dongle_battery_status_obj(&dongle_battery_status_widget), LV_ALIGN_TOP_RIGHT, 0, 0); + + return screen; +} diff --git a/config/boards/shields/dongle_display/custom_status_screen.h b/config/boards/shields/dongle_display/custom_status_screen.h new file mode 100644 index 0000000..3a01be1 --- /dev/null +++ b/config/boards/shields/dongle_display/custom_status_screen.h @@ -0,0 +1,12 @@ +/* + * + * Copyright (c) 2024 The ZMK Contributors + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include + +lv_obj_t *zmk_display_status_screen(); \ No newline at end of file diff --git a/config/boards/shields/dongle_display/dongle_display.conf b/config/boards/shields/dongle_display/dongle_display.conf new file mode 100644 index 0000000..fce87ee --- /dev/null +++ b/config/boards/shields/dongle_display/dongle_display.conf @@ -0,0 +1,3 @@ +CONFIG_ZMK_DISPLAY=y +CONFIG_BT_BAS=n +CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING=y \ No newline at end of file diff --git a/config/boards/shields/dongle_display/dongle_display.overlay b/config/boards/shields/dongle_display/dongle_display.overlay new file mode 100644 index 0000000..3385843 --- /dev/null +++ b/config/boards/shields/dongle_display/dongle_display.overlay @@ -0,0 +1,5 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ \ No newline at end of file diff --git a/config/boards/shields/dongle_display/dongle_display.zmk.yml b/config/boards/shields/dongle_display/dongle_display.zmk.yml new file mode 100644 index 0000000..a7b6391 --- /dev/null +++ b/config/boards/shields/dongle_display/dongle_display.zmk.yml @@ -0,0 +1,7 @@ +file_format: "1" +id: dongle_display +name: dongle_display +type: shield +url: https://github.com/englmaxi/zmk-dongle-display +requires: + - i2c_oled diff --git a/config/boards/shields/dongle_display/widgets/battery_status.c b/config/boards/shields/dongle_display/widgets/battery_status.c new file mode 100644 index 0000000..fb8896a --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/battery_status.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include + +#include "battery_status.h" + +#if IS_ENABLED(CONFIG_ZMK_DONGLE_DISPLAY_DONGLE_BATTERY) + #define SOURCE_OFFSET 1 +#else + #define SOURCE_OFFSET 0 +#endif + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); + +struct battery_state { + uint8_t source; + uint8_t level; + bool usb_present; +}; + +static lv_color_t battery_image_buffer[ZMK_SPLIT_BLE_PERIPHERAL_COUNT + SOURCE_OFFSET][5 * 8]; + +static void draw_battery(lv_obj_t *canvas, uint8_t level, bool usb_present) { + lv_canvas_fill_bg(canvas, lv_color_black(), LV_OPA_COVER); + + lv_draw_rect_dsc_t rect_fill_dsc; + lv_draw_rect_dsc_init(&rect_fill_dsc); + + if (usb_present) { + rect_fill_dsc.bg_opa = LV_OPA_TRANSP; + rect_fill_dsc.border_color = lv_color_white(); + rect_fill_dsc.border_width = 1; + } + + lv_canvas_set_px(canvas, 0, 0, lv_color_white()); + lv_canvas_set_px(canvas, 4, 0, lv_color_white()); + + if (level <= 10 || usb_present) { + lv_canvas_draw_rect(canvas, 1, 2, 3, 5, &rect_fill_dsc); + } else if (level <= 30) { + lv_canvas_draw_rect(canvas, 1, 2, 3, 4, &rect_fill_dsc); + } else if (level <= 50) { + lv_canvas_draw_rect(canvas, 1, 2, 3, 3, &rect_fill_dsc); + } else if (level <= 70) { + lv_canvas_draw_rect(canvas, 1, 2, 3, 2, &rect_fill_dsc); + } else if (level <= 90) { + lv_canvas_draw_rect(canvas, 1, 2, 3, 1, &rect_fill_dsc); + } +} + +static void set_battery_symbol(lv_obj_t *widget, struct battery_state state) { + if (state.source >= ZMK_SPLIT_BLE_PERIPHERAL_COUNT + SOURCE_OFFSET) { + return; + } + LOG_DBG("source: %d, level: %d, usb: %d", state.source, state.level, state.usb_present); + lv_obj_t *symbol = lv_obj_get_child(widget, state.source * 2); + lv_obj_t *label = lv_obj_get_child(widget, state.source * 2 + 1); + + draw_battery(symbol, state.level, state.usb_present); + lv_label_set_text_fmt(label, "%4u%%", state.level); + + if (state.level > 0 || state.usb_present) { + lv_obj_clear_flag(symbol, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(label, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_add_flag(symbol, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(label, LV_OBJ_FLAG_HIDDEN); + } +} + +void battery_status_update_cb(struct battery_state state) { + struct zmk_widget_dongle_battery_status *widget; + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_battery_symbol(widget->obj, state); } +} + +static struct battery_state peripheral_battery_status_get_state(const zmk_event_t *eh) { + const struct zmk_peripheral_battery_state_changed *ev = as_zmk_peripheral_battery_state_changed(eh); + return (struct battery_state){ + .source = ev->source + SOURCE_OFFSET, + .level = ev->state_of_charge, + }; +} + +static struct battery_state central_battery_status_get_state(const zmk_event_t *eh) { + const struct zmk_battery_state_changed *ev = as_zmk_battery_state_changed(eh); + return (struct battery_state) { + .source = 0, + .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), +#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) + .usb_present = zmk_usb_is_powered(), +#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ + }; +} + +static struct battery_state battery_status_get_state(const zmk_event_t *eh) { + if (as_zmk_peripheral_battery_state_changed(eh) != NULL) { + return peripheral_battery_status_get_state(eh); + } else { + return central_battery_status_get_state(eh); + } +} + +ZMK_DISPLAY_WIDGET_LISTENER(widget_dongle_battery_status, struct battery_state, + battery_status_update_cb, battery_status_get_state) + +ZMK_SUBSCRIPTION(widget_dongle_battery_status, zmk_peripheral_battery_state_changed); + +#if IS_ENABLED(CONFIG_ZMK_DONGLE_DISPLAY_DONGLE_BATTERY) +#if !IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) + +ZMK_SUBSCRIPTION(widget_dongle_battery_status, zmk_battery_state_changed); +#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) +ZMK_SUBSCRIPTION(widget_dongle_battery_status, zmk_usb_conn_state_changed); +#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ +#endif /* !IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) */ +#endif /* IS_ENABLED(CONFIG_ZMK_DONGLE_DISPLAY_DONGLE_BATTERY) */ + +int zmk_widget_dongle_battery_status_init(struct zmk_widget_dongle_battery_status *widget, lv_obj_t *parent) { + widget->obj = lv_obj_create(parent); + + lv_obj_set_size(widget->obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + + for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT + SOURCE_OFFSET; i++) { + lv_obj_t *image_canvas = lv_canvas_create(widget->obj); + lv_obj_t *battery_label = lv_label_create(widget->obj); + + lv_canvas_set_buffer(image_canvas, battery_image_buffer[i], 5, 8, LV_IMG_CF_TRUE_COLOR); + + lv_obj_align(image_canvas, LV_ALIGN_TOP_RIGHT, 0, i * 10); + lv_obj_align(battery_label, LV_ALIGN_TOP_RIGHT, -7, i * 10); + + lv_obj_add_flag(image_canvas, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(battery_label, LV_OBJ_FLAG_HIDDEN); + } + + sys_slist_append(&widgets, &widget->node); + + widget_dongle_battery_status_init(); + + return 0; +} + +lv_obj_t *zmk_widget_dongle_battery_status_obj(struct zmk_widget_dongle_battery_status *widget) { + return widget->obj; +} diff --git a/config/boards/shields/dongle_display/widgets/battery_status.h b/config/boards/shields/dongle_display/widgets/battery_status.h new file mode 100644 index 0000000..2834582 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/battery_status.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +struct zmk_widget_dongle_battery_status { + sys_snode_t node; + lv_obj_t *obj; +}; + +int zmk_widget_dongle_battery_status_init(struct zmk_widget_dongle_battery_status *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_dongle_battery_status_obj(struct zmk_widget_dongle_battery_status *widget); \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/bongo_cat.c b/config/boards/shields/dongle_display/widgets/bongo_cat.c new file mode 100644 index 0000000..acfd033 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/bongo_cat.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include +#include + +#include "bongo_cat.h" + +#define SRC(array) (const void **)array, sizeof(array) / sizeof(lv_img_dsc_t *) + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); + +LV_IMG_DECLARE(bongo_cat_none); +LV_IMG_DECLARE(bongo_cat_left1); +LV_IMG_DECLARE(bongo_cat_left2); +LV_IMG_DECLARE(bongo_cat_right1); +LV_IMG_DECLARE(bongo_cat_right2); +LV_IMG_DECLARE(bongo_cat_both1); +LV_IMG_DECLARE(bongo_cat_both1_open); +LV_IMG_DECLARE(bongo_cat_both2); + +#define ANIMATION_SPEED_IDLE 10000 +const lv_img_dsc_t *idle_imgs[] = { + &bongo_cat_both1_open, + &bongo_cat_both1_open, + &bongo_cat_both1_open, + &bongo_cat_both1, +}; + +#define ANIMATION_SPEED_SLOW 2000 +const lv_img_dsc_t *slow_imgs[] = { + &bongo_cat_left1, + &bongo_cat_both1, + &bongo_cat_both1, + &bongo_cat_right1, + &bongo_cat_both1, + &bongo_cat_both1, + &bongo_cat_left1, + &bongo_cat_both1, + &bongo_cat_both1, +}; + +#define ANIMATION_SPEED_MID 500 +const lv_img_dsc_t *mid_imgs[] = { + &bongo_cat_left2, + &bongo_cat_left1, + &bongo_cat_none, + &bongo_cat_right2, + &bongo_cat_right1, + &bongo_cat_none, +}; + +#define ANIMATION_SPEED_FAST 200 +const lv_img_dsc_t *fast_imgs[] = { + &bongo_cat_both2, + &bongo_cat_both1, + &bongo_cat_none, + &bongo_cat_none, +}; + +struct bongo_cat_wpm_status_state { + uint8_t wpm; +}; + +enum anim_state { + anim_state_none, + anim_state_idle, + anim_state_slow, + anim_state_mid, + anim_state_fast +} current_anim_state; + +static void set_animation(lv_obj_t *animing, struct bongo_cat_wpm_status_state state) { + if (state.wpm < 5) { + if (current_anim_state != anim_state_idle) { + lv_animimg_set_src(animing, SRC(idle_imgs)); + lv_animimg_set_duration(animing, ANIMATION_SPEED_IDLE); + lv_animimg_set_repeat_count(animing, LV_ANIM_REPEAT_INFINITE); + lv_animimg_start(animing); + current_anim_state = anim_state_idle; + } + } else if (state.wpm < 30) { + if (current_anim_state != anim_state_slow) { + lv_animimg_set_src(animing, SRC(slow_imgs)); + lv_animimg_set_duration(animing, ANIMATION_SPEED_SLOW); + lv_animimg_set_repeat_count(animing, LV_ANIM_REPEAT_INFINITE); + lv_animimg_start(animing); + current_anim_state = anim_state_slow; + } + } else if (state.wpm < 70) { + if (current_anim_state != anim_state_mid) { + lv_animimg_set_src(animing, SRC(mid_imgs)); + lv_animimg_set_duration(animing, ANIMATION_SPEED_MID); + lv_animimg_set_repeat_count(animing, LV_ANIM_REPEAT_INFINITE); + lv_animimg_start(animing); + current_anim_state = anim_state_mid; + } + } else { + if (current_anim_state != anim_state_fast) { + lv_animimg_set_src(animing, SRC(fast_imgs)); + lv_animimg_set_duration(animing, ANIMATION_SPEED_FAST); + lv_animimg_set_repeat_count(animing, LV_ANIM_REPEAT_INFINITE); + lv_animimg_start(animing); + current_anim_state = anim_state_fast; + } + } +} + +struct bongo_cat_wpm_status_state bongo_cat_wpm_status_get_state(const zmk_event_t *eh) { + struct zmk_wpm_state_changed *ev = as_zmk_wpm_state_changed(eh); + return (struct bongo_cat_wpm_status_state) { .wpm = ev->state }; +}; + +void bongo_cat_wpm_status_update_cb(struct bongo_cat_wpm_status_state state) { + struct zmk_widget_bongo_cat *widget; + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_animation(widget->obj, state); } +} + +ZMK_DISPLAY_WIDGET_LISTENER(widget_bongo_cat, struct bongo_cat_wpm_status_state, + bongo_cat_wpm_status_update_cb, bongo_cat_wpm_status_get_state) + +ZMK_SUBSCRIPTION(widget_bongo_cat, zmk_wpm_state_changed); + +int zmk_widget_bongo_cat_init(struct zmk_widget_bongo_cat *widget, lv_obj_t *parent) { + widget->obj = lv_animimg_create(parent); + lv_obj_center(widget->obj); + + sys_slist_append(&widgets, &widget->node); + + widget_bongo_cat_init(); + + return 0; +} + +lv_obj_t *zmk_widget_bongo_cat_obj(struct zmk_widget_bongo_cat *widget) { + return widget->obj; +} \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/bongo_cat.h b/config/boards/shields/dongle_display/widgets/bongo_cat.h new file mode 100644 index 0000000..f79aa65 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/bongo_cat.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + #pragma once + +#include +#include + +struct zmk_widget_bongo_cat { + sys_snode_t node; + lv_obj_t *obj; +}; + +int zmk_widget_bongo_cat_init(struct zmk_widget_bongo_cat *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_bongo_cat_obj(struct zmk_widget_bongo_cat *widget); \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/bongo_cat_images.c b/config/boards/shields/dongle_display/widgets/bongo_cat_images.c new file mode 100644 index 0000000..ea5d472 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/bongo_cat_images.c @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + #include + + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_NONE +#define LV_ATTRIBUTE_IMG_BONGO_CAT_NONE +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_NONE uint8_t bongo_cat_none_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x18, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x24, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x43, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x40, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x40, 0x14, 0x10, 0x02, 0x00, 0x00, + 0xe0, 0x20, 0x00, 0x29, 0x82, 0x00, 0x00, + 0x1f, 0x10, 0x01, 0x02, 0x41, 0x00, 0x00, + 0x00, 0xfc, 0x03, 0x84, 0x21, 0x80, 0x00, + 0x00, 0x03, 0xe0, 0x04, 0x10, 0x80, 0x00, + 0x00, 0x00, 0x1f, 0x84, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xf0, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_none = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_none_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_LEFT1 +#define LV_ATTRIBUTE_IMG_BONGO_CAT_LEFT1 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_LEFT1 uint8_t bongo_cat_left1_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x14, 0x10, 0x02, 0x00, 0x00, + 0xe0, 0x04, 0x00, 0x29, 0x82, 0x00, 0x00, + 0x1f, 0x08, 0x01, 0x02, 0x41, 0x00, 0x00, + 0x00, 0xf0, 0x03, 0x84, 0x21, 0x80, 0x00, + 0x00, 0x10, 0x20, 0x04, 0x10, 0x80, 0x00, + 0x00, 0x10, 0x7f, 0x84, 0x00, 0x80, 0x00, + 0x00, 0x09, 0x80, 0x7e, 0x00, 0xc0, 0x00, + 0x00, 0x06, 0x00, 0x03, 0xf0, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_left1 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_left1_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_LEFT2 +#define LV_ATTRIBUTE_IMG_BONGO_CAT_LEFT2 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_LEFT2 uint8_t bongo_cat_left2_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x14, 0x10, 0x02, 0x00, 0x00, + 0xe0, 0x04, 0x00, 0x29, 0x82, 0x00, 0x00, + 0x1f, 0x08, 0x01, 0x02, 0x41, 0x00, 0x00, + 0x00, 0xf0, 0x03, 0x84, 0x21, 0x80, 0x00, + 0x00, 0x10, 0x20, 0x04, 0x10, 0x80, 0x00, + 0x00, 0x10, 0x7f, 0x84, 0x00, 0x80, 0x00, + 0x00, 0x09, 0x80, 0x7e, 0x00, 0xc0, 0x00, + 0x00, 0x66, 0x00, 0x03, 0xf0, 0x40, 0x00, + 0x00, 0x40, 0x80, 0x00, 0x0f, 0xe0, 0x00, + 0x00, 0x04, 0x80, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_left2 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_left2_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_RIGHT1 +#define LV_ATTRIBUTE_IMG_BONGO_CAT_RIGHT1 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_RIGHT1 uint8_t bongo_cat_right1_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x18, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x24, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x43, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x40, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x40, 0x14, 0x10, 0x02, 0x00, 0x00, + 0xe0, 0x20, 0x00, 0x28, 0x02, 0x00, 0x00, + 0x1f, 0x10, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xfc, 0x03, 0x80, 0x01, 0x80, 0x00, + 0x00, 0x03, 0xe0, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x1f, 0x82, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0x00, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x2f, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x40, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_right1 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_right1_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_RIGHT2 +#define LV_ATTRIBUTE_IMG_BONGO_CAT_RIGHT2 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_RIGHT2 uint8_t bongo_cat_right2_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x18, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x24, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x43, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x40, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x40, 0x14, 0x10, 0x02, 0x00, 0x00, + 0xe0, 0x20, 0x00, 0x28, 0x02, 0x00, 0x00, + 0x1f, 0x10, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xfc, 0x03, 0x80, 0x01, 0x80, 0x00, + 0x00, 0x03, 0xe0, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x1f, 0x82, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0x00, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x2f, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x40, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x33, 0x80, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_right2 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_right2_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH1 +#define LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH1 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH1 uint8_t bongo_cat_both1_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x14, 0x10, 0x02, 0x00, 0x00, + 0xe0, 0x04, 0x00, 0x28, 0x02, 0x00, 0x00, + 0x1f, 0x08, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xf0, 0x03, 0x80, 0x01, 0x80, 0x00, + 0x00, 0x10, 0x20, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x10, 0x7f, 0x82, 0x00, 0x80, 0x00, + 0x00, 0x09, 0x80, 0x7c, 0x00, 0xc0, 0x00, + 0x00, 0x06, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x2f, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x40, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_both1 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_both1_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH1_OPEN +#define LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH1_OPEN +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH1_OPEN uint8_t bongo_cat_both1_open_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x08, 0x00, 0x02, 0x00, 0x00, + 0xe0, 0x04, 0x00, 0x10, 0x02, 0x00, 0x00, + 0x1f, 0x08, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xf0, 0x03, 0x80, 0x01, 0x80, 0x00, + 0x00, 0x10, 0x20, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x10, 0x7f, 0x82, 0x00, 0x80, 0x00, + 0x00, 0x09, 0x80, 0x7c, 0x00, 0xc0, 0x00, + 0x00, 0x06, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x2f, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x40, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_both1_open = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_both1_open_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH2 +#define LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH2 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BONGO_CAT_BOTH2 uint8_t bongo_cat_both2_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x7c, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x07, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x08, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x14, 0x10, 0x02, 0x00, 0x00, + 0xe0, 0x04, 0x00, 0x28, 0x02, 0x00, 0x00, + 0x1f, 0x08, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xf0, 0x03, 0x80, 0x01, 0x80, 0x00, + 0x00, 0x10, 0x20, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x10, 0x7f, 0x82, 0x00, 0x80, 0x00, + 0x00, 0x09, 0x80, 0x7c, 0x00, 0xc0, 0x00, + 0x00, 0x66, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x40, 0x80, 0x08, 0x2f, 0xe0, 0x00, + 0x00, 0x04, 0x80, 0x04, 0x40, 0x3e, 0x00, + 0x00, 0x0c, 0x00, 0x33, 0x80, 0x01, 0xc0, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t bongo_cat_both2 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 50, + .header.h = 26, + .data_size = 190, + .data = bongo_cat_both2_map, +}; + + + diff --git a/config/boards/shields/dongle_display/widgets/hid_indicators.c b/config/boards/shields/dongle_display/widgets/hid_indicators.c new file mode 100644 index 0000000..afe7b6d --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/hid_indicators.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include + +#include "hid_indicators.h" + +#define LED_NLCK 0x01 +#define LED_CLCK 0x02 +#define LED_SLCK 0x04 + +struct hid_indicators_state { + uint8_t hid_indicators; +}; + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); + +static void set_hid_indicators(lv_obj_t *label, struct hid_indicators_state state) { + char text[7] = {}; + bool lock = false; + + if (state.hid_indicators & LED_CLCK) { + strncat(text, "C", 1); + lock = true; + } + if (state.hid_indicators & LED_NLCK) { + strncat(text, "N", 1); + lock = true; + } + if (state.hid_indicators & LED_SLCK) { + strncat(text, "S", 1); + lock = true; + } + if (lock) { + strncat(text, "LCK", 3); + } + + lv_label_set_text(label, text); +} + +void hid_indicators_update_cb(struct hid_indicators_state state) { + struct zmk_widget_hid_indicators *widget; + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_hid_indicators(widget->obj, state); } +} + +static struct hid_indicators_state hid_indicators_get_state(const zmk_event_t *eh) { + struct zmk_hid_indicators_changed *ev = as_zmk_hid_indicators_changed(eh); + return (struct hid_indicators_state) { + .hid_indicators = ev->indicators, + }; +} + +ZMK_DISPLAY_WIDGET_LISTENER(widget_hid_indicators, struct hid_indicators_state, + hid_indicators_update_cb, hid_indicators_get_state) + +ZMK_SUBSCRIPTION(widget_hid_indicators, zmk_hid_indicators_changed); + +int zmk_widget_hid_indicators_init(struct zmk_widget_hid_indicators *widget, lv_obj_t *parent) { + widget->obj = lv_label_create(parent); + + sys_slist_append(&widgets, &widget->node); + + widget_hid_indicators_init(); + + return 0; +} + +lv_obj_t *zmk_widget_hid_indicators_obj(struct zmk_widget_hid_indicators *widget) { + return widget->obj; +} \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/hid_indicators.h b/config/boards/shields/dongle_display/widgets/hid_indicators.h new file mode 100644 index 0000000..b52dc4d --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/hid_indicators.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + #pragma once + +#include +#include + +struct zmk_widget_hid_indicators { + sys_snode_t node; + lv_obj_t *obj; +}; + +int zmk_widget_hid_indicators_init(struct zmk_widget_hid_indicators *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_hid_indicators_obj(struct zmk_widget_hid_indicators *widget); \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/layer_status.c b/config/boards/shields/dongle_display/widgets/layer_status.c new file mode 100644 index 0000000..7f7afec --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/layer_status.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); + +struct layer_status_state { + uint8_t index; + const char *label; +}; + +static void set_layer_symbol(lv_obj_t *label, struct layer_status_state state) { + if (state.label == NULL) { + char text[7] = {}; + + sprintf(text, "%i", state.index); + + lv_label_set_text(label, text); + } else { + char text[13] = {}; + + snprintf(text, sizeof(text), "%s", state.label); + + lv_label_set_text(label, text); + } +} + +static void layer_status_update_cb(struct layer_status_state state) { + struct zmk_widget_layer_status *widget; + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_layer_symbol(widget->obj, state); } +} + +static struct layer_status_state layer_status_get_state(const zmk_event_t *eh) { + uint8_t index = zmk_keymap_highest_layer_active(); + return (struct layer_status_state) { + .index = index, + .label = zmk_keymap_layer_name(index) + }; +} + +ZMK_DISPLAY_WIDGET_LISTENER(widget_layer_status, struct layer_status_state, layer_status_update_cb, + layer_status_get_state) + +ZMK_SUBSCRIPTION(widget_layer_status, zmk_layer_state_changed); + +int zmk_widget_layer_status_init(struct zmk_widget_layer_status *widget, lv_obj_t *parent) { + widget->obj = lv_label_create(parent); + + sys_slist_append(&widgets, &widget->node); + + widget_layer_status_init(); + return 0; +} + +lv_obj_t *zmk_widget_layer_status_obj(struct zmk_widget_layer_status *widget) { + return widget->obj; +} \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/layer_status.h b/config/boards/shields/dongle_display/widgets/layer_status.h new file mode 100644 index 0000000..3bc592c --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/layer_status.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +struct zmk_widget_layer_status { + sys_snode_t node; + lv_obj_t *obj; +}; + +int zmk_widget_layer_status_init(struct zmk_widget_layer_status *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_layer_status_obj(struct zmk_widget_layer_status *widget); \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/modifiers.c b/config/boards/shields/dongle_display/widgets/modifiers.c new file mode 100644 index 0000000..5aac8e2 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/modifiers.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include +#include +#include + +#include "modifiers.h" + +struct modifiers_state { + uint8_t modifiers; +}; + +struct modifier_symbol { + uint8_t modifier; + const lv_img_dsc_t *symbol_dsc; + lv_obj_t *symbol; + lv_obj_t *selection_line; + bool is_active; +}; + +LV_IMG_DECLARE(control_icon); +struct modifier_symbol ms_control = { + .modifier = MOD_LCTL | MOD_RCTL, + .symbol_dsc = &control_icon, +}; + +LV_IMG_DECLARE(shift_icon); +struct modifier_symbol ms_shift = { + .modifier = MOD_LSFT | MOD_RSFT, + .symbol_dsc = &shift_icon, +}; + +#if IS_ENABLED(CONFIG_ZMK_DONGLE_DISPLAY_MAC_MODIFIERS) +LV_IMG_DECLARE(opt_icon); +struct modifier_symbol ms_opt = { + .modifier = MOD_LALT | MOD_RALT, + .symbol_dsc = &opt_icon, +}; + +LV_IMG_DECLARE(cmd_icon); +struct modifier_symbol ms_cmd = { + .modifier = MOD_LGUI | MOD_RGUI, + .symbol_dsc = &cmd_icon, +}; + +struct modifier_symbol *modifier_symbols[] = { + // this order determines the order of the symbols + &ms_control, + &ms_opt, + &ms_cmd, + &ms_shift +}; +#else +LV_IMG_DECLARE(alt_icon); +struct modifier_symbol ms_alt = { + .modifier = MOD_LALT | MOD_RALT, + .symbol_dsc = &alt_icon, +}; + +LV_IMG_DECLARE(win_icon); +struct modifier_symbol ms_win = { + .modifier = MOD_LGUI | MOD_RGUI, + .symbol_dsc = &win_icon, +}; + +struct modifier_symbol *modifier_symbols[] = { + // this order determines the order of the symbols + &ms_win, + &ms_alt, + &ms_control, + &ms_shift +}; +#endif + +#define NUM_SYMBOLS (sizeof(modifier_symbols) / sizeof(struct modifier_symbol *)) + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); + +static void anim_y_cb(void *var, int32_t v) { + lv_obj_set_y(var, v); +} + +static void move_object_y(void *obj, int32_t from, int32_t to) { + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, obj); + lv_anim_set_time(&a, 200); // will be replaced with lv_anim_set_duration + lv_anim_set_exec_cb(&a, anim_y_cb); + lv_anim_set_path_cb(&a, lv_anim_path_overshoot); + lv_anim_set_values(&a, from, to); + lv_anim_start(&a); +} + +static void set_modifiers(lv_obj_t *widget, struct modifiers_state state) { + for (int i = 0; i < NUM_SYMBOLS; i++) { + bool mod_is_active = state.modifiers & modifier_symbols[i]->modifier; + + if (mod_is_active && !modifier_symbols[i]->is_active) { + move_object_y(modifier_symbols[i]->symbol, 1, 0); + move_object_y(modifier_symbols[i]->selection_line, SIZE_SYMBOLS + 4, SIZE_SYMBOLS + 2); + modifier_symbols[i]->is_active = true; + } else if (!mod_is_active && modifier_symbols[i]->is_active) { + move_object_y(modifier_symbols[i]->symbol, 0, 1); + move_object_y(modifier_symbols[i]->selection_line, SIZE_SYMBOLS + 2, SIZE_SYMBOLS + 4); + modifier_symbols[i]->is_active = false; + } + } +} + +void modifiers_update_cb(struct modifiers_state state) { + struct zmk_widget_modifiers *widget; + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_modifiers(widget->obj, state); } +} + +static struct modifiers_state modifiers_get_state(const zmk_event_t *eh) { + return (struct modifiers_state) { + .modifiers = zmk_hid_get_explicit_mods() + }; +} + +ZMK_DISPLAY_WIDGET_LISTENER(widget_modifiers, struct modifiers_state, + modifiers_update_cb, modifiers_get_state) + +ZMK_SUBSCRIPTION(widget_modifiers, zmk_keycode_state_changed); + +int zmk_widget_modifiers_init(struct zmk_widget_modifiers *widget, lv_obj_t *parent) { + widget->obj = lv_obj_create(parent); + + lv_obj_set_size(widget->obj, NUM_SYMBOLS * (SIZE_SYMBOLS + 1) + 1, SIZE_SYMBOLS + 3); + + static lv_style_t style_line; + lv_style_init(&style_line); + lv_style_set_line_width(&style_line, 2); + + static const lv_point_t selection_line_points[] = { {0, 0}, {SIZE_SYMBOLS, 0} }; + + for (int i = 0; i < NUM_SYMBOLS; i++) { + modifier_symbols[i]->symbol = lv_img_create(widget->obj); + lv_obj_align(modifier_symbols[i]->symbol, LV_ALIGN_TOP_LEFT, 1 + (SIZE_SYMBOLS + 1) * i, 1); + lv_img_set_src(modifier_symbols[i]->symbol, modifier_symbols[i]->symbol_dsc); + + modifier_symbols[i]->selection_line = lv_line_create(widget->obj); + lv_line_set_points(modifier_symbols[i]->selection_line, selection_line_points, 2); + lv_obj_add_style(modifier_symbols[i]->selection_line, &style_line, 0); + lv_obj_align_to(modifier_symbols[i]->selection_line, modifier_symbols[i]->symbol, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 3); + } + + sys_slist_append(&widgets, &widget->node); + + widget_modifiers_init(); + + return 0; +} + +lv_obj_t *zmk_widget_modifiers_obj(struct zmk_widget_modifiers *widget) { + return widget->obj; +} \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/modifiers.h b/config/boards/shields/dongle_display/widgets/modifiers.h new file mode 100644 index 0000000..be47e65 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/modifiers.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + #pragma once + +#include +#include + +#define SIZE_SYMBOLS 14 // 14 x 14 pixel + +struct zmk_widget_modifiers { + sys_snode_t node; + lv_obj_t *obj; +}; + +int zmk_widget_modifiers_init(struct zmk_widget_modifiers *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_modifiers_obj(struct zmk_widget_modifiers *widget); \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/modifiers_sym.c b/config/boards/shields/dongle_display/widgets/modifiers_sym.c new file mode 100644 index 0000000..9571607 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/modifiers_sym.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + #include + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_CONTROL +#define LV_ATTRIBUTE_IMG_CONTROL +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_CONTROL uint8_t control_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, + 0x00, 0x00, + 0x03, 0x00, + 0x07, 0x80, + 0x0c, 0xc0, + 0x18, 0x60, + 0x30, 0x30, + 0x20, 0x10, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, +}; + +const lv_img_dsc_t control_icon = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 14, + .header.h = 14, + .data_size = 36, + .data = control_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SHIFT +#define LV_ATTRIBUTE_IMG_SHIFT +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SHIFT uint8_t shift_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, + 0x00, 0x00, + 0x03, 0x00, + 0x07, 0x80, + 0x0c, 0xc0, + 0x18, 0x60, + 0x30, 0x30, + 0x78, 0x78, + 0x08, 0x40, + 0x08, 0x40, + 0x08, 0x40, + 0x0f, 0xc0, + 0x00, 0x00, + 0x00, 0x00, +}; + +const lv_img_dsc_t shift_icon = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 14, + .header.h = 14, + .data_size = 36, + .data = shift_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_ALT +#define LV_ATTRIBUTE_IMG_ALT +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_ALT uint8_t alt_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x32, 0xf8, + 0x4a, 0x20, + 0x4a, 0x20, + 0x7a, 0x20, + 0x4a, 0x20, + 0x4b, 0xa0, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, +}; + +const lv_img_dsc_t alt_icon = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 14, + .header.h = 14, + .data_size = 36, + .data = alt_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_WIN +#define LV_ATTRIBUTE_IMG_WIN +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_WIN uint8_t win_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0xf0, + 0x0b, 0xf0, + 0x3b, 0xf0, + 0x3b, 0xf0, + 0x3b, 0xf0, + 0x00, 0x00, + 0x3b, 0xf0, + 0x3b, 0xf0, + 0x3b, 0xf0, + 0x03, 0xf0, + 0x00, 0x30, + 0x00, 0x00, +}; + +const lv_img_dsc_t win_icon = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 14, + .header.h = 14, + .data_size = 36, + .data = win_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_CMD +#define LV_ATTRIBUTE_IMG_CMD +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_CMD uint8_t cmd_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, + 0x00, 0x00, + 0x18, 0x60, + 0x24, 0x90, + 0x24, 0x90, + 0x1f, 0xe0, + 0x04, 0x80, + 0x04, 0x80, + 0x1f, 0xe0, + 0x24, 0x90, + 0x24, 0x90, + 0x18, 0x60, + 0x00, 0x00, + 0x00, 0x00, +}; + +const lv_img_dsc_t cmd_icon = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 14, + .header.h = 14, + .data_size = 36, + .data = cmd_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_OPT +#define LV_ATTRIBUTE_IMG_OPT +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_OPT uint8_t opt_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, + 0x00, 0x00, + 0x3c, 0xe0, + 0x3c, 0xe0, + 0x06, 0x00, + 0x06, 0x00, + 0x06, 0x00, + 0x03, 0x00, + 0x03, 0x00, + 0x03, 0x00, + 0x01, 0xe0, + 0x01, 0xe0, + 0x00, 0x00, + 0x00, 0x00, +}; + +const lv_img_dsc_t opt_icon = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 14, + .header.h = 14, + .data_size = 36, + .data = opt_map, +}; \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/output_status.c b/config/boards/shields/dongle_display/widgets/output_status.c new file mode 100644 index 0000000..40bd255 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/output_status.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "output_status.h" + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); + +LV_IMG_DECLARE(sym_usb); +LV_IMG_DECLARE(sym_bt); +LV_IMG_DECLARE(sym_ok); +LV_IMG_DECLARE(sym_nok); +LV_IMG_DECLARE(sym_open); +LV_IMG_DECLARE(sym_1); +LV_IMG_DECLARE(sym_2); +LV_IMG_DECLARE(sym_3); +LV_IMG_DECLARE(sym_4); +LV_IMG_DECLARE(sym_5); + +const lv_img_dsc_t *sym_num[] = { + &sym_1, + &sym_2, + &sym_3, + &sym_4, + &sym_5, +}; + +enum output_symbol { + output_symbol_usb, + output_symbol_usb_hid_status, + output_symbol_bt, + output_symbol_bt_number, + output_symbol_bt_status, + output_symbol_selection_line +}; + +enum selection_line_state { + selection_line_state_usb, + selection_line_state_bt +} current_selection_line_state; + +lv_point_t selection_line_points[] = { {0, 0}, {13, 0} }; // will be replaced with lv_point_precise_t + +struct output_status_state { + struct zmk_endpoint_instance selected_endpoint; + int active_profile_index; + bool active_profile_connected; + bool active_profile_bonded; + bool usb_is_hid_ready; +}; + +static struct output_status_state get_state(const zmk_event_t *_eh) { + return (struct output_status_state){ + .selected_endpoint = zmk_endpoints_selected(), + .active_profile_index = zmk_ble_active_profile_index(), + .active_profile_connected = zmk_ble_active_profile_is_connected(), + .active_profile_bonded = !zmk_ble_active_profile_is_open(), + .usb_is_hid_ready = zmk_usb_is_hid_ready() + }; +} + +static void anim_x_cb(void * var, int32_t v) { + lv_obj_set_x(var, v); +} + +static void anim_size_cb(void * var, int32_t v) { + selection_line_points[1].x = v; +} + +static void move_object_x(void *obj, int32_t from, int32_t to) { + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, obj); + lv_anim_set_time(&a, 200); // will be replaced with lv_anim_set_duration + lv_anim_set_exec_cb(&a, anim_x_cb); + lv_anim_set_path_cb(&a, lv_anim_path_overshoot); + lv_anim_set_values(&a, from, to); + lv_anim_start(&a); +} + +static void change_size_object(void *obj, int32_t from, int32_t to) { + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, obj); + lv_anim_set_time(&a, 200); // will be replaced with lv_anim_set_duration + lv_anim_set_exec_cb(&a, anim_size_cb); + lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out); + lv_anim_set_values(&a, from, to); + lv_anim_start(&a); +} + +static void set_status_symbol(lv_obj_t *widget, struct output_status_state state) { + lv_obj_t *usb = lv_obj_get_child(widget, output_symbol_usb); + lv_obj_t *usb_hid_status = lv_obj_get_child(widget, output_symbol_usb_hid_status); + lv_obj_t *bt = lv_obj_get_child(widget, output_symbol_bt); + lv_obj_t *bt_number = lv_obj_get_child(widget, output_symbol_bt_number); + lv_obj_t *bt_status = lv_obj_get_child(widget, output_symbol_bt_status); + lv_obj_t *selection_line = lv_obj_get_child(widget, output_symbol_selection_line); + + switch (state.selected_endpoint.transport) { + case ZMK_TRANSPORT_USB: + if (current_selection_line_state != selection_line_state_usb) { + move_object_x(selection_line, lv_obj_get_x(bt) - 1, lv_obj_get_x(usb) - 1); + change_size_object(selection_line, 18, 11); + current_selection_line_state = selection_line_state_usb; + } + break; + case ZMK_TRANSPORT_BLE: + if (current_selection_line_state != selection_line_state_bt) { + move_object_x(selection_line, lv_obj_get_x(usb) - 1, lv_obj_get_x(bt) - 1); + change_size_object(selection_line, 11, 18); + current_selection_line_state = selection_line_state_bt; + } + break; + } + + if (state.usb_is_hid_ready) { + lv_img_set_src(usb_hid_status, &sym_ok); + } else { + lv_img_set_src(usb_hid_status, &sym_nok); + } + + if (state.active_profile_index < (sizeof(sym_num) / sizeof(lv_img_dsc_t *))) { + lv_img_set_src(bt_number, sym_num[state.active_profile_index]); + } else { + lv_img_set_src(bt_number, &sym_nok); + } + + if (state.active_profile_bonded) { + if (state.active_profile_connected) { + lv_img_set_src(bt_status, &sym_ok); + } else { + lv_img_set_src(bt_status, &sym_nok); + } + } else { + lv_img_set_src(bt_status, &sym_open); + } +} + +static void output_status_update_cb(struct output_status_state state) { + struct zmk_widget_output_status *widget; + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_status_symbol(widget->obj, state); } +} + +ZMK_DISPLAY_WIDGET_LISTENER(widget_output_status, struct output_status_state, + output_status_update_cb, get_state) +ZMK_SUBSCRIPTION(widget_output_status, zmk_endpoint_changed); +ZMK_SUBSCRIPTION(widget_output_status, zmk_ble_active_profile_changed); +ZMK_SUBSCRIPTION(widget_output_status, zmk_usb_conn_state_changed); + +int zmk_widget_output_status_init(struct zmk_widget_output_status *widget, lv_obj_t *parent) { + widget->obj = lv_obj_create(parent); + + lv_obj_set_size(widget->obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + + lv_obj_t *usb = lv_img_create(widget->obj); + lv_obj_align(usb, LV_ALIGN_TOP_LEFT, 1, 4); + lv_img_set_src(usb, &sym_usb); + + lv_obj_t *usb_hid_status = lv_img_create(widget->obj); + lv_obj_align_to(usb_hid_status, usb, LV_ALIGN_BOTTOM_LEFT, 2, -7); + + lv_obj_t *bt = lv_img_create(widget->obj); + lv_obj_align_to(bt, usb, LV_ALIGN_OUT_RIGHT_TOP, 6, 0); + lv_img_set_src(bt, &sym_bt); + + lv_obj_t *bt_number = lv_img_create(widget->obj); + lv_obj_align_to(bt_number, bt, LV_ALIGN_OUT_RIGHT_TOP, 2, 7); + + lv_obj_t *bt_status = lv_img_create(widget->obj); + lv_obj_align_to(bt_status, bt, LV_ALIGN_OUT_RIGHT_TOP, 2, 1); + + static lv_style_t style_line; + lv_style_init(&style_line); + lv_style_set_line_width(&style_line, 2); + + lv_obj_t *selection_line; + selection_line = lv_line_create(widget->obj); + lv_line_set_points(selection_line, selection_line_points, 2); + lv_obj_add_style(selection_line, &style_line, 0); + lv_obj_align_to(selection_line, usb, LV_ALIGN_OUT_TOP_LEFT, 3, -1); + + sys_slist_append(&widgets, &widget->node); + + widget_output_status_init(); + return 0; +} + +lv_obj_t *zmk_widget_output_status_obj(struct zmk_widget_output_status *widget) { + return widget->obj; +} diff --git a/config/boards/shields/dongle_display/widgets/output_status.h b/config/boards/shields/dongle_display/widgets/output_status.h new file mode 100644 index 0000000..dfd37bf --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/output_status.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + #pragma once + +#include +#include + +struct zmk_widget_output_status { + sys_snode_t node; + lv_obj_t *obj; +}; + +int zmk_widget_output_status_init(struct zmk_widget_output_status *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_output_status_obj(struct zmk_widget_output_status *widget); \ No newline at end of file diff --git a/config/boards/shields/dongle_display/widgets/output_status_sym.c b/config/boards/shields/dongle_display/widgets/output_status_sym.c new file mode 100644 index 0000000..bc333a8 --- /dev/null +++ b/config/boards/shields/dongle_display/widgets/output_status_sym.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + #include + + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_SYM_1 +#define LV_ATTRIBUTE_IMG_SYM_1 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_1 uint8_t sym_1_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x30, 0x70, 0x70, 0x30, 0x30, 0x30, +}; + +const lv_img_dsc_t sym_1 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 6, + .data_size = 14, + .data = sym_1_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_2 +#define LV_ATTRIBUTE_IMG_SYM_2 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_2 uint8_t sym_2_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x70, 0xd8, 0x18, 0x30, 0x60, 0xf8, +}; + +const lv_img_dsc_t sym_2 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 6, + .data_size = 14, + .data = sym_2_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_3 +#define LV_ATTRIBUTE_IMG_SYM_3 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_3 uint8_t sym_3_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x70, 0x98, 0x30, 0x18, 0xd8, 0x70, +}; + +const lv_img_dsc_t sym_3 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 6, + .data_size = 14, + .data = sym_3_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_4 +#define LV_ATTRIBUTE_IMG_SYM_4 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_4 uint8_t sym_4_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x10, 0x30, 0x70, 0xd0, 0xf8, 0x10, +}; + +const lv_img_dsc_t sym_4 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 6, + .data_size = 14, + .data = sym_4_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_5 +#define LV_ATTRIBUTE_IMG_SYM_5 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_5 uint8_t sym_5_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x78, 0x40, 0x70, 0x18, 0xd8, 0x70, +}; + +const lv_img_dsc_t sym_5 = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 6, + .data_size = 14, + .data = sym_5_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_OK +#define LV_ATTRIBUTE_IMG_SYM_OK +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_OK uint8_t sym_ok_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x08, 0x18, 0xb0, 0xe0, 0x40, +}; + +const lv_img_dsc_t sym_ok = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 5, + .data_size = 13, + .data = sym_ok_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_NOK +#define LV_ATTRIBUTE_IMG_SYM_NOK +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_NOK uint8_t sym_nok_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x88, 0xd8, 0x70, 0xd8, 0x88, +}; + +const lv_img_dsc_t sym_nok = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 5, + .data_size = 13, + .data = sym_nok_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_OPEN +#define LV_ATTRIBUTE_IMG_SYM_OPEN +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_OPEN uint8_t sym_open_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x20, 0x70, 0xd8, 0x70, 0x20, +}; + +const lv_img_dsc_t sym_open = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 5, + .header.h = 5, + .data_size = 13, + .data = sym_open_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_BT +#define LV_ATTRIBUTE_IMG_SYM_BT +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_BT uint8_t sym_bt_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x3e, 0x00, 0x67, 0x00, 0xe3, 0x80, 0xe9, + 0x80, 0x8c, 0x80, 0xc9, 0x80, 0xe3, 0x80, + 0xe3, 0x80, 0xc9, 0x80, 0x8c, 0x80, 0xe9, + 0x80, 0xe3, 0x80, 0x67, 0x00, 0x3e, 0x00, +}; + +const lv_img_dsc_t sym_bt = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 9, + .header.h = 14, + .data_size = 36, + .data = sym_bt_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_SYM_USB +#define LV_ATTRIBUTE_IMG_SYM_USB +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_SYM_USB uint8_t sym_usb_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x7f, 0x00, 0x41, 0x00, 0x55, 0x00, 0x41, + 0x00, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0xff, 0x80, +}; + +const lv_img_dsc_t sym_usb = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 9, + .header.h = 14, + .data_size = 36, + .data = sym_usb_map, +}; + + +