Skip to content

Instantly share code, notes, and snippets.

@caksoylar
Created May 7, 2022 20:25
Show Gist options
  • Save caksoylar/0046ff643030ae64587a65c8adbc2cf3 to your computer and use it in GitHub Desktop.
Save caksoylar/0046ff643030ae64587a65c8adbc2cf3 to your computer and use it in GitHub Desktop.
A patch to replace ZMK Wifi icon with the Bluetooth one

Replacing ZMK wireless connectivity indicator with BT icon

This patch replaces the Wifi icon in ZMK's default output status widget with a Bluetooth icon. This icon was created from scratch to work with the 16 pt font that ZMK uses by default for showing output status.

128x64 OLED with BT icon

Note that while LVGL font ZMK uses includes a Bluetooth icon, it doesn't render well in 16 pt font which is why we display this icon as an image instead.

diff --git a/app/include/zmk/display/widgets/output_status.h b/app/include/zmk/display/widgets/output_status.h
index 66f09271..a81fb1be 100644
--- a/app/include/zmk/display/widgets/output_status.h
+++ b/app/include/zmk/display/widgets/output_status.h
@@ -12,7 +12,8 @@
struct zmk_widget_output_status {
sys_snode_t node;
lv_obj_t *obj;
+ lv_obj_t *img;
};
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
+lv_obj_t *zmk_widget_output_status_obj(struct zmk_widget_output_status *widget);
diff --git a/app/src/display/widgets/CMakeLists.txt b/app/src/display/widgets/CMakeLists.txt
index 1d115dcc..ccad0356 100644
--- a/app/src/display/widgets/CMakeLists.txt
+++ b/app/src/display/widgets/CMakeLists.txt
@@ -3,5 +3,6 @@
target_sources_ifdef(CONFIG_ZMK_WIDGET_BATTERY_STATUS app PRIVATE battery_status.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_OUTPUT_STATUS app PRIVATE output_status.c)
+target_sources_ifdef(CONFIG_ZMK_WIDGET_OUTPUT_STATUS app PRIVATE bt18.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_LAYER_STATUS app PRIVATE layer_status.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_WPM_STATUS app PRIVATE wpm_status.c)
diff --git a/app/src/display/widgets/Kconfig b/app/src/display/widgets/Kconfig
index 0a6bf5c4..53cb9328 100644
--- a/app/src/display/widgets/Kconfig
+++ b/app/src/display/widgets/Kconfig
@@ -20,6 +20,7 @@ config ZMK_WIDGET_OUTPUT_STATUS
depends on BT
default y if BT
select LVGL_USE_LABEL
+ select LVGL_USE_IMG
config ZMK_WIDGET_WPM_STATUS
bool "Widget for displaying typed words per minute"
diff --git a/app/src/display/widgets/bt18.c b/app/src/display/widgets/bt18.c
new file mode 100644
index 00000000..a3170ac3
--- /dev/null
+++ b/app/src/display/widgets/bt18.c
@@ -0,0 +1,28 @@
+#include <lvgl.h>
+
+#ifndef LV_ATTRIBUTE_MEM_ALIGN
+#define LV_ATTRIBUTE_MEM_ALIGN
+#endif
+
+#ifndef LV_ATTRIBUTE_IMG_BT18
+#define LV_ATTRIBUTE_IMG_BT18
+#endif
+
+const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BT18 uint8_t bt18_map[] = {
+ 0x00, 0x00, 0x00, 0xff, /*Color of index 0*/
+ 0xff, 0xff, 0xff, 0xff, /*Color of index 1*/
+
+ 0xf9, 0xf8, 0xf8, 0xf8, 0xf8, 0x78, 0xf8, 0x38, 0x99, 0x18, 0x89, 0x88,
+ 0xc1, 0x18, 0xe0, 0x38, 0xf0, 0x78, 0xf0, 0x78, 0xe0, 0x38, 0xc1, 0x18,
+ 0x89, 0x88, 0x99, 0x18, 0xf8, 0x38, 0xf8, 0x78, 0xf8, 0xf8, 0xf9, 0xf8,
+};
+
+const lv_img_dsc_t bt18 = {
+ .header.cf = LV_IMG_CF_INDEXED_1BIT,
+ .header.always_zero = 0,
+ .header.reserved = 0,
+ .header.w = 13,
+ .header.h = 18,
+ .data_size = 44,
+ .data = bt18_map,
+};
diff --git a/app/src/display/widgets/output_status.c b/app/src/display/widgets/output_status.c
index fe99ac96..f95fff8d 100644
--- a/app/src/display/widgets/output_status.c
+++ b/app/src/display/widgets/output_status.c
@@ -20,6 +20,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/ble.h>
#include <zmk/endpoints.h>
+LV_IMG_DECLARE(bt18);
+
static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets);
struct output_status_state {
@@ -38,24 +40,26 @@ static struct output_status_state get_state(const zmk_event_t *_eh) {
;
}
-static void set_status_symbol(lv_obj_t *label, struct output_status_state state) {
- char text[9] = {};
+static void set_status_symbol(lv_obj_t *label, lv_obj_t *img, struct output_status_state state) {
+ char text[10] = {};
switch (state.selected_endpoint) {
case ZMK_ENDPOINT_USB:
+ lv_obj_set_hidden(img, true);
strcat(text, LV_SYMBOL_USB " ");
break;
case ZMK_ENDPOINT_BLE:
+ lv_obj_set_hidden(img, false);
if (state.active_profile_bonded) {
if (state.active_profile_connected) {
- snprintf(text, sizeof(text), LV_SYMBOL_WIFI "%i " LV_SYMBOL_OK,
+ snprintf(text, sizeof(text), " %i " LV_SYMBOL_OK,
state.active_profile_index);
} else {
- snprintf(text, sizeof(text), LV_SYMBOL_WIFI "%i " LV_SYMBOL_CLOSE,
+ snprintf(text, sizeof(text), " %i " LV_SYMBOL_CLOSE,
state.active_profile_index);
}
} else {
- snprintf(text, sizeof(text), LV_SYMBOL_WIFI "%i " LV_SYMBOL_SETTINGS,
+ snprintf(text, sizeof(text), " %i " LV_SYMBOL_SETTINGS,
state.active_profile_index);
}
break;
@@ -66,7 +70,9 @@ static void set_status_symbol(lv_obj_t *label, struct output_status_state state)
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); }
+ SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) {
+ set_status_symbol(widget->obj, widget->img, state);
+ }
}
ZMK_DISPLAY_WIDGET_LISTENER(widget_output_status, struct output_status_state,
@@ -82,6 +88,9 @@ ZMK_SUBSCRIPTION(widget_output_status, zmk_ble_active_profile_changed);
int zmk_widget_output_status_init(struct zmk_widget_output_status *widget, lv_obj_t *parent) {
widget->obj = lv_label_create(parent, NULL);
+ widget->img = lv_img_create(parent, NULL);
+ lv_img_set_src(widget->img, &bt18);
+ lv_obj_set_hidden(widget->img, true);
lv_obj_set_size(widget->obj, 40, 15);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment