From b6bc6b9e47605ede9bffe50445d1afe3acf0ab49 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 13 Jul 2023 10:58:06 +1000 Subject: [PATCH] Ui polish and fleshing out --- src/database/index.cpp | 23 +- src/ui/CMakeLists.txt | 2 +- src/ui/font_symbols.c | 375 ++++++++++++++++-------------- src/ui/include/font_symbols.hpp | 11 + src/ui/include/screen.hpp | 9 + src/ui/include/screen_playing.hpp | 1 + src/ui/include/widget_top_bar.hpp | 31 ++- src/ui/screen.cpp | 32 +++ src/ui/screen_menu.cpp | 12 + src/ui/screen_playing.cpp | 23 +- src/ui/screen_track_browser.cpp | 9 +- src/ui/widget_top_bar.cpp | 58 +++-- tools/mkfonts.sh | 4 +- 13 files changed, 386 insertions(+), 204 deletions(-) create mode 100644 src/ui/include/font_symbols.hpp create mode 100644 src/ui/screen.cpp diff --git a/src/database/index.cpp b/src/database/index.cpp index 84d00bcd..d480e84b 100644 --- a/src/database/index.cpp +++ b/src/database/index.cpp @@ -31,6 +31,22 @@ const IndexInfo kAllTracks{ .components = {Tag::kTitle}, }; +static auto missing_component_text(Tag tag) -> std::optional { + switch (tag) { + case Tag::kArtist: + return "Unknown Artist"; + case Tag::kAlbum: + return "Unknown Album"; + case Tag::kGenre: + return "Unknown Genre"; + case Tag::kAlbumTrack: + case Tag::kDuration: + case Tag::kTitle: + default: + return {}; + } +} + auto Index(const IndexInfo& info, const Track& t, leveldb::WriteBatch* batch) -> bool { IndexKey key{ @@ -43,6 +59,7 @@ auto Index(const IndexInfo& info, const Track& t, leveldb::WriteBatch* batch) .track = {}, }; + std::optional value; for (std::uint8_t i = 0; i < info.components.size(); i++) { // Fill in the text for this depth. auto text = t.tags().at(info.components.at(i)); @@ -50,22 +67,22 @@ auto Index(const IndexInfo& info, const Track& t, leveldb::WriteBatch* batch) key.item = *text; } else { key.item = {}; + value = missing_component_text(info.components.at(i)); } // If this is the last component, then we should also fill in the track id // and title. - std::optional title; if (i == info.components.size() - 1) { key.track = t.data().id(); if (info.components.at(i) != Tag::kTitle) { - title = t.TitleOrFilename(); + value = t.TitleOrFilename(); } } else { key.track = {}; } auto encoded = EncodeIndexKey(key); - batch->Put(encoded.slice, title.value_or("")); + batch->Put(encoded.slice, value.value_or("")); // If there are more components after this, then we need to finish by // narrowing the header with the current title. diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index c69d1484..71330cb5 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -4,7 +4,7 @@ idf_component_register( SRCS "lvgl_task.cpp" "ui_fsm.cpp" "screen_splash.cpp" "screen_menu.cpp" "wheel_encoder.cpp" "screen_track_browser.cpp" "screen_playing.cpp" "themes.cpp" - "widget_top_bar.cpp" + "widget_top_bar.cpp" "screen.cpp" "splash.c" "font_fusion.c" "font_symbols.c" INCLUDE_DIRS "include" REQUIRES "drivers" "lvgl" "tinyfsm" "events" "system_fsm" "database" "esp_timer") diff --git a/src/ui/font_symbols.c b/src/ui/font_symbols.c index 0edffd7e..abc380eb 100644 --- a/src/ui/font_symbols.c +++ b/src/ui/font_symbols.c @@ -1,7 +1,7 @@ /******************************************************************************* - * Size: 10 px + * Size: 12 px * Bpp: 1 - * Opts: --font fonts/font-awesome/FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465 -r 61468,61473,61478,61479,61480,61502,61512,61515,61516,61517 -r 61521,61522,61523,61524,61543,61544,61550,61552,61553,61556 -r 61559,61560,61561,61563,61587,61589,61636,61637,61639,61671 -r 61674,61683,61724,61732,61787,61931,62016,62017,62018,62019 -r 62020,62087,62099,62212,62189,62810,63426,63650 --size 10 --bpp 1 --format lvgl -o font_symbols.c + * Opts: --font fonts/font-awesome/FontAwesome5-Solid+Brands+Regular.woff -r 0xf244,0xf243,0xf242,0xf241,0xf240 -r 0xf104,0xf0d7 -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465 -r 61468,61473,61478,61479,61480,61502,61512,61515,61516,61517 -r 61521,61522,61523,61524,61543,61544,61550,61552,61553,61556 -r 61559,61560,61561,61563,61587,61589,61636,61637,61639,61671 -r 61674,61683,61724,61732,61787,61931,62016,62017,62018,62019 -r 62020,62087,62099,62212,62189,62810,63426,63650 --size 12 --bpp 1 --format lvgl -o font_symbols.c ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -23,221 +23,256 @@ /*Store the image of the glyphs*/ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { /* U+F001 "" */ - 0x0, 0x40, 0xf1, 0xfc, 0x7d, 0x18, 0x44, 0x11, - 0x4, 0x47, 0x71, 0xdc, 0x0, + 0x0, 0x70, 0x3f, 0x1f, 0xf1, 0xfb, 0x1c, 0x31, + 0x83, 0x18, 0x31, 0x83, 0x19, 0xf7, 0x9f, 0xf8, + 0x47, 0x0, /* U+F008 "" */ - 0xbf, 0x78, 0x7e, 0x1e, 0xfd, 0xe1, 0xe8, 0x5f, - 0xfc, + 0xbf, 0xde, 0x7, 0xa0, 0x5e, 0x7, 0xbf, 0xde, + 0x7, 0xa0, 0x5e, 0x7, 0xbf, 0xd0, /* U+F00B "" */ - 0xef, 0xfb, 0xf0, 0x3, 0xbf, 0xef, 0xc0, 0xe, - 0xff, 0xbf, + 0xf7, 0xf7, 0xbf, 0xfd, 0xfe, 0x0, 0xf, 0x7f, + 0x7b, 0xff, 0xdf, 0xc0, 0x0, 0xf7, 0xf7, 0xbf, + 0xfd, 0xfc, /* U+F00C "" */ - 0x0, 0xc0, 0x64, 0x33, 0x98, 0x7c, 0xe, 0x1, - 0x0, + 0x0, 0x20, 0x7, 0x0, 0xe4, 0x1c, 0xe3, 0x87, + 0x70, 0x3e, 0x1, 0xc0, 0x8, 0x0, /* U+F00D "" */ - 0xc7, 0xdd, 0xf1, 0xc7, 0xdd, 0xf1, 0x80, + 0xc3, 0xe7, 0x7e, 0x3c, 0x3c, 0x7e, 0xe7, 0xc3, /* U+F011 "" */ - 0xc, 0xb, 0x46, 0xdb, 0x33, 0xcc, 0xf0, 0x3c, - 0x1d, 0x86, 0x3f, 0x0, + 0x6, 0x2, 0x64, 0x76, 0xe6, 0x66, 0xc6, 0x3c, + 0x63, 0xc6, 0x3c, 0x3, 0x60, 0x67, 0xe, 0x3f, + 0xc0, 0xf0, /* U+F013 "" */ - 0xc, 0xe, 0x1f, 0xff, 0xf6, 0x33, 0x1b, 0xdf, - 0xff, 0x5c, 0xe, 0x0, + 0xe, 0x4, 0xf0, 0x7f, 0xef, 0xfe, 0x71, 0xe7, + 0xc, 0x71, 0xef, 0xfe, 0x7f, 0xe4, 0xf0, 0xe, + 0x0, /* U+F015 "" */ - 0x4, 0x83, 0x70, 0xd6, 0x37, 0x6d, 0xf6, 0x7f, - 0xe, 0xe1, 0xdc, 0x3b, 0x80, + 0x3, 0x30, 0x1e, 0xc1, 0xcf, 0xc, 0xcc, 0x6f, + 0xdb, 0x7f, 0xb3, 0xff, 0xf, 0x3c, 0x3c, 0xf0, + 0xf3, 0xc0, /* U+F019 "" */ - 0xe, 0x1, 0xc0, 0x38, 0x1f, 0xc1, 0xf0, 0x1c, - 0x3d, 0x7f, 0xfd, 0xff, 0xe0, + 0xe, 0x0, 0xe0, 0xe, 0x0, 0xe0, 0x3f, 0xc3, + 0xf8, 0x1f, 0x0, 0xe0, 0xf5, 0xff, 0xff, 0xff, + 0x5f, 0xff, /* U+F01C "" */ - 0x3f, 0x8c, 0x19, 0x1, 0x60, 0x3f, 0x1f, 0xff, - 0xff, 0xf8, + 0x1f, 0xe0, 0xc0, 0xc6, 0x1, 0x90, 0x2, 0xf8, + 0x7f, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, /* U+F021 "" */ - 0x0, 0x47, 0xd6, 0x1d, 0xf, 0x0, 0x0, 0xf, - 0xb, 0x6, 0xe3, 0x27, 0x80, + 0x0, 0x31, 0xf3, 0x71, 0xfc, 0x7, 0xc3, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0xfc, 0x3e, 0x3, 0xf8, + 0xec, 0xf8, 0xc0, 0x0, /* U+F026 "" */ - 0x8, 0xff, 0xff, 0xfc, 0x61, + 0xc, 0x7f, 0xff, 0xff, 0xf1, 0xc3, /* U+F027 "" */ - 0x8, 0x18, 0xf8, 0xf9, 0xf9, 0xfa, 0x18, 0x8, + 0xc, 0xe, 0x3f, 0x7f, 0x9f, 0xdf, 0xe0, 0x70, + 0x18, /* U+F028 "" */ - 0x8, 0x83, 0x2b, 0xe2, 0xfc, 0xdf, 0x9b, 0xf5, - 0x46, 0x70, 0x42, 0x0, 0x80, + 0x0, 0x60, 0x1, 0x83, 0x34, 0x38, 0xdf, 0xda, + 0xfe, 0x57, 0xf6, 0xbf, 0x8d, 0x1c, 0xd0, 0x61, + 0x80, 0x18, /* U+F03E "" */ - 0xff, 0xe7, 0xf9, 0xef, 0xf1, 0xc8, 0x60, 0x1f, - 0xfc, + 0xff, 0xf9, 0xff, 0x9f, 0xf9, 0xef, 0xfc, 0x7d, + 0x83, 0xc0, 0x38, 0x3, 0xff, 0xf0, /* U+F048 "" */ - 0x86, 0x7b, 0xff, 0xff, 0xfb, 0xe7, 0x84, + 0xc3, 0xc7, 0xcf, 0xdf, 0xff, 0xff, 0xdf, 0xcf, + 0xc7, 0xc3, /* U+F04B "" */ - 0xc0, 0x70, 0x3e, 0x1f, 0xcf, 0xff, 0xff, 0xfd, - 0xf8, 0xf0, 0x70, 0x0, + 0x0, 0x1c, 0x3, 0xe0, 0x7f, 0xf, 0xf9, 0xff, + 0xbf, 0xff, 0xfe, 0xff, 0x9f, 0xc3, 0xe0, 0x70, + 0x0, 0x0, /* U+F04C "" */ - 0xf7, 0xfb, 0xfd, 0xfe, 0xff, 0x7f, 0xbf, 0xdf, - 0xef, 0xf7, 0x80, + 0xfb, 0xff, 0x7f, 0xef, 0xfd, 0xff, 0xbf, 0xf7, + 0xfe, 0xff, 0xdf, 0xfb, 0xff, 0x7c, /* U+F04D "" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, /* U+F051 "" */ - 0x87, 0x9f, 0x7f, 0xff, 0xff, 0x79, 0x84, + 0xc3, 0xe3, 0xf3, 0xfb, 0xff, 0xff, 0xfb, 0xf3, + 0xe3, 0xc3, /* U+F052 "" */ - 0x18, 0x1e, 0x1f, 0x8f, 0xef, 0xf8, 0x3, 0xff, - 0xff, + 0xc, 0x3, 0xc0, 0x7c, 0x1f, 0xc7, 0xfd, 0xff, + 0xbf, 0xf0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x80, /* U+F053 "" */ - 0x19, 0x99, 0x8c, 0x30, 0xc3, + 0xc, 0x73, 0x9c, 0xe3, 0x87, 0xe, 0x1c, 0x30, /* U+F054 "" */ - 0x86, 0x18, 0x63, 0xb3, 0x10, + 0x83, 0x87, 0xe, 0x1c, 0x73, 0x9c, 0xe2, 0x0, /* U+F067 "" */ - 0x8, 0x4, 0x2, 0x1, 0xf, 0xf8, 0x40, 0x20, - 0x10, 0x8, 0x0, + 0xe, 0x1, 0xc0, 0x38, 0x7, 0xf, 0xff, 0xff, + 0xc3, 0x80, 0x70, 0xe, 0x1, 0xc0, /* U+F068 "" */ - 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, /* U+F06E "" */ - 0x1f, 0x6, 0x31, 0x9b, 0x73, 0x7e, 0xee, 0xdd, - 0x8c, 0x60, 0xf8, + 0xf, 0x81, 0xc7, 0x1c, 0x1d, 0xc6, 0x7e, 0xfb, + 0xf7, 0xdd, 0xdd, 0xc7, 0x1c, 0xf, 0x80, /* U+F070 "" */ - 0xc0, 0x1, 0xdf, 0x1, 0xc6, 0x3, 0x4c, 0x67, - 0xb9, 0xc6, 0xe3, 0xf, 0x6, 0x18, 0xf, 0x38, - 0x0, 0x30, + 0x0, 0x1, 0xc0, 0x1, 0xdf, 0x0, 0xe3, 0x80, + 0xdb, 0x84, 0xfb, 0x9c, 0x77, 0x3c, 0x6e, 0x38, + 0x78, 0x38, 0x70, 0x1e, 0x30, 0x0, 0x30, 0x0, + 0x0, /* U+F071 "" */ - 0x4, 0x1, 0xc0, 0x3c, 0xd, 0x83, 0xb8, 0x77, - 0x1f, 0xf3, 0xdf, 0xfb, 0xff, 0xfc, + 0x3, 0x0, 0x1c, 0x0, 0xf8, 0x3, 0xf0, 0x1c, + 0xc0, 0x73, 0x83, 0xcf, 0x1f, 0xfc, 0x7c, 0xfb, + 0xf3, 0xef, 0xff, 0x80, /* U+F074 "" */ - 0x1, 0xb8, 0xf3, 0x58, 0x30, 0x18, 0xd, 0xee, - 0x3c, 0x6, + 0x0, 0x0, 0x6, 0xe1, 0xff, 0x3f, 0x17, 0x60, + 0xe4, 0x1f, 0x6f, 0xbf, 0xf1, 0xf0, 0x6, 0x0, + 0x40, /* U+F077 "" */ - 0x1c, 0x1f, 0x1d, 0xdc, 0x7c, 0x18, + 0x0, 0x3, 0x1, 0xe0, 0xcc, 0x61, 0xb0, 0x30, + 0x0, /* U+F078 "" */ - 0xc1, 0xb1, 0x8d, 0x83, 0x80, 0x80, + 0x0, 0x30, 0x36, 0x18, 0xcc, 0x1e, 0x3, 0x0, + 0x0, /* U+F079 "" */ - 0x20, 0x3, 0x9f, 0x3e, 0x8, 0x40, 0x42, 0x2, - 0x10, 0x7c, 0xf9, 0xc0, 0x4, + 0x30, 0x0, 0xf7, 0xf3, 0xf0, 0x65, 0xa0, 0xc3, + 0x1, 0x86, 0xb, 0x4c, 0x1f, 0x9f, 0xde, 0x0, + 0x18, /* U+F07B "" */ - 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, + 0x78, 0xf, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, /* U+F093 "" */ - 0xc, 0x7, 0x83, 0xf0, 0xfc, 0xc, 0x3, 0xe, - 0xdf, 0xfd, 0xff, 0xc0, + 0x6, 0x0, 0xf0, 0x1f, 0x83, 0xfc, 0x7, 0x0, + 0x70, 0x7, 0x0, 0x70, 0xf7, 0xff, 0xff, 0xff, + 0x5f, 0xff, /* U+F095 "" */ - 0x1, 0x80, 0x70, 0x3c, 0x7, 0x1, 0x80, 0x62, - 0x33, 0xf8, 0xfc, 0x3e, 0x0, + 0x0, 0x0, 0xf, 0x0, 0xf0, 0x1f, 0x0, 0xf0, + 0x6, 0x0, 0xe0, 0x1c, 0x73, 0xcf, 0xf8, 0xfe, + 0xf, 0xc0, 0x40, 0x0, /* U+F0C4 "" */ - 0x0, 0x79, 0xe5, 0xcf, 0xc1, 0xc3, 0xe3, 0xd9, - 0x26, 0x61, 0x0, + 0x70, 0x5b, 0x3f, 0x6f, 0x3f, 0xc1, 0xf0, 0x3e, + 0x1f, 0xe6, 0xde, 0xd9, 0xee, 0x8, /* U+F0C5 "" */ - 0x1d, 0xe, 0xf7, 0x1b, 0xfd, 0xfe, 0xff, 0x7f, - 0xbf, 0xc0, 0x7e, 0x0, + 0x1f, 0x43, 0xef, 0x7f, 0xef, 0xfd, 0xff, 0xbf, + 0xf7, 0xfe, 0xff, 0xdf, 0xf8, 0x3, 0xfc, 0x0, /* U+F0C7 "" */ - 0xfe, 0x41, 0xa0, 0xf0, 0x7f, 0xff, 0x3f, 0x9f, - 0xff, + 0xff, 0x98, 0x1b, 0x3, 0xe0, 0x7c, 0xf, 0xff, + 0xfe, 0x7f, 0x8f, 0xf9, 0xff, 0xfc, + + /* U+F0D7 "" */ + 0xfe, 0xf8, 0xe0, 0x80, /* U+F0E7 "" */ - 0x73, 0xcf, 0x3f, 0xfc, 0x63, 0xc, 0x20, + 0x78, 0x78, 0xf8, 0xf0, 0xff, 0xfe, 0xfc, 0x1c, + 0x18, 0x18, 0x10, 0x30, /* U+F0EA "" */ - 0x10, 0x76, 0x3f, 0x1c, 0xe, 0xd7, 0x67, 0xbf, - 0xdf, 0xf, 0x87, 0xc0, + 0x18, 0x3b, 0x8e, 0xe3, 0xf8, 0xe0, 0x3b, 0xae, + 0xe7, 0xbf, 0xef, 0xfb, 0xf0, 0xfc, 0x3f, /* U+F0F3 "" */ - 0x8, 0xe, 0xf, 0x8f, 0xe7, 0xf3, 0xf9, 0xfd, - 0xff, 0x0, 0xe, 0x0, + 0x4, 0x0, 0x80, 0x7c, 0x1f, 0xc3, 0xf8, 0x7f, + 0x1f, 0xf3, 0xfe, 0x7f, 0xdf, 0xfc, 0x0, 0x7, + 0x0, + + /* U+F104 "" */ + 0x17, 0xec, 0xe7, 0x10, /* U+F11C "" */ - 0xff, 0xf5, 0x57, 0xff, 0xea, 0xbf, 0xff, 0x41, - 0x7f, 0xf8, + 0xff, 0xff, 0x52, 0xbd, 0x4a, 0xff, 0xff, 0xeb, + 0x5f, 0xff, 0xfd, 0x2, 0xf4, 0xb, 0xff, 0xfc, /* U+F124 "" */ - 0x0, 0xc0, 0xf0, 0xf8, 0xfe, 0xff, 0xbf, 0xc0, - 0xf0, 0x38, 0xe, 0x3, 0x0, + 0x0, 0x0, 0xf, 0x3, 0xf0, 0xfe, 0x3f, 0xef, + 0xfc, 0xff, 0xc0, 0x78, 0x7, 0x80, 0x78, 0x7, + 0x0, 0x70, 0x2, 0x0, /* U+F15B "" */ - 0xf4, 0xf6, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, + 0xfa, 0x7d, 0xbe, 0xff, 0xf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, /* U+F1EB "" */ - 0x1f, 0xc3, 0xef, 0xb8, 0xe, 0x3f, 0x3, 0xc, - 0x0, 0x0, 0x18, 0x0, 0xc0, + 0x7, 0xc0, 0x7f, 0xf1, 0xe0, 0xf7, 0x0, 0x70, + 0x7c, 0x3, 0xfe, 0x6, 0xc, 0x0, 0x0, 0x3, + 0x80, 0x7, 0x0, 0xe, 0x0, /* U+F240 "" */ - 0xff, 0xe8, 0x3, 0xbf, 0xdb, 0xfd, 0x80, 0x3f, - 0xff, + 0xff, 0xff, 0x80, 0x1f, 0x7f, 0xfe, 0xff, 0xbd, + 0xff, 0xf8, 0x1, 0xff, 0xff, 0x80, /* U+F241 "" */ - 0xff, 0xe8, 0x3, 0xbf, 0x1b, 0xf1, 0x80, 0x3f, - 0xff, + 0xff, 0xff, 0x80, 0x1f, 0x7f, 0x3e, 0xfe, 0x3d, + 0xfc, 0xf8, 0x1, 0xff, 0xff, 0x80, /* U+F242 "" */ - 0xff, 0xe8, 0x3, 0xbc, 0x1b, 0xc1, 0x80, 0x3f, - 0xff, + 0xff, 0xff, 0x80, 0x1f, 0x78, 0x3e, 0xf0, 0x3d, + 0xe0, 0xf8, 0x1, 0xff, 0xff, 0x80, /* U+F243 "" */ - 0xff, 0xe8, 0x3, 0xb0, 0x1b, 0x1, 0x80, 0x3f, - 0xff, + 0xff, 0xff, 0x80, 0x1f, 0x60, 0x3e, 0xc0, 0x3d, + 0x80, 0xf8, 0x1, 0xff, 0xff, 0x80, /* U+F244 "" */ - 0xff, 0xf8, 0x3, 0x80, 0x18, 0x1, 0x80, 0x3f, - 0xff, + 0xff, 0xff, 0x80, 0x1f, 0x0, 0x3e, 0x0, 0x3c, + 0x0, 0xf8, 0x1, 0xff, 0xff, 0x80, /* U+F287 "" */ - 0x1, 0x0, 0x3c, 0x2, 0x1, 0xd0, 0x2f, 0xff, - 0xf2, 0x8, 0xb, 0x0, 0x38, + 0x0, 0xc0, 0x7, 0x80, 0x10, 0x7, 0x20, 0x6f, + 0xff, 0xfc, 0x41, 0x80, 0x40, 0x0, 0xb8, 0x0, + 0xf0, /* U+F293 "" */ - 0x3c, 0x76, 0xf3, 0xdb, 0xe7, 0xe7, 0xdb, 0xf3, - 0x76, 0x3c, + 0x3e, 0x3b, 0x9c, 0xdb, 0x7c, 0xbf, 0x1f, 0x9f, + 0x87, 0xd5, 0xf9, 0x9d, 0xc7, 0xc0, /* U+F2ED "" */ - 0x1c, 0x7f, 0xc0, 0xf, 0xe5, 0x52, 0xa9, 0x54, - 0xaa, 0x55, 0x3f, 0x80, + 0xe, 0x1f, 0xfc, 0x0, 0x0, 0x7, 0xfc, 0xd5, + 0x9a, 0xb3, 0x56, 0x6a, 0xcd, 0x59, 0xab, 0x3f, + 0xe0, /* U+F304 "" */ - 0x1, 0x80, 0xf0, 0x5c, 0x3a, 0x1f, 0xf, 0x87, - 0xc3, 0xe0, 0xf0, 0x38, 0x0, + 0x0, 0x40, 0xe, 0x0, 0xf0, 0x37, 0x7, 0xa0, + 0xfc, 0x1f, 0x83, 0xf0, 0x7e, 0xf, 0xc0, 0xf8, + 0xf, 0x0, 0x80, 0x0, /* U+F55A "" */ - 0x1f, 0xf9, 0xed, 0xdf, 0xf, 0xfc, 0xf7, 0xc3, - 0x9e, 0xdc, 0x7f, 0xe0, + 0xf, 0xfe, 0x3f, 0xfc, 0xfb, 0x3b, 0xf0, 0xff, + 0xf3, 0xef, 0xc3, 0xcf, 0xb7, 0x8f, 0xff, 0xf, + 0xfe, /* U+F7C2 "" */ - 0x3e, 0xb7, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, + 0x1f, 0x9a, 0xbe, 0xaf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, /* U+F8A2 "" */ - 0x0, 0x48, 0x36, 0xf, 0xff, 0x60, 0x8, 0x0 + 0x0, 0x0, 0x3, 0x30, 0x37, 0x3, 0xff, 0xff, + 0xff, 0x70, 0x3, 0x0 }; @@ -247,63 +282,65 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, - {.bitmap_index = 0, .adv_w = 160, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 13, .adv_w = 160, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 22, .adv_w = 160, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 32, .adv_w = 160, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 41, .adv_w = 110, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 48, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 60, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 72, .adv_w = 180, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 85, .adv_w = 160, .box_w = 11, .box_h = 9, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 98, .adv_w = 180, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 108, .adv_w = 160, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 121, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 126, .adv_w = 120, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 134, .adv_w = 180, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 147, .adv_w = 160, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 156, .adv_w = 140, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 163, .adv_w = 140, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 175, .adv_w = 140, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 186, .adv_w = 140, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 197, .adv_w = 140, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 204, .adv_w = 140, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 213, .adv_w = 100, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 218, .adv_w = 100, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 223, .adv_w = 140, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 234, .adv_w = 140, .box_w = 9, .box_h = 2, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 237, .adv_w = 180, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 248, .adv_w = 200, .box_w = 14, .box_h = 10, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 266, .adv_w = 180, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 280, .adv_w = 160, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 290, .adv_w = 140, .box_w = 9, .box_h = 5, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 296, .adv_w = 140, .box_w = 9, .box_h = 5, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 302, .adv_w = 200, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 315, .adv_w = 160, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 324, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 336, .adv_w = 160, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 349, .adv_w = 140, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 360, .adv_w = 140, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 372, .adv_w = 140, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 381, .adv_w = 100, .box_w = 6, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 388, .adv_w = 140, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 400, .adv_w = 140, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 412, .adv_w = 180, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 422, .adv_w = 160, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 435, .adv_w = 120, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 445, .adv_w = 200, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 458, .adv_w = 200, .box_w = 12, .box_h = 6, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 467, .adv_w = 200, .box_w = 12, .box_h = 6, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 476, .adv_w = 200, .box_w = 12, .box_h = 6, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 485, .adv_w = 200, .box_w = 12, .box_h = 6, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 494, .adv_w = 200, .box_w = 12, .box_h = 6, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 503, .adv_w = 200, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 516, .adv_w = 140, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 526, .adv_w = 140, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 538, .adv_w = 160, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 551, .adv_w = 200, .box_w = 13, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 563, .adv_w = 120, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 572, .adv_w = 161, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 1} + {.bitmap_index = 0, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 32, .adv_w = 192, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 64, .adv_w = 132, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 72, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90, .adv_w = 192, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107, .adv_w = 216, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 125, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143, .adv_w = 216, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 159, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 179, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 185, .adv_w = 144, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 194, .adv_w = 216, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 212, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 226, .adv_w = 168, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 236, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 254, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 268, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 282, .adv_w = 168, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 292, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 308, .adv_w = 120, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 316, .adv_w = 120, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 324, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 338, .adv_w = 168, .box_w = 11, .box_h = 2, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 341, .adv_w = 216, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 356, .adv_w = 240, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 381, .adv_w = 216, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 401, .adv_w = 192, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 418, .adv_w = 168, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 427, .adv_w = 168, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 436, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 453, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 467, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 485, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 505, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 519, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 535, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 549, .adv_w = 120, .box_w = 7, .box_h = 4, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 553, .adv_w = 120, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 565, .adv_w = 168, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 580, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 597, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 601, .adv_w = 216, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 617, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 637, .adv_w = 144, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 651, .adv_w = 240, .box_w = 15, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 672, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 686, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 700, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 714, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 728, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 742, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 759, .adv_w = 168, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 773, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 790, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 810, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 827, .adv_w = 144, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 841, .adv_w = 193, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 1} }; /*--------------------- @@ -315,10 +352,10 @@ static const uint16_t unicode_list_0[] = { 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d, 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52, 0x53, 0x66, 0x67, 0x6d, 0x6f, 0x70, 0x73, 0x76, 0x77, 0x78, - 0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xe6, 0xe9, - 0xf2, 0x11b, 0x123, 0x15a, 0x1ea, 0x23f, 0x240, 0x241, - 0x242, 0x243, 0x286, 0x292, 0x2ec, 0x303, 0x559, 0x7c1, - 0x8a1 + 0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xd6, 0xe6, + 0xe9, 0xf2, 0x103, 0x11b, 0x123, 0x15a, 0x1ea, 0x23f, + 0x240, 0x241, 0x242, 0x243, 0x286, 0x292, 0x2ec, 0x303, + 0x559, 0x7c1, 0x8a1 }; /*Collect the unicode lists and glyph_id offsets*/ @@ -326,7 +363,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = { { .range_start = 61441, .range_length = 2210, .glyph_id_start = 1, - .unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 57, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 59, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -370,14 +407,14 @@ lv_font_t font_symbols = { #endif .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ - .line_height = 10, /*The maximum line height required by the font*/ - .base_line = 1, /*Baseline measured from the bottom of the line*/ + .line_height = 13, /*The maximum line height required by the font*/ + .base_line = 2, /*Baseline measured from the bottom of the line*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, #endif #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 .underline_position = -4, - .underline_thickness = 0, + .underline_thickness = 1, #endif .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ }; diff --git a/src/ui/include/font_symbols.hpp b/src/ui/include/font_symbols.hpp new file mode 100644 index 00000000..08bb4f6e --- /dev/null +++ b/src/ui/include/font_symbols.hpp @@ -0,0 +1,11 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include "font/lv_font.h" + +LV_FONT_DECLARE(font_symbols); diff --git a/src/ui/include/screen.hpp b/src/ui/include/screen.hpp index c6b2f137..0ec72a63 100644 --- a/src/ui/include/screen.hpp +++ b/src/ui/include/screen.hpp @@ -12,6 +12,7 @@ #include "core/lv_obj.h" #include "core/lv_obj_tree.h" #include "lvgl.h" +#include "widget_top_bar.hpp" namespace ui { @@ -37,12 +38,20 @@ class Screen { */ virtual auto Tick() -> void {} + auto UpdateTopBar(const widgets::TopBar::State& state) -> void; + auto root() -> lv_obj_t* { return root_; } auto group() -> lv_group_t* { return group_; } protected: + auto CreateTopBar(lv_obj_t* parent, const widgets::TopBar::Configuration&) + -> widgets::TopBar*; + lv_obj_t* const root_; lv_group_t* const group_; + + private: + std::unique_ptr top_bar_; }; } // namespace ui diff --git a/src/ui/include/screen_playing.hpp b/src/ui/include/screen_playing.hpp index 0e15a85b..c684ddff 100644 --- a/src/ui/include/screen_playing.hpp +++ b/src/ui/include/screen_playing.hpp @@ -71,6 +71,7 @@ class Playing : public Screen { lv_obj_t* next_up_header_; lv_obj_t* next_up_label_; + lv_obj_t* next_up_hint_; lv_obj_t* next_up_container_; }; diff --git a/src/ui/include/widget_top_bar.hpp b/src/ui/include/widget_top_bar.hpp index 9019807f..adb889fc 100644 --- a/src/ui/include/widget_top_bar.hpp +++ b/src/ui/include/widget_top_bar.hpp @@ -6,6 +6,7 @@ #pragma once +#include #include #include "lvgl.h" @@ -16,13 +17,37 @@ namespace widgets { class TopBar { public: - TopBar(lv_obj_t* parent, lv_group_t* group); + struct Configuration { + bool show_back_button; + std::string title; + }; - auto set_title(const std::string&) -> void; + enum class PlaybackState { + kIdle, + kPaused, + kPlaying, + }; + struct State { + PlaybackState playback_state; + uint_fast8_t battery_percent; + bool is_charging; + }; + + explicit TopBar(lv_obj_t* parent, const Configuration& config); + + auto root() -> lv_obj_t* { return container_; } + auto button() -> lv_obj_t* { return back_button_; } + + auto Update(const State&) -> void; + + private: lv_obj_t* container_; - lv_obj_t* title_; + lv_obj_t* back_button_; + lv_obj_t* title_; + lv_obj_t* playback_; + lv_obj_t* battery_; }; } // namespace widgets diff --git a/src/ui/screen.cpp b/src/ui/screen.cpp new file mode 100644 index 00000000..7ea5e3ce --- /dev/null +++ b/src/ui/screen.cpp @@ -0,0 +1,32 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "screen.hpp" + +#include + +#include "widget_top_bar.hpp" + +namespace ui { + +auto Screen::UpdateTopBar(const widgets::TopBar::State& state) -> void { + if (top_bar_) { + top_bar_->Update(state); + } +} + +auto Screen::CreateTopBar(lv_obj_t* parent, + const widgets::TopBar::Configuration& config) + -> widgets::TopBar* { + assert(top_bar_ == nullptr); + top_bar_ = std::make_unique(parent, config); + if (top_bar_->button()) { + lv_group_add_obj(group_, top_bar_->button()); + } + return top_bar_.get(); +} + +} // namespace ui diff --git a/src/ui/screen_menu.cpp b/src/ui/screen_menu.cpp index 743dc6fa..37254f92 100644 --- a/src/ui/screen_menu.cpp +++ b/src/ui/screen_menu.cpp @@ -20,6 +20,7 @@ #include "misc/lv_area.h" #include "ui_events.hpp" #include "ui_fsm.hpp" +#include "widget_top_bar.hpp" #include "widgets/lv_label.h" namespace ui { @@ -37,6 +38,17 @@ static void item_click_cb(lv_event_t* ev) { } Menu::Menu(std::vector indexes) : indexes_(indexes) { + lv_obj_set_layout(root_, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(root_, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(root_, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + + widgets::TopBar::Configuration config{ + .show_back_button = false, + .title = "", + }; + CreateTopBar(root_, config); + lv_obj_t* list = lv_list_create(root_); lv_obj_set_size(list, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL)); lv_obj_center(list); diff --git a/src/ui/screen_playing.cpp b/src/ui/screen_playing.cpp index 85200c4d..27f7654b 100644 --- a/src/ui/screen_playing.cpp +++ b/src/ui/screen_playing.cpp @@ -16,8 +16,8 @@ #include "esp_log.h" #include "extra/layouts/flex/lv_flex.h" #include "extra/layouts/grid/lv_grid.h" -#include "font/lv_font.h" #include "font/lv_symbol_def.h" +#include "font_symbols.hpp" #include "future_fetcher.hpp" #include "lvgl.h" @@ -42,8 +42,6 @@ #include "widgets/lv_img.h" #include "widgets/lv_label.h" -LV_FONT_DECLARE(font_symbols); - namespace ui { namespace screens { @@ -70,6 +68,7 @@ static lv_style_t scrubber_style; auto info_label(lv_obj_t* parent) -> lv_obj_t* { lv_obj_t* label = lv_label_create(parent); lv_obj_set_size(label, lv_pct(100), LV_SIZE_CONTENT); + lv_label_set_text(label, ""); lv_label_set_long_mode(label, LV_LABEL_LONG_DOT); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); lv_obj_center(label); @@ -124,8 +123,11 @@ Playing::Playing(std::weak_ptr db, audio::TrackQueue* queue) lv_obj_set_flex_align(above_fold_container, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); - widgets::TopBar top_bar(above_fold_container, group_); - top_bar.set_title("Now Playing"); + widgets::TopBar::Configuration config{ + .show_back_button = true, + .title = "Now Playing", + }; + CreateTopBar(above_fold_container, config); lv_obj_t* info_container = lv_obj_create(above_fold_container); lv_obj_set_layout(info_container, LV_LAYOUT_FLEX); @@ -171,13 +173,14 @@ Playing::Playing(std::weak_ptr db, audio::TrackQueue* queue) LV_FLEX_ALIGN_END); next_up_label_ = lv_label_create(next_up_header_); - lv_label_set_text(next_up_label_, "Next up..."); + lv_label_set_text(next_up_label_, ""); lv_obj_set_height(next_up_label_, lv_pct(100)); lv_obj_set_flex_grow(next_up_label_, 1); - lv_obj_t* next_up_hint = lv_label_create(next_up_header_); - lv_label_set_text(next_up_hint, LV_SYMBOL_DOWN); - lv_obj_set_size(next_up_hint, LV_SIZE_CONTENT, lv_pct(100)); + next_up_hint_ = lv_label_create(next_up_header_); + lv_label_set_text(next_up_hint_, ""); + lv_obj_set_style_text_font(next_up_hint_, &font_symbols, 0); + lv_obj_set_size(next_up_hint_, LV_SIZE_CONTENT, lv_pct(100)); next_up_container_ = lv_list_create(root_); lv_obj_set_layout(next_up_container_, LV_LAYOUT_FLEX); @@ -277,9 +280,11 @@ auto Playing::ApplyNextUp(const std::vector& tracks) -> void { if (next_tracks_.empty()) { lv_label_set_text(next_up_label_, "Nothing queued"); + lv_label_set_text(next_up_hint_, ""); return; } else { lv_label_set_text(next_up_label_, "Next up"); + lv_label_set_text(next_up_hint_, ""); } for (const auto& track : next_tracks_) { diff --git a/src/ui/screen_track_browser.cpp b/src/ui/screen_track_browser.cpp index 86140558..a9333be4 100644 --- a/src/ui/screen_track_browser.cpp +++ b/src/ui/screen_track_browser.cpp @@ -79,9 +79,12 @@ TrackBrowser::TrackBrowser( // Wrapping behaves in surprising ways, again due to progressing loading. lv_group_set_wrap(group_, false); - widgets::TopBar top_bar(root_, group_); - top_bar.set_title(title); - back_button_ = top_bar.back_button_; + widgets::TopBar::Configuration config{ + .show_back_button = true, + .title = title, + }; + auto top_bar = CreateTopBar(root_, config); + back_button_ = top_bar->button(); list_ = lv_list_create(root_); lv_obj_set_width(list_, lv_pct(100)); diff --git a/src/ui/widget_top_bar.cpp b/src/ui/widget_top_bar.cpp index 62c05a25..9f192c84 100644 --- a/src/ui/widget_top_bar.cpp +++ b/src/ui/widget_top_bar.cpp @@ -9,9 +9,12 @@ #include "core/lv_obj.h" #include "event_queue.hpp" #include "extra/layouts/flex/lv_flex.h" +#include "font/lv_symbol_def.h" +#include "font_symbols.hpp" #include "ui_events.hpp" #include "ui_fsm.hpp" #include "widgets/lv_img.h" +#include "widgets/lv_label.h" namespace ui { namespace widgets { @@ -20,34 +23,59 @@ static void back_click_cb(lv_event_t* ev) { events::Dispatch({}); } -TopBar::TopBar(lv_obj_t* parent, lv_group_t* group) { +TopBar::TopBar(lv_obj_t* parent, const Configuration& config) { container_ = lv_obj_create(parent); lv_obj_set_size(container_, lv_pct(100), 14); lv_obj_set_flex_flow(container_, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(container_, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END); - back_button_ = lv_btn_create(container_); - lv_obj_set_size(back_button_, LV_SIZE_CONTENT, LV_SIZE_CONTENT); - lv_obj_t* button_icon = lv_label_create(back_button_); - lv_label_set_text(button_icon, "<"); - - lv_group_add_obj(group, back_button_); - lv_obj_add_event_cb(back_button_, back_click_cb, LV_EVENT_CLICKED, NULL); + if (config.show_back_button) { + back_button_ = lv_btn_create(container_); + lv_obj_set_size(back_button_, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_t* button_icon = lv_label_create(back_button_); + lv_label_set_text(button_icon, ""); + lv_obj_set_style_text_font(button_icon, &font_symbols, 0); + lv_obj_add_event_cb(back_button_, back_click_cb, LV_EVENT_CLICKED, NULL); + } else { + back_button_ = nullptr; + } title_ = lv_label_create(container_); - lv_label_set_text(title_, ""); + lv_label_set_text(title_, config.title.c_str()); lv_obj_set_flex_grow(title_, 1); - lv_obj_t* playback_label = lv_label_create(container_); - lv_label_set_text(playback_label, LV_SYMBOL_PAUSE); + playback_ = lv_label_create(container_); + lv_label_set_text(playback_, ""); - lv_obj_t* battery_label = lv_label_create(container_); - lv_label_set_text(battery_label, LV_SYMBOL_BATTERY_2); + battery_ = lv_label_create(container_); + lv_label_set_text(battery_, ""); } -auto TopBar::set_title(const std::string& new_title) -> void { - lv_label_set_text(title_, new_title.c_str()); +auto TopBar::Update(const State& state) -> void { + switch (state.playback_state) { + case PlaybackState::kIdle: + lv_label_set_text(playback_, ""); + break; + case PlaybackState::kPaused: + lv_label_set_text(playback_, ""); + break; + case PlaybackState::kPlaying: + lv_label_set_text(playback_, ""); + break; + } + + if (state.battery_percent >= 95) { + lv_label_set_text(battery_, ""); + } else if (state.battery_percent >= 70) { + lv_label_set_text(battery_, ""); + } else if (state.battery_percent >= 40) { + lv_label_set_text(battery_, ""); + } else if (state.battery_percent >= 10) { + lv_label_set_text(battery_, ""); + } else { + lv_label_set_text(battery_, ""); + } } } // namespace widgets diff --git a/tools/mkfonts.sh b/tools/mkfonts.sh index d2d9414e..7888512a 100755 --- a/tools/mkfonts.sh +++ b/tools/mkfonts.sh @@ -11,11 +11,13 @@ lv_font_conv \ lv_font_conv \ --font fonts/font-awesome/FontAwesome5-Solid+Brands+Regular.woff \ + -r 0xf244,0xf243,0xf242,0xf241,0xf240 `# battery indicators, empty->full` \ + -r 0xf104,0xf0d7 \ -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465 \ -r 61468,61473,61478,61479,61480,61502,61512,61515,61516,61517 \ -r 61521,61522,61523,61524,61543,61544,61550,61552,61553,61556 \ -r 61559,61560,61561,61563,61587,61589,61636,61637,61639,61671 \ -r 61674,61683,61724,61732,61787,61931,62016,62017,62018,62019 \ -r 62020,62087,62099,62212,62189,62810,63426,63650 \ - --size 10 \ + --size 12 \ --bpp 1 --format lvgl -o font_symbols.c