[FL-1908] New animation update scheme (#737)
* Assets: update desktop animation frame rate and cleanup. * Power: update ViewPort only if changed. * Gui: tie IconAnimation with View, new update event generation scheme. Desktop: update IconAnimation usage. Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
This commit is contained in:
parent
6f346597d2
commit
61aaed8abb
@ -45,7 +45,6 @@ bool desktop_scene_locked_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
void desktop_scene_locked_on_exit(void* context) {
|
void desktop_scene_locked_on_exit(void* context) {
|
||||||
Desktop* desktop = (Desktop*)context;
|
Desktop* desktop = (Desktop*)context;
|
||||||
DesktopLockedView* locked_view = desktop->locked_view;
|
|
||||||
desktop_locked_reset_counter(desktop->locked_view);
|
desktop_locked_reset_counter(desktop->locked_view);
|
||||||
osTimerStop(locked_view->timer);
|
osTimerStop(desktop->locked_view->timer);
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
|||||||
desktop_switch_to_app(desktop, &FLIPPER_ARCHIVE);
|
desktop_switch_to_app(desktop, &FLIPPER_ARCHIVE);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DesktopMainEventOpenFavorite:
|
case DesktopMainEventOpenFavorite:
|
||||||
desktop_settings_load(&desktop->settings);
|
desktop_settings_load(&desktop->settings);
|
||||||
desktop_switch_to_app(desktop, &FLIPPER_APPS[desktop->settings.favorite]);
|
desktop_switch_to_app(desktop, &FLIPPER_APPS[desktop->settings.favorite]);
|
||||||
|
@ -20,13 +20,12 @@ void locked_view_timer_callback(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// temporary locked screen animation managment
|
// temporary locked screen animation managment
|
||||||
static void
|
static void desktop_locked_set_scene(DesktopLockedView* locked_view, const Icon* icon_data) {
|
||||||
desktop_scene_handler_set_scene(DesktopLockedView* locked_view, const Icon* icon_data) {
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
locked_view->view, (DesktopLockedViewModel * model) {
|
locked_view->view, (DesktopLockedViewModel * model) {
|
||||||
if(model->animation) icon_animation_free(model->animation);
|
if(model->animation) icon_animation_free(model->animation);
|
||||||
model->animation = icon_animation_alloc(icon_data);
|
model->animation = icon_animation_alloc(icon_data);
|
||||||
icon_animation_start(model->animation);
|
view_tie_icon_animation(locked_view->view, model->animation);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -148,6 +147,25 @@ bool desktop_locked_input(InputEvent* event, void* context) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void desktop_locked_enter(void* context) {
|
||||||
|
DesktopLockedView* locked_view = context;
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
locked_view->view, (DesktopLockedViewModel * model) {
|
||||||
|
if(model->animation) icon_animation_start(model->animation);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void desktop_locked_exit(void* context) {
|
||||||
|
DesktopLockedView* locked_view = context;
|
||||||
|
with_view_model(
|
||||||
|
locked_view->view, (DesktopLockedViewModel * model) {
|
||||||
|
if(model->animation) icon_animation_stop(model->animation);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
DesktopLockedView* desktop_locked_alloc() {
|
DesktopLockedView* desktop_locked_alloc() {
|
||||||
DesktopLockedView* locked_view = furi_alloc(sizeof(DesktopLockedView));
|
DesktopLockedView* locked_view = furi_alloc(sizeof(DesktopLockedView));
|
||||||
locked_view->view = view_alloc();
|
locked_view->view = view_alloc();
|
||||||
@ -158,8 +176,10 @@ DesktopLockedView* desktop_locked_alloc() {
|
|||||||
view_set_context(locked_view->view, locked_view);
|
view_set_context(locked_view->view, locked_view);
|
||||||
view_set_draw_callback(locked_view->view, (ViewDrawCallback)desktop_locked_render);
|
view_set_draw_callback(locked_view->view, (ViewDrawCallback)desktop_locked_render);
|
||||||
view_set_input_callback(locked_view->view, desktop_locked_input);
|
view_set_input_callback(locked_view->view, desktop_locked_input);
|
||||||
|
view_set_enter_callback(locked_view->view, desktop_locked_enter);
|
||||||
|
view_set_exit_callback(locked_view->view, desktop_locked_exit);
|
||||||
|
|
||||||
desktop_scene_handler_set_scene(locked_view, idle_scenes[random() % COUNT_OF(idle_scenes)]);
|
desktop_locked_set_scene(locked_view, idle_scenes[random() % COUNT_OF(idle_scenes)]);
|
||||||
return locked_view;
|
return locked_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,17 +17,18 @@ void desktop_main_set_callback(
|
|||||||
void desktop_main_reset_hint(DesktopMainView* main_view) {
|
void desktop_main_reset_hint(DesktopMainView* main_view) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
main_view->view, (DesktopMainViewModel * model) {
|
main_view->view, (DesktopMainViewModel * model) {
|
||||||
model->hint_timeout = 0;
|
model->hint_expire_at = 0;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporary main screen animation managment
|
// temporary main screen animation managment
|
||||||
void desktop_scene_handler_set_scene(DesktopMainView* main_view, const Icon* icon_data) {
|
static void desktop_main_set_scene(DesktopMainView* main_view, const Icon* icon_data) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
main_view->view, (DesktopMainViewModel * model) {
|
main_view->view, (DesktopMainViewModel * model) {
|
||||||
if(model->animation) icon_animation_free(model->animation);
|
if(model->animation) icon_animation_free(model->animation);
|
||||||
model->animation = icon_animation_alloc(icon_data);
|
model->animation = icon_animation_alloc(icon_data);
|
||||||
icon_animation_start(model->animation);
|
view_tie_icon_animation(main_view->view, model->animation);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -38,7 +39,6 @@ void desktop_scene_handler_switch_scene(DesktopMainView* main_view) {
|
|||||||
if(icon_animation_is_last_frame(model->animation)) {
|
if(icon_animation_is_last_frame(model->animation)) {
|
||||||
if(model->animation) icon_animation_free(model->animation);
|
if(model->animation) icon_animation_free(model->animation);
|
||||||
model->animation = icon_animation_alloc(idle_scenes[model->scene_num]);
|
model->animation = icon_animation_alloc(idle_scenes[model->scene_num]);
|
||||||
icon_animation_start(model->animation);
|
|
||||||
model->scene_num = random() % COUNT_OF(idle_scenes);
|
model->scene_num = random() % COUNT_OF(idle_scenes);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -53,8 +53,7 @@ void desktop_main_render(Canvas* canvas, void* model) {
|
|||||||
canvas_draw_icon_animation(canvas, 0, -3, m->animation);
|
canvas_draw_icon_animation(canvas, 0, -3, m->animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m->unlocked && m->hint_timeout) {
|
if(osKernelGetTickCount() < m->hint_expire_at) {
|
||||||
m->hint_timeout = CLAMP(m->hint_timeout - 1, 2, 0);
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
elements_multiline_text_framed(canvas, 42, 30, "Unlocked");
|
elements_multiline_text_framed(canvas, 42, 30, "Unlocked");
|
||||||
}
|
}
|
||||||
@ -87,6 +86,25 @@ bool desktop_main_input(InputEvent* event, void* context) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void desktop_main_enter(void* context) {
|
||||||
|
DesktopMainView* main_view = context;
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
main_view->view, (DesktopMainViewModel * model) {
|
||||||
|
if(model->animation) icon_animation_start(model->animation);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void desktop_main_exit(void* context) {
|
||||||
|
DesktopMainView* main_view = context;
|
||||||
|
with_view_model(
|
||||||
|
main_view->view, (DesktopMainViewModel * model) {
|
||||||
|
if(model->animation) icon_animation_stop(model->animation);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
DesktopMainView* desktop_main_alloc() {
|
DesktopMainView* desktop_main_alloc() {
|
||||||
DesktopMainView* main_view = furi_alloc(sizeof(DesktopMainView));
|
DesktopMainView* main_view = furi_alloc(sizeof(DesktopMainView));
|
||||||
main_view->view = view_alloc();
|
main_view->view = view_alloc();
|
||||||
@ -94,8 +112,10 @@ DesktopMainView* desktop_main_alloc() {
|
|||||||
view_set_context(main_view->view, main_view);
|
view_set_context(main_view->view, main_view);
|
||||||
view_set_draw_callback(main_view->view, (ViewDrawCallback)desktop_main_render);
|
view_set_draw_callback(main_view->view, (ViewDrawCallback)desktop_main_render);
|
||||||
view_set_input_callback(main_view->view, desktop_main_input);
|
view_set_input_callback(main_view->view, desktop_main_input);
|
||||||
|
view_set_enter_callback(main_view->view, desktop_main_enter);
|
||||||
|
view_set_exit_callback(main_view->view, desktop_main_exit);
|
||||||
|
|
||||||
desktop_scene_handler_set_scene(main_view, idle_scenes[random() % COUNT_OF(idle_scenes)]);
|
desktop_main_set_scene(main_view, idle_scenes[random() % COUNT_OF(idle_scenes)]);
|
||||||
|
|
||||||
return main_view;
|
return main_view;
|
||||||
}
|
}
|
||||||
@ -109,8 +129,7 @@ void desktop_main_free(DesktopMainView* main_view) {
|
|||||||
void desktop_main_unlocked(DesktopMainView* main_view) {
|
void desktop_main_unlocked(DesktopMainView* main_view) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
main_view->view, (DesktopMainViewModel * model) {
|
main_view->view, (DesktopMainViewModel * model) {
|
||||||
model->unlocked = true;
|
model->hint_expire_at = osKernelGetTickCount() + osKernelGetTickFreq();
|
||||||
model->hint_timeout = 2;
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,7 @@ struct DesktopMainView {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
IconAnimation* animation;
|
IconAnimation* animation;
|
||||||
uint8_t scene_num;
|
uint8_t scene_num;
|
||||||
uint8_t hint_timeout;
|
uint32_t hint_expire_at;
|
||||||
bool unlocked;
|
|
||||||
} DesktopMainViewModel;
|
} DesktopMainViewModel;
|
||||||
|
|
||||||
void desktop_main_set_callback(
|
void desktop_main_set_callback(
|
||||||
@ -40,4 +39,5 @@ void desktop_main_set_callback(
|
|||||||
View* desktop_main_get_view(DesktopMainView* main_view);
|
View* desktop_main_get_view(DesktopMainView* main_view);
|
||||||
|
|
||||||
DesktopMainView* desktop_main_alloc();
|
DesktopMainView* desktop_main_alloc();
|
||||||
|
|
||||||
void desktop_main_free(DesktopMainView* main_view);
|
void desktop_main_free(DesktopMainView* main_view);
|
||||||
|
@ -7,26 +7,26 @@ IconAnimation* icon_animation_alloc(const Icon* icon) {
|
|||||||
furi_assert(icon);
|
furi_assert(icon);
|
||||||
IconAnimation* instance = furi_alloc(sizeof(IconAnimation));
|
IconAnimation* instance = furi_alloc(sizeof(IconAnimation));
|
||||||
instance->icon = icon;
|
instance->icon = icon;
|
||||||
|
instance->timer = osTimerNew(icon_animation_timer_callback, osTimerPeriodic, instance, NULL);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void icon_animation_free(IconAnimation* instance) {
|
void icon_animation_free(IconAnimation* instance) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
|
furi_check(osTimerDelete(instance->timer) == osOK);
|
||||||
free(instance);
|
free(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* icon_animation_get_data(IconAnimation* instance) {
|
void icon_animation_set_update_callback(
|
||||||
|
IconAnimation* instance,
|
||||||
|
IconAnimationCallback callback,
|
||||||
|
void* context) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
if(instance->tick) {
|
instance->callback = callback;
|
||||||
uint32_t now = osKernelGetTickCount();
|
instance->callback_context = context;
|
||||||
if(now < instance->tick) {
|
}
|
||||||
instance->tick = now;
|
|
||||||
icon_animation_next_frame(instance);
|
const uint8_t* icon_animation_get_data(IconAnimation* instance) {
|
||||||
} else if(now - instance->tick > osKernelGetTickFreq() / instance->icon->frame_rate) {
|
|
||||||
instance->tick = now;
|
|
||||||
icon_animation_next_frame(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return instance->icon->frames[instance->frame];
|
return instance->icon->frames[instance->frame];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +35,19 @@ void icon_animation_next_frame(IconAnimation* instance) {
|
|||||||
instance->frame = (instance->frame + 1) % instance->icon->frame_count;
|
instance->frame = (instance->frame + 1) % instance->icon->frame_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void icon_animation_timer_callback(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
|
||||||
|
IconAnimation* instance = context;
|
||||||
|
|
||||||
|
if(!instance->animating) return;
|
||||||
|
|
||||||
|
icon_animation_next_frame(instance);
|
||||||
|
if(instance->callback) {
|
||||||
|
instance->callback(instance, instance->callback_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t icon_animation_get_width(IconAnimation* instance) {
|
uint8_t icon_animation_get_width(IconAnimation* instance) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
return instance->icon->width;
|
return instance->icon->width;
|
||||||
@ -45,30 +58,23 @@ uint8_t icon_animation_get_height(IconAnimation* instance) {
|
|||||||
return instance->icon->height;
|
return instance->icon->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icon_animation_is_animated(IconAnimation* instance) {
|
|
||||||
furi_assert(instance);
|
|
||||||
return instance->icon->frame_count > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icon_animation_is_animating(IconAnimation* instance) {
|
|
||||||
furi_assert(instance);
|
|
||||||
return instance->tick > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void icon_animation_start(IconAnimation* instance) {
|
void icon_animation_start(IconAnimation* instance) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
instance->tick = osKernelGetTickCount();
|
if(!instance->animating) {
|
||||||
|
instance->animating = true;
|
||||||
|
furi_check(
|
||||||
|
osTimerStart(instance->timer, (osKernelGetTickFreq() / instance->icon->frame_rate)) ==
|
||||||
|
osOK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void icon_animation_stop(IconAnimation* instance) {
|
void icon_animation_stop(IconAnimation* instance) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
instance->tick = 0;
|
if(instance->animating) {
|
||||||
|
instance->animating = false;
|
||||||
|
furi_check(osTimerStop(instance->timer) == osOK);
|
||||||
instance->frame = 0;
|
instance->frame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t icon_animation_get_current_frame(IconAnimation* instance) {
|
|
||||||
furi_assert(instance);
|
|
||||||
return instance->frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icon_animation_is_last_frame(IconAnimation* instance) {
|
bool icon_animation_is_last_frame(IconAnimation* instance) {
|
||||||
|
@ -11,54 +11,41 @@ extern "C" {
|
|||||||
|
|
||||||
typedef struct IconAnimation IconAnimation;
|
typedef struct IconAnimation IconAnimation;
|
||||||
|
|
||||||
/*
|
typedef void (*IconAnimationCallback)(IconAnimation* instance, void* context);
|
||||||
* Allocate icon animation instance with const icon data.
|
|
||||||
|
/** Allocate icon animation instance with const icon data.
|
||||||
* always returns Icon or stops system if not enough memory
|
* always returns Icon or stops system if not enough memory
|
||||||
*/
|
*/
|
||||||
IconAnimation* icon_animation_alloc(const Icon* icon);
|
IconAnimation* icon_animation_alloc(const Icon* icon);
|
||||||
|
|
||||||
/*
|
/** Release icon animation instance
|
||||||
* Release icon animation instance
|
|
||||||
*/
|
*/
|
||||||
void icon_animation_free(IconAnimation* instance);
|
void icon_animation_free(IconAnimation* instance);
|
||||||
|
|
||||||
/*
|
/** Get icon animation width
|
||||||
* Get icon animation width
|
*/
|
||||||
|
void icon_animation_set_update_callback(
|
||||||
|
IconAnimation* instance,
|
||||||
|
IconAnimationCallback callback,
|
||||||
|
void* context);
|
||||||
|
|
||||||
|
/** Get icon animation width
|
||||||
*/
|
*/
|
||||||
uint8_t icon_animation_get_width(IconAnimation* instance);
|
uint8_t icon_animation_get_width(IconAnimation* instance);
|
||||||
|
|
||||||
/*
|
/** Get icon animation height
|
||||||
* Get icon animation height
|
|
||||||
*/
|
*/
|
||||||
uint8_t icon_animation_get_height(IconAnimation* instance);
|
uint8_t icon_animation_get_height(IconAnimation* instance);
|
||||||
|
|
||||||
/*
|
/** Start icon animation
|
||||||
* Check if icon is animated
|
|
||||||
*/
|
|
||||||
bool icon_animation_is_animated(IconAnimation* instance);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if icon animation is active
|
|
||||||
*/
|
|
||||||
bool icon_animation_is_animating(IconAnimation* instance);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start icon animation
|
|
||||||
*/
|
*/
|
||||||
void icon_animation_start(IconAnimation* instance);
|
void icon_animation_start(IconAnimation* instance);
|
||||||
|
|
||||||
/*
|
/** Stop icon animation
|
||||||
* Stop icon animation
|
|
||||||
*/
|
*/
|
||||||
void icon_animation_stop(IconAnimation* instance);
|
void icon_animation_stop(IconAnimation* instance);
|
||||||
|
|
||||||
/*
|
/** Returns true if current frame is a last one
|
||||||
* Get current frame
|
|
||||||
*/
|
|
||||||
uint8_t icon_animation_get_current_frame(IconAnimation* instance);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns true if current frame is a last one
|
|
||||||
*/
|
*/
|
||||||
bool icon_animation_is_last_frame(IconAnimation* instance);
|
bool icon_animation_is_last_frame(IconAnimation* instance);
|
||||||
|
|
||||||
|
@ -2,20 +2,22 @@
|
|||||||
|
|
||||||
#include "icon_animation.h"
|
#include "icon_animation.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <furi.h>
|
||||||
|
|
||||||
struct IconAnimation {
|
struct IconAnimation {
|
||||||
const Icon* icon;
|
const Icon* icon;
|
||||||
uint8_t frame;
|
uint8_t frame;
|
||||||
uint32_t tick;
|
bool animating;
|
||||||
|
osTimerId_t timer;
|
||||||
|
IconAnimationCallback callback;
|
||||||
|
void* callback_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/** Get pointer to current frame data */
|
||||||
* Get pointer to current frame data
|
|
||||||
*/
|
|
||||||
const uint8_t* icon_animation_get_data(IconAnimation* instance);
|
const uint8_t* icon_animation_get_data(IconAnimation* instance);
|
||||||
|
|
||||||
/*
|
/** Advance to next frame */
|
||||||
* Advance to next frame
|
|
||||||
*/
|
|
||||||
void icon_animation_next_frame(IconAnimation* instance);
|
void icon_animation_next_frame(IconAnimation* instance);
|
||||||
|
|
||||||
|
/** IconAnimation timer callback */
|
||||||
|
void icon_animation_timer_callback(void* context);
|
||||||
|
54
applications/gui/modules/menu.c
Executable file → Normal file
54
applications/gui/modules/menu.c
Executable file → Normal file
@ -20,7 +20,7 @@ ARRAY_DEF(MenuItemArray, MenuItem, M_POD_OPLIST);
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MenuItemArray_t items;
|
MenuItemArray_t items;
|
||||||
uint8_t position;
|
size_t position;
|
||||||
} MenuModel;
|
} MenuModel;
|
||||||
|
|
||||||
static void menu_process_up(Menu* menu);
|
static void menu_process_up(Menu* menu);
|
||||||
@ -32,7 +32,7 @@ static void menu_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
|
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
|
|
||||||
uint8_t position = model->position;
|
size_t position = model->position;
|
||||||
size_t items_count = MenuItemArray_size(model->items);
|
size_t items_count = MenuItemArray_size(model->items);
|
||||||
if(items_count) {
|
if(items_count) {
|
||||||
MenuItem* item;
|
MenuItem* item;
|
||||||
@ -43,7 +43,6 @@ static void menu_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
item = MenuItemArray_get(model->items, shift_position);
|
item = MenuItemArray_get(model->items, shift_position);
|
||||||
if(item->icon) {
|
if(item->icon) {
|
||||||
canvas_draw_icon_animation(canvas, 4, 3, item->icon);
|
canvas_draw_icon_animation(canvas, 4, 3, item->icon);
|
||||||
icon_animation_stop(item->icon);
|
|
||||||
}
|
}
|
||||||
canvas_draw_str(canvas, 22, 14, item->label);
|
canvas_draw_str(canvas, 22, 14, item->label);
|
||||||
// Second line main
|
// Second line main
|
||||||
@ -52,7 +51,6 @@ static void menu_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
item = MenuItemArray_get(model->items, shift_position);
|
item = MenuItemArray_get(model->items, shift_position);
|
||||||
if(item->icon) {
|
if(item->icon) {
|
||||||
canvas_draw_icon_animation(canvas, 4, 25, item->icon);
|
canvas_draw_icon_animation(canvas, 4, 25, item->icon);
|
||||||
icon_animation_start(item->icon);
|
|
||||||
}
|
}
|
||||||
canvas_draw_str(canvas, 22, 36, item->label);
|
canvas_draw_str(canvas, 22, 36, item->label);
|
||||||
// Third line
|
// Third line
|
||||||
@ -61,7 +59,6 @@ static void menu_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
item = MenuItemArray_get(model->items, shift_position);
|
item = MenuItemArray_get(model->items, shift_position);
|
||||||
if(item->icon) {
|
if(item->icon) {
|
||||||
canvas_draw_icon_animation(canvas, 4, 47, item->icon);
|
canvas_draw_icon_animation(canvas, 4, 47, item->icon);
|
||||||
icon_animation_stop(item->icon);
|
|
||||||
}
|
}
|
||||||
canvas_draw_str(canvas, 22, 58, item->label);
|
canvas_draw_str(canvas, 22, 58, item->label);
|
||||||
// Frame and scrollbar
|
// Frame and scrollbar
|
||||||
@ -93,6 +90,30 @@ static bool menu_input_callback(InputEvent* event, void* context) {
|
|||||||
return consumed;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void menu_enter(void* context) {
|
||||||
|
Menu* menu = context;
|
||||||
|
with_view_model(
|
||||||
|
menu->view, (MenuModel * model) {
|
||||||
|
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||||
|
if(item && item->icon) {
|
||||||
|
icon_animation_start(item->icon);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_exit(void* context) {
|
||||||
|
Menu* menu = context;
|
||||||
|
with_view_model(
|
||||||
|
menu->view, (MenuModel * model) {
|
||||||
|
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||||
|
if(item && item->icon) {
|
||||||
|
icon_animation_stop(item->icon);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Menu* menu_alloc() {
|
Menu* menu_alloc() {
|
||||||
Menu* menu = furi_alloc(sizeof(Menu));
|
Menu* menu = furi_alloc(sizeof(Menu));
|
||||||
menu->view = view_alloc(menu->view);
|
menu->view = view_alloc(menu->view);
|
||||||
@ -100,6 +121,8 @@ Menu* menu_alloc() {
|
|||||||
view_allocate_model(menu->view, ViewModelTypeLocking, sizeof(MenuModel));
|
view_allocate_model(menu->view, ViewModelTypeLocking, sizeof(MenuModel));
|
||||||
view_set_draw_callback(menu->view, menu_draw_callback);
|
view_set_draw_callback(menu->view, menu_draw_callback);
|
||||||
view_set_input_callback(menu->view, menu_input_callback);
|
view_set_input_callback(menu->view, menu_input_callback);
|
||||||
|
view_set_enter_callback(menu->view, menu_enter);
|
||||||
|
view_set_exit_callback(menu->view, menu_exit);
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
menu->view, (MenuModel * model) {
|
menu->view, (MenuModel * model) {
|
||||||
@ -143,6 +166,7 @@ void menu_add_item(
|
|||||||
item = MenuItemArray_push_new(model->items);
|
item = MenuItemArray_push_new(model->items);
|
||||||
item->label = label;
|
item->label = label;
|
||||||
item->icon = icon;
|
item->icon = icon;
|
||||||
|
view_tie_icon_animation(menu->view, item->icon);
|
||||||
item->index = index;
|
item->index = index;
|
||||||
item->callback = callback;
|
item->callback = callback;
|
||||||
item->callback_context = context;
|
item->callback_context = context;
|
||||||
@ -175,11 +199,21 @@ void menu_set_selected_item(Menu* menu, uint32_t index) {
|
|||||||
static void menu_process_up(Menu* menu) {
|
static void menu_process_up(Menu* menu) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
menu->view, (MenuModel * model) {
|
menu->view, (MenuModel * model) {
|
||||||
|
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||||
|
if(item && item->icon) {
|
||||||
|
icon_animation_stop(item->icon);
|
||||||
|
}
|
||||||
|
|
||||||
if(model->position > 0) {
|
if(model->position > 0) {
|
||||||
model->position--;
|
model->position--;
|
||||||
} else {
|
} else {
|
||||||
model->position = MenuItemArray_size(model->items) - 1;
|
model->position = MenuItemArray_size(model->items) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item = MenuItemArray_get(model->items, model->position);
|
||||||
|
if(item && item->icon) {
|
||||||
|
icon_animation_start(item->icon);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -187,11 +221,21 @@ static void menu_process_up(Menu* menu) {
|
|||||||
static void menu_process_down(Menu* menu) {
|
static void menu_process_down(Menu* menu) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
menu->view, (MenuModel * model) {
|
menu->view, (MenuModel * model) {
|
||||||
|
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||||
|
if(item && item->icon) {
|
||||||
|
icon_animation_stop(item->icon);
|
||||||
|
}
|
||||||
|
|
||||||
if(model->position < MenuItemArray_size(model->items) - 1) {
|
if(model->position < MenuItemArray_size(model->items) - 1) {
|
||||||
model->position++;
|
model->position++;
|
||||||
} else {
|
} else {
|
||||||
model->position = 0;
|
model->position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item = MenuItemArray_get(model->items, model->position);
|
||||||
|
if(item && item->icon) {
|
||||||
|
icon_animation_start(item->icon);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,11 @@ void view_free(View* view) {
|
|||||||
free(view);
|
free(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void view_tie_icon_animation(View* view, IconAnimation* icon_animation) {
|
||||||
|
furi_assert(view);
|
||||||
|
icon_animation_set_update_callback(icon_animation, view_icon_animation_callback, view);
|
||||||
|
}
|
||||||
|
|
||||||
void view_set_draw_callback(View* view, ViewDrawCallback callback) {
|
void view_set_draw_callback(View* view, ViewDrawCallback callback) {
|
||||||
furi_assert(view);
|
furi_assert(view);
|
||||||
furi_assert(view->draw_callback == NULL);
|
furi_assert(view->draw_callback == NULL);
|
||||||
@ -120,6 +125,14 @@ void view_commit_model(View* view, bool update) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void view_icon_animation_callback(IconAnimation* instance, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
View* view = context;
|
||||||
|
if(view->update_callback) {
|
||||||
|
view->update_callback(view, view->update_callback_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void view_unlock_model(View* view) {
|
void view_unlock_model(View* view) {
|
||||||
furi_assert(view);
|
furi_assert(view);
|
||||||
if(view->model_type == ViewModelTypeLocking) {
|
if(view->model_type == ViewModelTypeLocking) {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <input/input.h>
|
#include <input/input.h>
|
||||||
|
|
||||||
|
#include "icon_animation.h"
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -10,9 +12,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Hides drawing view_port */
|
/** Hides drawing view_port */
|
||||||
#define VIEW_NONE 0xFFFFFFFF
|
#define VIEW_NONE 0xFFFFFFFF
|
||||||
/* Ignore navigation event */
|
|
||||||
|
/** Ignore navigation event */
|
||||||
#define VIEW_IGNORE 0xFFFFFFFE
|
#define VIEW_IGNORE 0xFFFFFFFE
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -20,17 +23,17 @@ typedef enum {
|
|||||||
ViewOrientationVertical,
|
ViewOrientationVertical,
|
||||||
} ViewOrientation;
|
} ViewOrientation;
|
||||||
|
|
||||||
/* View, anonymous type */
|
/** View, anonymous type */
|
||||||
typedef struct View View;
|
typedef struct View View;
|
||||||
|
|
||||||
/* View Draw callback
|
/** View Draw callback
|
||||||
* @param canvas, pointer to canvas
|
* @param canvas, pointer to canvas
|
||||||
* @param view_model, pointer to context
|
* @param view_model, pointer to context
|
||||||
* @warning called from GUI thread
|
* @warning called from GUI thread
|
||||||
*/
|
*/
|
||||||
typedef void (*ViewDrawCallback)(Canvas* canvas, void* model);
|
typedef void (*ViewDrawCallback)(Canvas* canvas, void* model);
|
||||||
|
|
||||||
/* View Input callback
|
/** View Input callback
|
||||||
* @param event, pointer to input event data
|
* @param event, pointer to input event data
|
||||||
* @param context, pointer to context
|
* @param context, pointer to context
|
||||||
* @return true if event handled, false if event ignored
|
* @return true if event handled, false if event ignored
|
||||||
@ -38,27 +41,27 @@ typedef void (*ViewDrawCallback)(Canvas* canvas, void* model);
|
|||||||
*/
|
*/
|
||||||
typedef bool (*ViewInputCallback)(InputEvent* event, void* context);
|
typedef bool (*ViewInputCallback)(InputEvent* event, void* context);
|
||||||
|
|
||||||
/* View Custom callback
|
/** View Custom callback
|
||||||
* @param event, number of custom event
|
* @param event, number of custom event
|
||||||
* @param context, pointer to context
|
* @param context, pointer to context
|
||||||
* @return true if event handled, false if event ignored
|
* @return true if event handled, false if event ignored
|
||||||
*/
|
*/
|
||||||
typedef bool (*ViewCustomCallback)(uint32_t event, void* context);
|
typedef bool (*ViewCustomCallback)(uint32_t event, void* context);
|
||||||
|
|
||||||
/* View navigation callback
|
/** View navigation callback
|
||||||
* @param context, pointer to context
|
* @param context, pointer to context
|
||||||
* @return next view id
|
* @return next view id
|
||||||
* @warning called from GUI thread
|
* @warning called from GUI thread
|
||||||
*/
|
*/
|
||||||
typedef uint32_t (*ViewNavigationCallback)(void* context);
|
typedef uint32_t (*ViewNavigationCallback)(void* context);
|
||||||
|
|
||||||
/* View callback
|
/** View callback
|
||||||
* @param context, pointer to context
|
* @param context, pointer to context
|
||||||
* @warning called from GUI thread
|
* @warning called from GUI thread
|
||||||
*/
|
*/
|
||||||
typedef void (*ViewCallback)(void* context);
|
typedef void (*ViewCallback)(void* context);
|
||||||
|
|
||||||
/* View Update Callback
|
/** View Update Callback
|
||||||
* Called upon model change, need to be propagated to GUI throw ViewPort update
|
* Called upon model change, need to be propagated to GUI throw ViewPort update
|
||||||
* @param view, pointer to view
|
* @param view, pointer to view
|
||||||
* @param context, pointer to context
|
* @param context, pointer to context
|
||||||
@ -66,7 +69,7 @@ typedef void (*ViewCallback)(void* context);
|
|||||||
*/
|
*/
|
||||||
typedef void (*ViewUpdateCallback)(View* view, void* context);
|
typedef void (*ViewUpdateCallback)(View* view, void* context);
|
||||||
|
|
||||||
/* View model types */
|
/** View model types */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* Model is not allocated */
|
/* Model is not allocated */
|
||||||
ViewModelTypeNone,
|
ViewModelTypeNone,
|
||||||
@ -80,97 +83,103 @@ typedef enum {
|
|||||||
ViewModelTypeLocking,
|
ViewModelTypeLocking,
|
||||||
} ViewModelType;
|
} ViewModelType;
|
||||||
|
|
||||||
/* Allocate and init View
|
/** Allocate and init View
|
||||||
* @return pointer to View
|
* @return View instance
|
||||||
*/
|
*/
|
||||||
View* view_alloc();
|
View* view_alloc();
|
||||||
|
|
||||||
/* Free View
|
/** Free View
|
||||||
* @param pointer to View
|
* @param View instance
|
||||||
*/
|
*/
|
||||||
void view_free(View* view);
|
void view_free(View* view);
|
||||||
|
|
||||||
/* Set View Draw callback
|
/** Tie IconAnimation with View
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
|
* @param icon_animation, IconAnimation instance
|
||||||
|
*/
|
||||||
|
void view_tie_icon_animation(View* view, IconAnimation* icon_animation);
|
||||||
|
|
||||||
|
/** Set View Draw callback
|
||||||
|
* @param view, View instance
|
||||||
* @param callback, draw callback
|
* @param callback, draw callback
|
||||||
*/
|
*/
|
||||||
void view_set_draw_callback(View* view, ViewDrawCallback callback);
|
void view_set_draw_callback(View* view, ViewDrawCallback callback);
|
||||||
|
|
||||||
/* Set View Input callback
|
/** Set View Input callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param callback, input callback
|
* @param callback, input callback
|
||||||
*/
|
*/
|
||||||
void view_set_input_callback(View* view, ViewInputCallback callback);
|
void view_set_input_callback(View* view, ViewInputCallback callback);
|
||||||
|
|
||||||
/* Set View Custom callback
|
/** Set View Custom callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param callback, input callback
|
* @param callback, input callback
|
||||||
*/
|
*/
|
||||||
void view_set_custom_callback(View* view, ViewCustomCallback callback);
|
void view_set_custom_callback(View* view, ViewCustomCallback callback);
|
||||||
|
|
||||||
/* Set Navigation Previous callback
|
/** Set Navigation Previous callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param callback, input callback
|
* @param callback, input callback
|
||||||
*/
|
*/
|
||||||
void view_set_previous_callback(View* view, ViewNavigationCallback callback);
|
void view_set_previous_callback(View* view, ViewNavigationCallback callback);
|
||||||
|
|
||||||
/* Set Enter callback
|
/** Set Enter callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param callback, callback
|
* @param callback, callback
|
||||||
*/
|
*/
|
||||||
void view_set_enter_callback(View* view, ViewCallback callback);
|
void view_set_enter_callback(View* view, ViewCallback callback);
|
||||||
|
|
||||||
/* Set Exit callback
|
/** Set Exit callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param callback, callback
|
* @param callback, callback
|
||||||
*/
|
*/
|
||||||
void view_set_exit_callback(View* view, ViewCallback callback);
|
void view_set_exit_callback(View* view, ViewCallback callback);
|
||||||
|
|
||||||
/* Set Update callback
|
/** Set Update callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param callback, callback
|
* @param callback, callback
|
||||||
*/
|
*/
|
||||||
void view_set_update_callback(View* view, ViewUpdateCallback callback);
|
void view_set_update_callback(View* view, ViewUpdateCallback callback);
|
||||||
|
|
||||||
/* Set View Draw callback
|
/** Set View Draw callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param context, context for callbacks
|
* @param context, context for callbacks
|
||||||
*/
|
*/
|
||||||
void view_set_update_callback_context(View* view, void* context);
|
void view_set_update_callback_context(View* view, void* context);
|
||||||
|
|
||||||
/* Set View Draw callback
|
/** Set View Draw callback
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param context, context for callbacks
|
* @param context, context for callbacks
|
||||||
*/
|
*/
|
||||||
void view_set_context(View* view, void* context);
|
void view_set_context(View* view, void* context);
|
||||||
|
|
||||||
/* Set View Orientation
|
/** Set View Orientation
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param orientation, either vertical or horizontal
|
* @param orientation, either vertical or horizontal
|
||||||
*/
|
*/
|
||||||
void view_set_orientation(View* view, ViewOrientation orientation);
|
void view_set_orientation(View* view, ViewOrientation orientation);
|
||||||
|
|
||||||
/* Allocate view model.
|
/** Allocate view model.
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param type, View Model Type
|
* @param type, View Model Type
|
||||||
* @param size, size
|
* @param size, size
|
||||||
*/
|
*/
|
||||||
void view_allocate_model(View* view, ViewModelType type, size_t size);
|
void view_allocate_model(View* view, ViewModelType type, size_t size);
|
||||||
|
|
||||||
/* Free view model data memory.
|
/** Free view model data memory.
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
*/
|
*/
|
||||||
void view_free_model(View* view);
|
void view_free_model(View* view);
|
||||||
|
|
||||||
/* Get view model data
|
/** Get view model data
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @return pointer to model data
|
* @return pointer to model data
|
||||||
* @warning Don't forget to commit model changes
|
* @warning Don't forget to commit model changes
|
||||||
*/
|
*/
|
||||||
void* view_get_model(View* view);
|
void* view_get_model(View* view);
|
||||||
|
|
||||||
/* Commit view model
|
/** Commit view model
|
||||||
* @param view, pointer to View
|
* @param view, View instance
|
||||||
* @param update, true if you want to emit view update, false otherwise
|
* @param update, true if you want to emit view update, false otherwise
|
||||||
*/
|
*/
|
||||||
void view_commit_model(View* view, bool update);
|
void view_commit_model(View* view, bool update);
|
||||||
@ -187,7 +196,7 @@ void view_commit_model(View* view, bool update);
|
|||||||
view_commit_model(view, update); \
|
view_commit_model(view, update); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/*
|
/**
|
||||||
* With clause for view model
|
* With clause for view model
|
||||||
* @param view, View instance pointer
|
* @param view, View instance pointer
|
||||||
* @param function_body a (){} lambda declaration, executed within you parent function context
|
* @param function_body a (){} lambda declaration, executed within you parent function context
|
||||||
|
@ -26,6 +26,9 @@ struct View {
|
|||||||
void* context;
|
void* context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* IconAnimation tie callback */
|
||||||
|
void view_icon_animation_callback(IconAnimation* instance, void* context);
|
||||||
|
|
||||||
/* Unlock model */
|
/* Unlock model */
|
||||||
void view_unlock_model(View* view);
|
void view_unlock_model(View* view);
|
||||||
|
|
||||||
|
@ -14,48 +14,41 @@ typedef enum {
|
|||||||
ViewPortOrientationVertical,
|
ViewPortOrientationVertical,
|
||||||
} ViewPortOrientation;
|
} ViewPortOrientation;
|
||||||
|
|
||||||
/*
|
/** ViewPort Draw callback
|
||||||
* ViewPort Draw callback
|
|
||||||
* @warning called from GUI thread
|
* @warning called from GUI thread
|
||||||
*/
|
*/
|
||||||
typedef void (*ViewPortDrawCallback)(Canvas* canvas, void* context);
|
typedef void (*ViewPortDrawCallback)(Canvas* canvas, void* context);
|
||||||
|
|
||||||
/*
|
/** ViewPort Input callback
|
||||||
* ViewPort Input callback
|
|
||||||
* @warning called from GUI thread
|
* @warning called from GUI thread
|
||||||
*/
|
*/
|
||||||
typedef void (*ViewPortInputCallback)(InputEvent* event, void* context);
|
typedef void (*ViewPortInputCallback)(InputEvent* event, void* context);
|
||||||
|
|
||||||
/*
|
/** ViewPort allocator
|
||||||
* ViewPort allocator
|
|
||||||
* always returns view_port or stops system if not enough memory.
|
* always returns view_port or stops system if not enough memory.
|
||||||
*/
|
*/
|
||||||
ViewPort* view_port_alloc();
|
ViewPort* view_port_alloc();
|
||||||
|
|
||||||
/*
|
/** ViewPort deallocator
|
||||||
* ViewPort deallocator
|
|
||||||
* Ensure that view_port was unregistered in GUI system before use.
|
* Ensure that view_port was unregistered in GUI system before use.
|
||||||
*/
|
*/
|
||||||
void view_port_free(ViewPort* view_port);
|
void view_port_free(ViewPort* view_port);
|
||||||
|
|
||||||
/*
|
/** Set view_port width.
|
||||||
* Set view_port width.
|
|
||||||
* Will be used to limit canvas drawing area and autolayout feature.
|
* Will be used to limit canvas drawing area and autolayout feature.
|
||||||
* @param width - wanted width, 0 - auto.
|
* @param width - wanted width, 0 - auto.
|
||||||
*/
|
*/
|
||||||
void view_port_set_width(ViewPort* view_port, uint8_t width);
|
void view_port_set_width(ViewPort* view_port, uint8_t width);
|
||||||
uint8_t view_port_get_width(ViewPort* view_port);
|
uint8_t view_port_get_width(ViewPort* view_port);
|
||||||
|
|
||||||
/*
|
/** Set view_port height.
|
||||||
* Set view_port height.
|
|
||||||
* Will be used to limit canvas drawing area and autolayout feature.
|
* Will be used to limit canvas drawing area and autolayout feature.
|
||||||
* @param height - wanted height, 0 - auto.
|
* @param height - wanted height, 0 - auto.
|
||||||
*/
|
*/
|
||||||
void view_port_set_height(ViewPort* view_port, uint8_t height);
|
void view_port_set_height(ViewPort* view_port, uint8_t height);
|
||||||
uint8_t view_port_get_height(ViewPort* view_port);
|
uint8_t view_port_get_height(ViewPort* view_port);
|
||||||
|
|
||||||
/*
|
/** Enable or disable view_port rendering.
|
||||||
* Enable or disable view_port rendering.
|
|
||||||
* @param view_port - ViewPort instance
|
* @param view_port - ViewPort instance
|
||||||
* @param enabled
|
* @param enabled
|
||||||
* @warning automatically dispatches update event
|
* @warning automatically dispatches update event
|
||||||
@ -63,8 +56,7 @@ uint8_t view_port_get_height(ViewPort* view_port);
|
|||||||
void view_port_enabled_set(ViewPort* view_port, bool enabled);
|
void view_port_enabled_set(ViewPort* view_port, bool enabled);
|
||||||
bool view_port_is_enabled(ViewPort* view_port);
|
bool view_port_is_enabled(ViewPort* view_port);
|
||||||
|
|
||||||
/*
|
/** ViewPort event callbacks
|
||||||
* ViewPort event callbacks
|
|
||||||
* @param callback - appropriate callback function
|
* @param callback - appropriate callback function
|
||||||
* @param context - context to pass to callback
|
* @param context - context to pass to callback
|
||||||
*/
|
*/
|
||||||
@ -74,14 +66,12 @@ void view_port_input_callback_set(
|
|||||||
ViewPortInputCallback callback,
|
ViewPortInputCallback callback,
|
||||||
void* context);
|
void* context);
|
||||||
|
|
||||||
/*
|
/** Emit update signal to GUI system.
|
||||||
* Emit update signal to GUI system.
|
|
||||||
* Rendering will happen later after GUI system process signal.
|
* Rendering will happen later after GUI system process signal.
|
||||||
*/
|
*/
|
||||||
void view_port_update(ViewPort* view_port);
|
void view_port_update(ViewPort* view_port);
|
||||||
|
|
||||||
/*
|
/** Set ViewPort orientation.
|
||||||
* Set ViewPort orientation.
|
|
||||||
* @param orientation, display orientation, horizontal or vertical.
|
* @param orientation, display orientation, horizontal or vertical.
|
||||||
*/
|
*/
|
||||||
void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation);
|
void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation);
|
||||||
|
38
applications/power/power_service/power.c
Executable file → Normal file
38
applications/power/power_service/power.c
Executable file → Normal file
@ -97,23 +97,27 @@ static void power_check_charging_state(Power* power) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void power_update_info(Power* power) {
|
static bool power_update_info(Power* power) {
|
||||||
|
PowerInfo info;
|
||||||
|
|
||||||
|
info.charge = furi_hal_power_get_pct();
|
||||||
|
info.health = furi_hal_power_get_bat_health_pct();
|
||||||
|
info.capacity_remaining = furi_hal_power_get_battery_remaining_capacity();
|
||||||
|
info.capacity_full = furi_hal_power_get_battery_full_capacity();
|
||||||
|
info.current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger);
|
||||||
|
info.current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge);
|
||||||
|
info.voltage_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger);
|
||||||
|
info.voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge);
|
||||||
|
info.voltage_vbus = furi_hal_power_get_usb_voltage();
|
||||||
|
info.temperature_charger = furi_hal_power_get_battery_temperature(FuriHalPowerICCharger);
|
||||||
|
info.temperature_gauge = furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge);
|
||||||
|
|
||||||
osMutexAcquire(power->info_mtx, osWaitForever);
|
osMutexAcquire(power->info_mtx, osWaitForever);
|
||||||
PowerInfo* info = &power->info;
|
bool need_refresh = power->info.charge != info.charge;
|
||||||
|
power->info = info;
|
||||||
info->charge = furi_hal_power_get_pct();
|
|
||||||
info->health = furi_hal_power_get_bat_health_pct();
|
|
||||||
info->capacity_remaining = furi_hal_power_get_battery_remaining_capacity();
|
|
||||||
info->capacity_full = furi_hal_power_get_battery_full_capacity();
|
|
||||||
info->current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger);
|
|
||||||
info->current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge);
|
|
||||||
info->voltage_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger);
|
|
||||||
info->voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge);
|
|
||||||
info->voltage_vbus = furi_hal_power_get_usb_voltage();
|
|
||||||
info->temperature_charger = furi_hal_power_get_battery_temperature(FuriHalPowerICCharger);
|
|
||||||
info->temperature_gauge = furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge);
|
|
||||||
|
|
||||||
osMutexRelease(power->info_mtx);
|
osMutexRelease(power->info_mtx);
|
||||||
|
|
||||||
|
return need_refresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void power_check_low_battery(Power* power) {
|
static void power_check_low_battery(Power* power) {
|
||||||
@ -156,7 +160,7 @@ int32_t power_srv(void* p) {
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
// Update data from gauge and charger
|
// Update data from gauge and charger
|
||||||
power_update_info(power);
|
bool need_refresh = power_update_info(power);
|
||||||
|
|
||||||
// Check low battery level
|
// Check low battery level
|
||||||
power_check_low_battery(power);
|
power_check_low_battery(power);
|
||||||
@ -168,7 +172,7 @@ int32_t power_srv(void* p) {
|
|||||||
power_check_battery_level_change(power);
|
power_check_battery_level_change(power);
|
||||||
|
|
||||||
// Update battery view port
|
// Update battery view port
|
||||||
view_port_update(power->battery_view_port);
|
if(need_refresh) view_port_update(power->battery_view_port);
|
||||||
|
|
||||||
osDelay(1000);
|
osDelay(1000);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 830 B |
@ -1 +1 @@
|
|||||||
10
|
1
|
@ -1 +1 @@
|
|||||||
10
|
1
|
Loading…
Reference in New Issue
Block a user