Add card acceptance animation
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,6 +2,6 @@ bin/
|
|||||||
obj/
|
obj/
|
||||||
.cache
|
.cache
|
||||||
.build
|
.build
|
||||||
|
.config.old
|
||||||
build.log
|
build.log
|
||||||
include
|
include
|
||||||
.config.old
|
|
||||||
|
|||||||
14
inc/idle.h
Normal file
14
inc/idle.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/**********************************************************
|
||||||
|
* File: idle.h
|
||||||
|
*
|
||||||
|
* Description: Idle screen for standby
|
||||||
|
*********************************************************/
|
||||||
|
#ifndef IDLE_H_CGT5FQUY
|
||||||
|
#define IDLE_H_CGT5FQUY
|
||||||
|
|
||||||
|
#include "lvgl/lvgl.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
void screen_idle_create(lv_obj_t *screen);
|
||||||
|
void screen_idle_update();
|
||||||
|
|
||||||
|
#endif /* end of include guard: IDLE_H_CGT5FQUY */
|
||||||
168
src/idle.c
Normal file
168
src/idle.c
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/**********************************************************
|
||||||
|
* File: idle.c
|
||||||
|
*
|
||||||
|
* Description: Idle screen for standby
|
||||||
|
*********************************************************/
|
||||||
|
#include "lvgl/lvgl.h" // IWYU pragma: keep
|
||||||
|
#include "lvgl/src/misc/lv_anim.h"
|
||||||
|
#include "lvgl/src/widgets/label/lv_label.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define ARROW_DURATION 395
|
||||||
|
#define CARDS_DURATION 4000
|
||||||
|
#define CARDS_RATE 3.0
|
||||||
|
#define CARDS_MID 0.5
|
||||||
|
#define CARDS_DELAY 0.09
|
||||||
|
#define WHITE lv_color_hex(0xffffff)
|
||||||
|
|
||||||
|
LV_FONT_DECLARE(montserrat_15);
|
||||||
|
LV_FONT_DECLARE(dejavu_28);
|
||||||
|
LV_FONT_DECLARE(dejavu_bold_10);
|
||||||
|
LV_FONT_DECLARE(dejavu_cbold_52);
|
||||||
|
LV_IMG_DECLARE(hop_arrow);
|
||||||
|
LV_IMG_DECLARE(hop_logo);
|
||||||
|
LV_IMG_DECLARE(hop_cards);
|
||||||
|
|
||||||
|
static lv_anim_t arrow_anim_template;
|
||||||
|
static lv_anim_t *running_arrow_anim;
|
||||||
|
|
||||||
|
static lv_anim_t cards_anim_template;
|
||||||
|
static lv_anim_t *running_cards_anim;
|
||||||
|
|
||||||
|
lv_obj_t *label_time;
|
||||||
|
lv_obj_t *label_date;
|
||||||
|
lv_obj_t *label_tap;
|
||||||
|
lv_obj_t *label_sku;
|
||||||
|
lv_obj_t *label_contactless;
|
||||||
|
lv_obj_t *img_arrow;
|
||||||
|
lv_obj_t *img_logo;
|
||||||
|
lv_obj_t *img_cards;
|
||||||
|
|
||||||
|
time_t curr_time;
|
||||||
|
struct tm *local_time;
|
||||||
|
char buf[100];
|
||||||
|
|
||||||
|
double clamp(double d, double min, double max)
|
||||||
|
{
|
||||||
|
const double t = d < min ? min : d;
|
||||||
|
return t > max ? max : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_opa(void *var, int32_t value)
|
||||||
|
{
|
||||||
|
lv_obj_t *obj = (lv_obj_t *)var;
|
||||||
|
lv_obj_set_style_image_opa(obj, value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cards_anim_cb(void *var, int32_t value)
|
||||||
|
{
|
||||||
|
double progress = (double)value / 0x7fff;
|
||||||
|
double prompt_opa = progress - (CARDS_MID - CARDS_DELAY / 2);
|
||||||
|
prompt_opa *= CARDS_RATE;
|
||||||
|
prompt_opa = clamp(prompt_opa, 0.0, 1.0) * 255;
|
||||||
|
double cards_opa = -progress + (CARDS_MID - CARDS_DELAY / 2);
|
||||||
|
cards_opa *= CARDS_RATE;
|
||||||
|
cards_opa = clamp(cards_opa, 0.0, 1.0) * 255;
|
||||||
|
lv_obj_set_style_text_opa(label_tap, (int32_t)prompt_opa, 0);
|
||||||
|
lv_obj_set_style_image_opa(img_cards, (int32_t)cards_opa, 0);
|
||||||
|
lv_obj_set_style_text_opa(label_contactless, (int32_t)cards_opa, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_idle_create(lv_obj_t *screen)
|
||||||
|
{
|
||||||
|
/*Change the active screen's background color*/
|
||||||
|
lv_obj_set_style_bg_color(screen, lv_color_hex(0), LV_PART_MAIN);
|
||||||
|
|
||||||
|
// hop logo
|
||||||
|
img_logo = lv_img_create(screen);
|
||||||
|
lv_img_set_src(img_logo, &hop_logo);
|
||||||
|
lv_obj_align(img_logo, LV_ALIGN_CENTER, 0, -98);
|
||||||
|
|
||||||
|
// flickering arrow
|
||||||
|
img_arrow = lv_img_create(screen);
|
||||||
|
lv_img_set_src(img_arrow, &hop_arrow);
|
||||||
|
lv_obj_align(img_arrow, LV_ALIGN_CENTER, 0, 155);
|
||||||
|
lv_obj_set_style_img_opa(img_arrow, 100, 0);
|
||||||
|
|
||||||
|
lv_anim_init(&arrow_anim_template);
|
||||||
|
lv_anim_set_exec_cb(&arrow_anim_template, set_opa);
|
||||||
|
lv_anim_set_values(&arrow_anim_template, 0, 255);
|
||||||
|
lv_anim_set_duration(&arrow_anim_template, ARROW_DURATION);
|
||||||
|
lv_anim_set_path_cb(&arrow_anim_template, lv_anim_path_ease_out);
|
||||||
|
lv_anim_set_reverse_duration(&arrow_anim_template, ARROW_DURATION);
|
||||||
|
lv_anim_set_repeat_count(&arrow_anim_template, LV_ANIM_REPEAT_INFINITE);
|
||||||
|
lv_anim_set_var(&arrow_anim_template, img_arrow);
|
||||||
|
|
||||||
|
running_arrow_anim = lv_anim_start(&arrow_anim_template);
|
||||||
|
|
||||||
|
// tap prompt
|
||||||
|
label_tap = lv_label_create(screen);
|
||||||
|
lv_label_set_text(label_tap, "Tap card or phone below");
|
||||||
|
lv_obj_set_style_text_font(label_tap, &dejavu_cbold_52, 0);
|
||||||
|
lv_obj_set_style_text_color(label_tap, WHITE, 0);
|
||||||
|
lv_obj_align(label_tap, LV_ALIGN_CENTER, 0, 83);
|
||||||
|
|
||||||
|
// card acceptance logos
|
||||||
|
img_cards = lv_img_create(screen);
|
||||||
|
lv_img_set_src(img_cards, &hop_cards);
|
||||||
|
lv_obj_align(img_cards, LV_ALIGN_CENTER, 0, 75);
|
||||||
|
|
||||||
|
// contactless payments note
|
||||||
|
label_contactless = lv_label_create(screen);
|
||||||
|
lv_label_set_text(label_contactless, "Contactless payment only");
|
||||||
|
lv_obj_set_style_text_font(label_contactless, &montserrat_15, 0);
|
||||||
|
lv_obj_set_style_text_color(label_contactless, WHITE, 0);
|
||||||
|
lv_obj_align(label_contactless, LV_ALIGN_CENTER, 0, 118);
|
||||||
|
|
||||||
|
// animation for tap prompt/card acceptance
|
||||||
|
lv_anim_init(&cards_anim_template);
|
||||||
|
lv_anim_set_exec_cb(&cards_anim_template, cards_anim_cb);
|
||||||
|
lv_anim_set_values(&cards_anim_template, 0, 0x7fff);
|
||||||
|
lv_anim_set_duration(&cards_anim_template, CARDS_DURATION);
|
||||||
|
lv_anim_set_path_cb(&cards_anim_template, lv_anim_path_linear);
|
||||||
|
lv_anim_set_reverse_duration(&cards_anim_template, CARDS_DURATION);
|
||||||
|
lv_anim_set_repeat_count(&cards_anim_template, LV_ANIM_REPEAT_INFINITE);
|
||||||
|
lv_anim_set_var(&cards_anim_template, label_contactless);
|
||||||
|
running_cards_anim = lv_anim_start(&cards_anim_template);
|
||||||
|
|
||||||
|
// device number at bottom
|
||||||
|
label_sku = lv_label_create(screen);
|
||||||
|
lv_label_set_text(label_sku, "DEMO-DEV-LVGL");
|
||||||
|
lv_obj_set_style_text_font(label_sku, &dejavu_bold_10, 0);
|
||||||
|
lv_obj_set_style_text_color(label_sku, WHITE, 0);
|
||||||
|
lv_obj_align(label_sku, LV_ALIGN_CENTER, 0, 233);
|
||||||
|
|
||||||
|
// date in bottom left
|
||||||
|
label_date = lv_label_create(screen);
|
||||||
|
lv_label_set_text(label_date, "01-01-99");
|
||||||
|
lv_obj_set_style_text_font(label_date, &dejavu_28, 0);
|
||||||
|
lv_obj_set_style_text_color(label_date, WHITE, 0);
|
||||||
|
lv_obj_align(label_date, LV_ALIGN_CENTER, -275, 226);
|
||||||
|
|
||||||
|
// time in bottom right
|
||||||
|
label_time = lv_label_create(screen);
|
||||||
|
lv_label_set_text(label_time, "12:59 a.m.");
|
||||||
|
lv_obj_set_style_text_font(label_time, &dejavu_28, 0);
|
||||||
|
lv_obj_set_style_text_color(label_time, WHITE, 0);
|
||||||
|
lv_obj_align(label_time, LV_ALIGN_CENTER, 275, 226);
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_idle_update()
|
||||||
|
{
|
||||||
|
time(&curr_time);
|
||||||
|
local_time = localtime(&curr_time);
|
||||||
|
strftime(buf, 100, "%m-%d-%y", local_time);
|
||||||
|
lv_label_set_text(label_date, buf);
|
||||||
|
strftime(buf, 90, "%l:%M %P", local_time);
|
||||||
|
int i = 0;
|
||||||
|
while (buf[i])
|
||||||
|
i++;
|
||||||
|
if (i > 0) {
|
||||||
|
buf[i - 1] = '.';
|
||||||
|
buf[i] = 'm';
|
||||||
|
buf[i + 1] = '.';
|
||||||
|
buf[i + 2] = '\0';
|
||||||
|
}
|
||||||
|
lv_label_set_text(label_time, buf);
|
||||||
|
}
|
||||||
@@ -1,88 +1,12 @@
|
|||||||
#include "lvgl/lvgl.h" // IWYU pragma: keep
|
#include "lvgl/lvgl.h" // IWYU pragma: keep
|
||||||
#include "lvgl/src/misc/lv_anim.h"
|
|
||||||
#include "lvgl/src/widgets/label/lv_label.h"
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "idle.h"
|
||||||
#define ARROW_DELAY 395
|
|
||||||
|
|
||||||
LV_FONT_DECLARE(dejavu_28);
|
|
||||||
LV_FONT_DECLARE(dejavu_bold_10);
|
|
||||||
LV_FONT_DECLARE(dejavu_cbold_52);
|
|
||||||
LV_IMG_DECLARE(hop_arrow);
|
|
||||||
LV_IMG_DECLARE(hop_logo);
|
|
||||||
|
|
||||||
static lv_anim_t anim_template;
|
|
||||||
static lv_anim_t *running_anim;
|
|
||||||
|
|
||||||
lv_display_t *display;
|
lv_display_t *display;
|
||||||
lv_obj_t *label_time;
|
uint32_t idle_time;
|
||||||
lv_obj_t *label_date;
|
|
||||||
|
|
||||||
void set_opa(void *var, int32_t value)
|
|
||||||
{
|
|
||||||
lv_obj_t *obj = (lv_obj_t *)var;
|
|
||||||
lv_obj_set_style_image_opa(obj, value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_screen()
|
|
||||||
{
|
|
||||||
/*Change the active screen's background color*/
|
|
||||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0),
|
|
||||||
LV_PART_MAIN);
|
|
||||||
|
|
||||||
lv_obj_t *logo = lv_img_create(lv_screen_active());
|
|
||||||
lv_img_set_src(logo, &hop_logo);
|
|
||||||
lv_obj_align(logo, LV_ALIGN_CENTER, 0, -98);
|
|
||||||
|
|
||||||
lv_obj_t *arrow = lv_img_create(lv_screen_active());
|
|
||||||
lv_img_set_src(arrow, &hop_arrow);
|
|
||||||
lv_obj_align(arrow, LV_ALIGN_CENTER, 0, 155);
|
|
||||||
lv_obj_set_style_img_opa(arrow, 100, 0);
|
|
||||||
|
|
||||||
lv_anim_init(&anim_template);
|
|
||||||
lv_anim_set_exec_cb(&anim_template, set_opa);
|
|
||||||
lv_anim_set_values(&anim_template, 0, 255);
|
|
||||||
lv_anim_set_duration(&anim_template, ARROW_DELAY);
|
|
||||||
lv_anim_set_path_cb(&anim_template, lv_anim_path_ease_out);
|
|
||||||
lv_anim_set_reverse_duration(&anim_template, ARROW_DELAY);
|
|
||||||
lv_anim_set_repeat_count(&anim_template, LV_ANIM_REPEAT_INFINITE);
|
|
||||||
lv_anim_set_var(&anim_template, arrow);
|
|
||||||
|
|
||||||
running_anim = lv_anim_start(&anim_template);
|
|
||||||
|
|
||||||
lv_obj_t *label_tap = lv_label_create(lv_screen_active());
|
|
||||||
lv_label_set_text(label_tap, "Tap card or phone below");
|
|
||||||
lv_obj_set_style_text_font(label_tap, &dejavu_cbold_52, 0);
|
|
||||||
lv_obj_set_style_text_color(label_tap, lv_color_hex(0xffffff), 0);
|
|
||||||
lv_obj_align(label_tap, LV_ALIGN_CENTER, 0, 83);
|
|
||||||
|
|
||||||
lv_obj_t *label_sku = lv_label_create(lv_screen_active());
|
|
||||||
lv_label_set_text(label_sku, "DEMO-DEV-LVGL");
|
|
||||||
lv_obj_set_style_text_font(label_sku, &dejavu_bold_10, 0);
|
|
||||||
lv_obj_set_style_text_color(label_sku, lv_color_hex(0xffffff), 0);
|
|
||||||
lv_obj_align(label_sku, LV_ALIGN_CENTER, 0, 233);
|
|
||||||
|
|
||||||
label_date = lv_label_create(lv_screen_active());
|
|
||||||
lv_label_set_text(label_date, "01-01-99");
|
|
||||||
lv_obj_set_style_text_font(label_date, &dejavu_28, 0);
|
|
||||||
lv_obj_set_style_text_color(label_date, lv_color_hex(0xffffff), 0);
|
|
||||||
lv_obj_align(label_date, LV_ALIGN_CENTER, -275, 226);
|
|
||||||
|
|
||||||
label_time = lv_label_create(lv_screen_active());
|
|
||||||
lv_label_set_text(label_time, "12:59 a.m.");
|
|
||||||
lv_obj_set_style_text_font(label_time, &dejavu_28, 0);
|
|
||||||
lv_obj_set_style_text_color(label_time, lv_color_hex(0xffffff), 0);
|
|
||||||
lv_obj_align(label_time, LV_ALIGN_CENTER, 275, 226);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
uint32_t idle_time;
|
|
||||||
time_t curr_time;
|
|
||||||
struct tm *local_time;
|
|
||||||
char buf[100];
|
|
||||||
|
|
||||||
lv_init();
|
lv_init();
|
||||||
#ifdef LV_TARGET_FB
|
#ifdef LV_TARGET_FB
|
||||||
display = lv_linux_fbdev_create();
|
display = lv_linux_fbdev_create();
|
||||||
@@ -91,26 +15,12 @@ int main(int argc, char *argv[])
|
|||||||
display = lv_x11_window_create("LVGL X11 Simulation", 800, 480);
|
display = lv_x11_window_create("LVGL X11 Simulation", 800, 480);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
create_screen();
|
screen_idle_create(lv_screen_active());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Returns the time to the next timer execution */
|
/* Returns the time to the next timer execution */
|
||||||
idle_time = lv_timer_handler();
|
idle_time = lv_timer_handler();
|
||||||
time(&curr_time);
|
screen_idle_update();
|
||||||
local_time = localtime(&curr_time);
|
|
||||||
strftime(buf, 100, "%m-%d-%y", local_time);
|
|
||||||
lv_label_set_text(label_date, buf);
|
|
||||||
strftime(buf, 90, "%l:%M %P", local_time);
|
|
||||||
int i = 0;
|
|
||||||
while (buf[i])
|
|
||||||
i++;
|
|
||||||
if (i > 0) {
|
|
||||||
buf[i - 1] = '.';
|
|
||||||
buf[i] = 'm';
|
|
||||||
buf[i + 1] = '.';
|
|
||||||
buf[i + 2] = '\0';
|
|
||||||
}
|
|
||||||
lv_label_set_text(label_time, buf);
|
|
||||||
usleep(idle_time * 1000);
|
usleep(idle_time * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
92
src/res/hop_cards.c
Normal file
92
src/res/hop_cards.c
Normal file
File diff suppressed because one or more lines are too long
1516
src/res/montserrat_15.c
Normal file
1516
src/res/montserrat_15.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user