Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/bongo cat #2

Merged
merged 2 commits into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/include/zmk/display/widgets/bongo_cat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2021 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <lvgl.h>
#include <kernel.h>

struct zmk_widget_bongo_cat {
sys_snode_t node;
lv_obj_t *obj;
lv_anim_t anim;
};

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);
12 changes: 12 additions & 0 deletions app/src/display/status_screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include <zmk/display/widgets/battery_status.h>
#include <zmk/display/widgets/layer_status.h>
#include <zmk/display/widgets/wpm_status.h>
#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT)
#include <zmk/display/widgets/bongo_cat.h>
#endif
#include <zmk/display/status_screen.h>

#include <logging/log.h>
Expand All @@ -29,6 +32,10 @@ static struct zmk_widget_layer_status layer_status_widget;
static struct zmk_widget_wpm_status wpm_status_widget;
#endif

#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT)
static struct zmk_widget_bongo_cat bongo_cat_widget;
#endif

lv_obj_t *zmk_display_status_screen() {
lv_obj_t *screen;

Expand All @@ -55,6 +62,11 @@ lv_obj_t *zmk_display_status_screen() {
0, 0);
#endif

#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT)
zmk_widget_bongo_cat_init(&bongo_cat_widget, screen);
lv_obj_align(zmk_widget_bongo_cat_obj(&bongo_cat_widget), NULL, LV_ALIGN_CENTER, 0, 0);
#endif

#if IS_ENABLED(CONFIG_ZMK_WIDGET_WPM_STATUS)
zmk_widget_wpm_status_init(&wpm_status_widget, screen);
lv_obj_align(zmk_widget_wpm_status_obj(&wpm_status_widget), NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -12,
Expand Down
2 changes: 2 additions & 0 deletions app/src/display/widgets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ target_sources_ifdef(CONFIG_ZMK_WIDGET_BATTERY_STATUS app PRIVATE battery_status
target_sources_ifdef(CONFIG_ZMK_WIDGET_OUTPUT_STATUS app PRIVATE output_status.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)
target_sources_ifdef(CONFIG_ZMK_WIDGET_BONGO_CAT app PRIVATE bongo_cat.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_BONGO_CAT app PRIVATE bongo_cat_images.c)
20 changes: 20 additions & 0 deletions app/src/display/widgets/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,24 @@ config ZMK_WIDGET_WPM_STATUS
select LVGL_USE_LABEL
select ZMK_WPM

config ZMK_WIDGET_BONGO_CAT
bool "Widget for displaying bongo cat that reacts to typing"
depends on !ZMK_DISPLAY_WORK_QUEUE_DEDICATED && (!ZMK_SPLIT || ZMK_SPLIT_BLE_ROLE_CENTRAL)
select LVGL_USE_IMG
select LVGL_USE_ANIMATION
select ZMK_WPM

if ZMK_WIDGET_BONGO_CAT

config ZMK_WIDGET_BONGO_CAT_IDLE_LIMIT
int "Upper limit for WPM for showing idle animation"
default 30

config ZMK_WIDGET_BONGO_CAT_SLOW_LIMIT
int "Upper limit for WPM for showing slow typing image"
default 60

endif # ZMK_WIDGET_BONGO_CAT


endmenu
120 changes: 120 additions & 0 deletions app/src/display/widgets/bongo_cat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2021 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <zmk/event_manager.h>
#include <zmk/events/wpm_state_changed.h>

#include <logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#include <zmk/display/widgets/bongo_cat.h>

#if IS_ENABLED(CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED)
#error "Bongo cat only works with the system work queue currently"
#endif

static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets);

enum anim_state {
anim_state_none,
anim_state_idle,
anim_state_slow,
anim_state_fast
} current_anim_state;

const void **images;
uint8_t images_len;

LV_IMG_DECLARE(idle_img1);
LV_IMG_DECLARE(idle_img2);
LV_IMG_DECLARE(idle_img3);
LV_IMG_DECLARE(idle_img4);
LV_IMG_DECLARE(idle_img5);

LV_IMG_DECLARE(slow_img);

LV_IMG_DECLARE(fast_img1);
LV_IMG_DECLARE(fast_img2);

const void *idle_images[] = {
&idle_img1, &idle_img2, &idle_img3, &idle_img4, &idle_img5,
};

const void *fast_images[] = {
&fast_img1,
&fast_img2,
};

void set_img_src(void *var, lv_anim_value_t val) {
lv_obj_t *img = (lv_obj_t *)var;
lv_img_set_src(img, images[val]);
}

void update_bongo_cat_wpm(struct zmk_widget_bongo_cat *widget, int wpm) {
LOG_DBG("anim state %d", current_anim_state);
if (wpm < CONFIG_ZMK_WIDGET_BONGO_CAT_IDLE_LIMIT) {
if (current_anim_state != anim_state_idle) {
LOG_DBG("Set source to idle images!");
lv_anim_init(&widget->anim);
lv_anim_set_var(&widget->anim, widget->obj);
lv_anim_set_time(&widget->anim, 1000);
lv_anim_set_values(&widget->anim, 0, 4);
lv_anim_set_exec_cb(&widget->anim, set_img_src);
lv_anim_set_repeat_count(&widget->anim, 1000);
lv_anim_set_repeat_delay(&widget->anim, 100);
images = idle_images;
current_anim_state = anim_state_idle;
lv_anim_start(&widget->anim);
}
} else if (wpm < CONFIG_ZMK_WIDGET_BONGO_CAT_SLOW_LIMIT) {
if (current_anim_state != anim_state_slow) {
LOG_DBG("Set source to slow image!");
lv_anim_del(widget->obj, set_img_src);
lv_img_set_src(widget->obj, &slow_img);
current_anim_state = anim_state_slow;
}
} else {
if (current_anim_state != anim_state_fast) {
LOG_DBG("Set source to fast images!");
lv_anim_init(&widget->anim);
lv_anim_set_time(&widget->anim, 500);
lv_anim_set_repeat_delay(&widget->anim, 500);
lv_anim_set_var(&widget->anim, widget->obj);
lv_anim_set_values(&widget->anim, 0, 1);
lv_anim_set_exec_cb(&widget->anim, set_img_src);
lv_anim_set_repeat_count(&widget->anim, LV_ANIM_REPEAT_INFINITE);
images = fast_images;
current_anim_state = anim_state_fast;
lv_anim_start(&widget->anim);
}
}
}

int zmk_widget_bongo_cat_init(struct zmk_widget_bongo_cat *widget, lv_obj_t *parent) {
widget->obj = lv_img_create(parent, NULL);

lv_img_set_auto_size(widget->obj, true);
update_bongo_cat_wpm(widget, 0);

sys_slist_append(&widgets, &widget->node);

return 0;
}

lv_obj_t *zmk_widget_bongo_cat_obj(struct zmk_widget_bongo_cat *widget) { return widget->obj; }

int bongo_cat_listener(const zmk_event_t *eh) {
struct zmk_widget_bongo_cat *widget;
struct zmk_wpm_state_changed *ev = as_zmk_wpm_state_changed(eh);
SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) {
LOG_DBG("Set the WPM %d", ev->state);
update_bongo_cat_wpm(widget, ev->state);
}
return ZMK_EV_EVENT_BUBBLE;
}

ZMK_LISTENER(zmk_widget_bongo_cat, bongo_cat_listener)
ZMK_SUBSCRIPTION(zmk_widget_bongo_cat, zmk_wpm_state_changed);
Loading