First pass at having some kind of design and theming

custom
jacqueline 2 years ago
parent bf1fc5a2a0
commit 6c20eafd05
  1. 4
      src/ui/include/modal_add_to_queue.hpp
  2. 11
      src/ui/include/themes.hpp
  3. 3
      src/ui/modal.cpp
  4. 125
      src/ui/modal_add_to_queue.cpp
  5. 2
      src/ui/screen.cpp
  6. 1
      src/ui/screen_menu.cpp
  7. 29
      src/ui/screen_playing.cpp
  8. 69
      src/ui/screen_settings.cpp
  9. 131
      src/ui/themes.cpp
  10. 5
      src/ui/widget_top_bar.cpp

@ -30,6 +30,10 @@ class AddToQueue : public Modal {
audio::TrackQueue& queue_;
std::shared_ptr<playlist::IndexRecordSource> item_;
lv_obj_t* container_;
lv_obj_t* selected_track_btn_;
lv_obj_t* all_tracks_btn_;
bool all_tracks_;
};
} // namespace modals

@ -5,7 +5,16 @@
namespace ui {
namespace themes {
enum class Style { kMenuItem, kTopBar };
enum class Style {
kMenuItem,
kMenuSubheadFirst,
kMenuSubhead,
kTopBar,
kPopup,
kTab,
kButtonPrimary,
};
class Theme {
public:
void Apply(void);

@ -21,6 +21,7 @@
#include "index.hpp"
#include "misc/lv_area.h"
#include "screen.hpp"
#include "themes.hpp"
#include "ui_events.hpp"
#include "ui_fsm.hpp"
#include "widget_top_bar.hpp"
@ -40,6 +41,8 @@ Modal::Modal(Screen* host)
lv_obj_set_style_bg_opa(root_, LV_OPA_COVER, 0);
lv_obj_set_style_bg_color(root_, lv_color_white(), 0);
themes::Theme::instance()->ApplyStyle(root_, themes::Style::kPopup);
host_->modal_group(group_);
}

@ -14,13 +14,17 @@
#include "core/lv_group.h"
#include "core/lv_obj_pos.h"
#include "event_queue.hpp"
#include "extra/layouts/flex/lv_flex.h"
#include "extra/widgets/list/lv_list.h"
#include "extra/widgets/menu/lv_menu.h"
#include "extra/widgets/spinner/lv_spinner.h"
#include "extra/widgets/tabview/lv_tabview.h"
#include "hal/lv_hal_disp.h"
#include "index.hpp"
#include "misc/lv_area.h"
#include "misc/lv_color.h"
#include "source.hpp"
#include "themes.hpp"
#include "track_queue.hpp"
#include "ui_events.hpp"
#include "ui_fsm.hpp"
@ -34,15 +38,12 @@ namespace modals {
AddToQueue::AddToQueue(Screen* host,
audio::TrackQueue& queue,
std::shared_ptr<playlist::IndexRecordSource> item)
: Modal(host), queue_(queue), item_(item) {
: Modal(host), queue_(queue), item_(item), all_tracks_(0) {
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_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER,
lv_obj_set_flex_align(root_, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START,
LV_FLEX_ALIGN_CENTER);
lv_obj_t* label = lv_label_create(root_);
lv_label_set_text(label, "This track");
lv_obj_t* button_container = lv_obj_create(root_);
lv_obj_set_size(button_container, lv_pct(100), LV_SIZE_CONTENT);
lv_obj_set_layout(button_container, LV_LAYOUT_FLEX);
@ -50,16 +51,56 @@ AddToQueue::AddToQueue(Screen* host,
lv_obj_set_flex_align(button_container, LV_FLEX_ALIGN_SPACE_EVENLY,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
selected_track_btn_ = lv_btn_create(button_container);
lv_obj_t* label = lv_label_create(selected_track_btn_);
lv_label_set_text(label, "Selected");
lv_group_add_obj(group_, selected_track_btn_);
lv_obj_add_state(selected_track_btn_, LV_STATE_CHECKED);
themes::Theme::instance()->ApplyStyle(selected_track_btn_,
themes::Style::kTab);
lv_bind(selected_track_btn_, LV_EVENT_CLICKED, [this](lv_obj_t*) {
lv_obj_add_state(selected_track_btn_, LV_STATE_CHECKED);
lv_obj_clear_state(all_tracks_btn_, LV_STATE_CHECKED);
all_tracks_ = false;
});
all_tracks_btn_ = lv_btn_create(button_container);
label = lv_label_create(all_tracks_btn_);
lv_label_set_text(label, "All tracks");
lv_group_add_obj(group_, all_tracks_btn_);
themes::Theme::instance()->ApplyStyle(all_tracks_btn_, themes::Style::kTab);
lv_bind(all_tracks_btn_, LV_EVENT_CLICKED, [this](lv_obj_t*) {
lv_obj_clear_state(selected_track_btn_, LV_STATE_CHECKED);
lv_obj_add_state(all_tracks_btn_, LV_STATE_CHECKED);
all_tracks_ = true;
});
lv_obj_t* spacer = lv_obj_create(root_);
lv_obj_set_size(spacer, 1, 4);
button_container = lv_obj_create(root_);
lv_obj_set_size(button_container, lv_pct(100), LV_SIZE_CONTENT);
lv_obj_set_layout(button_container, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(button_container, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(button_container, LV_FLEX_ALIGN_SPACE_EVENLY,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_t* btn = lv_btn_create(button_container);
label = lv_label_create(btn);
lv_label_set_text(label, "Play");
lv_label_set_text(label, "Play now");
lv_group_add_obj(group_, btn);
lv_bind(btn, LV_EVENT_CLICKED, [this](lv_obj_t*) {
queue_.Clear();
auto track = item_->Current();
if (track) {
queue_.AddNext(*track);
if (all_tracks_) {
queue_.IncludeNext(item_);
} else {
auto track = item_->Current();
if (track) {
queue_.AddNext(*track);
}
}
events::Ui().Dispatch(internal::ModalCancelPressed{});
});
@ -67,56 +108,64 @@ AddToQueue::AddToQueue(Screen* host,
bool has_queue = queue.GetCurrent().has_value();
if (has_queue) {
label = lv_label_create(root_);
lv_label_set_text(label, "Enqueue");
spacer = lv_obj_create(root_);
lv_obj_set_size(spacer, 1, 4);
button_container = lv_obj_create(root_);
lv_obj_set_size(button_container, lv_pct(100), LV_SIZE_CONTENT);
lv_obj_set_layout(button_container, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(button_container, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(button_container, LV_FLEX_ALIGN_SPACE_EVENLY,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
btn = lv_btn_create(button_container);
label = lv_label_create(btn);
lv_label_set_text(label, "Enqueue");
lv_label_set_text(label, "Next");
lv_group_add_obj(group_, btn);
lv_bind(btn, LV_EVENT_CLICKED, [this](lv_obj_t*) {
auto track = item_->Current();
if (track) {
queue_.AddLast(*track);
if (all_tracks_) {
queue_.IncludeNext(item_);
} else {
queue_.AddNext(item_->Current().value());
}
events::Ui().Dispatch(internal::ModalCancelPressed{});
});
}
label = lv_label_create(root_);
lv_label_set_text(label, "All tracks");
button_container = lv_obj_create(root_);
lv_obj_set_size(button_container, lv_pct(100), LV_SIZE_CONTENT);
lv_obj_set_layout(button_container, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(button_container, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(button_container, LV_FLEX_ALIGN_SPACE_EVENLY,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
btn = lv_btn_create(button_container);
label = lv_label_create(btn);
lv_label_set_text(label, "Play");
lv_group_add_obj(group_, btn);
lv_bind(btn, LV_EVENT_CLICKED, [this](lv_obj_t*) {
queue_.Clear();
queue_.IncludeNext(item_);
events::Ui().Dispatch(internal::ModalCancelPressed{});
});
if (has_queue) {
btn = lv_btn_create(button_container);
label = lv_label_create(btn);
lv_label_set_text(label, "Enqueue");
lv_label_set_text(label, "Last");
lv_group_add_obj(group_, btn);
lv_bind(btn, LV_EVENT_CLICKED, [this](lv_obj_t*) {
queue_.IncludeLast(item_);
if (all_tracks_) {
queue_.IncludeLast(item_);
} else {
queue_.AddLast(item_->Current().value());
}
events::Ui().Dispatch(internal::ModalCancelPressed{});
});
}
btn = lv_btn_create(root_);
spacer = lv_obj_create(root_);
lv_obj_set_size(spacer, 1, 4);
button_container = lv_obj_create(root_);
lv_obj_set_size(button_container, lv_pct(100), LV_SIZE_CONTENT);
lv_obj_set_layout(button_container, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(button_container, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(button_container, LV_FLEX_ALIGN_END,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
btn = lv_btn_create(button_container);
label = lv_label_create(btn);
lv_label_set_text(label, "Cancel");
lv_group_add_obj(group_, btn);
lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_RED),
LV_PART_MAIN);
lv_bind(btn, LV_EVENT_CLICKED, [](lv_obj_t*) {
events::Ui().Dispatch(internal::ModalCancelPressed{});

@ -76,6 +76,8 @@ MenuScreen::MenuScreen(models::TopBar& top_bar_model,
lv_obj_set_flex_flow(content_, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(content_, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START,
LV_FLEX_ALIGN_START);
lv_obj_set_style_pad_all(content_, 4, LV_PART_MAIN);
}
} // namespace ui

@ -17,6 +17,7 @@
#include "extra/widgets/spinner/lv_spinner.h"
#include "hal/lv_hal_disp.h"
#include "index.hpp"
#include "lv_api_map.h"
#include "misc/lv_area.h"
#include "model_top_bar.hpp"
#include "ui_events.hpp"

@ -127,7 +127,7 @@ Playing::Playing(models::TopBar& top_bar_model,
lv_obj_set_layout(above_fold_container, LV_LAYOUT_FLEX);
lv_obj_set_size(above_fold_container, lv_pct(100), lv_disp_get_ver_res(NULL));
lv_obj_set_flex_flow(above_fold_container, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(above_fold_container, LV_FLEX_ALIGN_SPACE_BETWEEN,
lv_obj_set_flex_align(above_fold_container, LV_FLEX_ALIGN_START,
LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
widgets::TopBar::Configuration config{
@ -136,7 +136,18 @@ Playing::Playing(models::TopBar& top_bar_model,
};
CreateTopBar(above_fold_container, config, top_bar_model);
lv_obj_t* info_container = lv_obj_create(above_fold_container);
lv_obj_t* now_playing_container = lv_obj_create(above_fold_container);
lv_obj_set_layout(now_playing_container, LV_LAYOUT_FLEX);
lv_obj_set_width(now_playing_container, lv_pct(100));
lv_obj_set_flex_grow(now_playing_container, 1);
lv_obj_set_flex_flow(now_playing_container, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(now_playing_container, LV_FLEX_ALIGN_SPACE_BETWEEN,
LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_set_style_pad_left(now_playing_container, 4, LV_PART_MAIN);
lv_obj_set_style_pad_right(now_playing_container, 4, LV_PART_MAIN);
lv_obj_t* info_container = lv_obj_create(now_playing_container);
lv_obj_set_layout(info_container, LV_LAYOUT_FLEX);
lv_obj_set_width(info_container, lv_pct(100));
lv_obj_set_flex_grow(info_container, 1);
@ -148,7 +159,7 @@ Playing::Playing(models::TopBar& top_bar_model,
lv_obj_t* album_label = info_label(info_container);
lv_obj_t* title_label = info_label(info_container);
lv_obj_t* scrubber = lv_slider_create(above_fold_container);
lv_obj_t* scrubber = lv_slider_create(now_playing_container);
lv_obj_set_size(scrubber, lv_pct(100), 5);
lv_style_init(&scrubber_style);
@ -199,7 +210,10 @@ Playing::Playing(models::TopBar& top_bar_model,
playback_model.current_track_position.onChangedAndNow(
[=](uint32_t p) { lv_slider_set_value(scrubber, p, LV_ANIM_OFF); }));
lv_obj_t* controls_container = lv_obj_create(above_fold_container);
lv_obj_t* spacer = lv_obj_create(now_playing_container);
lv_obj_set_size(spacer, 1, 4);
lv_obj_t* controls_container = lv_obj_create(now_playing_container);
lv_obj_set_size(controls_container, lv_pct(100), 20);
lv_obj_set_flex_flow(controls_container, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(controls_container, LV_FLEX_ALIGN_SPACE_EVENLY,
@ -226,7 +240,7 @@ Playing::Playing(models::TopBar& top_bar_model,
lv_group_add_obj(group_, control_button(controls_container, LV_SYMBOL_LOOP));
next_up_header_ = lv_obj_create(above_fold_container);
next_up_header_ = lv_obj_create(now_playing_container);
lv_obj_set_size(next_up_header_, lv_pct(100), 15);
lv_obj_set_flex_flow(next_up_header_, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(next_up_header_, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END,
@ -325,8 +339,9 @@ auto Playing::OnFocusAboveFold() -> void {
}
auto Playing::OnFocusBelowFold() -> void {
if (lv_obj_get_scroll_y(content_) < lv_obj_get_y(next_up_header_)) {
lv_obj_scroll_to_y(content_, lv_obj_get_y(next_up_header_), LV_ANIM_ON);
if (lv_obj_get_scroll_y(content_) < lv_obj_get_y(next_up_header_) + 20) {
lv_obj_scroll_to_y(content_, lv_obj_get_y(next_up_header_) + 20,
LV_ANIM_ON);
}
}

@ -27,11 +27,13 @@
#include "extra/widgets/spinner/lv_spinner.h"
#include "hal/lv_hal_disp.h"
#include "index.hpp"
#include "lv_api_map.h"
#include "misc/lv_anim.h"
#include "misc/lv_area.h"
#include "model_top_bar.hpp"
#include "nvs.hpp"
#include "screen.hpp"
#include "themes.hpp"
#include "ui_events.hpp"
#include "ui_fsm.hpp"
#include "widget_top_bar.hpp"
@ -69,15 +71,18 @@ Settings::Settings(models::TopBar& bar) : MenuScreen(bar, "Settings") {
lv_obj_t* list = lv_list_create(content_);
lv_obj_set_size(list, lv_pct(100), lv_pct(100));
lv_list_add_text(list, "Audio");
themes::Theme::instance()->ApplyStyle(lv_list_add_text(list, "Audio"),
themes::Style::kMenuSubheadFirst);
sub_menu(list, group_, "Bluetooth", Page::kBluetooth);
sub_menu(list, group_, "Headphones", Page::kHeadphones);
lv_list_add_text(list, "Interface");
themes::Theme::instance()->ApplyStyle(lv_list_add_text(list, "Interface"),
themes::Style::kMenuSubhead);
sub_menu(list, group_, "Appearance", Page::kAppearance);
sub_menu(list, group_, "Input Method", Page::kInput);
lv_list_add_text(list, "System");
themes::Theme::instance()->ApplyStyle(lv_list_add_text(list, "System"),
themes::Style::kMenuSubhead);
sub_menu(list, group_, "Storage", Page::kStorage);
sub_menu(list, group_, "Firmware Update", Page::kFirmwareUpdate);
sub_menu(list, group_, "About", Page::kAbout);
@ -281,10 +286,13 @@ Headphones::Headphones(models::TopBar& bar, drivers::NvsStorage& nvs)
lv_obj_t* vol_label = lv_label_create(content_);
lv_label_set_text(vol_label, "Volume Limit");
lv_obj_t* vol_dropdown = lv_dropdown_create(content_);
lv_dropdown_set_options(vol_dropdown,
"Line Level (-10 dB)\nCD Level (+6 dB)\nMax "
"before clipping (+10dB)\nCustom");
lv_obj_set_width(vol_dropdown, lv_pct(100));
lv_dropdown_set_options(
vol_dropdown,
"Line Level (-10 dB)\nCD Level (+6 dB)\nMaximum (+10dB)\nCustom");
lv_group_add_obj(group_, vol_dropdown);
themes::Theme::instance()->ApplyStyle(lv_dropdown_get_list(vol_dropdown),
themes::Style::kPopup);
uint16_t level = nvs.AmpMaxVolume();
for (int i = 0; i < index_to_level_.size() + 1; i++) {
@ -318,10 +326,17 @@ Headphones::Headphones(models::TopBar& bar, drivers::NvsStorage& nvs)
lv_obj_add_flag(custom_vol_container_, LV_OBJ_FLAG_HIDDEN);
}
lv_obj_t* spacer = lv_obj_create(content_);
lv_obj_set_size(spacer, 1, 4);
lv_obj_t* balance_label = lv_label_create(content_);
lv_label_set_text(balance_label, "Left/Right Balance");
spacer = lv_obj_create(content_);
lv_obj_set_size(spacer, 1, 4);
lv_obj_t* balance = lv_slider_create(content_);
lv_obj_set_width(balance, lv_pct(100));
lv_obj_set_size(balance, lv_pct(100), 5);
lv_slider_set_range(balance, -10, 10);
lv_slider_set_value(balance, 0, LV_ANIM_OFF);
lv_slider_set_mode(balance, LV_SLIDER_MODE_SYMMETRICAL);
@ -329,6 +344,8 @@ Headphones::Headphones(models::TopBar& bar, drivers::NvsStorage& nvs)
lv_obj_t* current_balance_label = lv_label_create(content_);
lv_label_set_text(current_balance_label, "0dB");
lv_obj_set_size(current_balance_label, lv_pct(100), LV_SIZE_CONTENT);
lv_obj_move_foreground(lv_dropdown_get_list(vol_dropdown));
}
auto Headphones::ChangeMaxVolume(uint8_t index) -> void {
@ -396,7 +413,7 @@ Appearance::Appearance(models::TopBar& bar,
lv_obj_t* brightness_label = lv_label_create(content_);
lv_label_set_text(brightness_label, "Brightness");
lv_obj_t* brightness = lv_slider_create(content_);
lv_obj_set_width(brightness, lv_pct(100));
lv_obj_set_size(brightness, lv_pct(100), 5);
lv_slider_set_range(brightness, 10, 100);
lv_slider_set_value(brightness, initial_brightness, LV_ANIM_OFF);
lv_group_add_obj(group_, brightness);
@ -434,6 +451,8 @@ InputMethod::InputMethod(models::TopBar& bar, drivers::NvsStorage& nvs)
lv_dropdown_set_selected(primary_dropdown,
static_cast<uint16_t>(nvs.PrimaryInput()));
themes::Theme::instance()->ApplyStyle(lv_dropdown_get_list(primary_dropdown),
themes::Style::kPopup);
lv_bind(primary_dropdown, LV_EVENT_VALUE_CHANGED, [this](lv_obj_t* obj) {
drivers::NvsStorage::InputModes mode;
@ -467,10 +486,19 @@ Storage::Storage(models::TopBar& bar) : MenuScreen(bar, "Storage") {
lv_bar_set_range(usage_bar, 0, 32);
lv_bar_set_value(usage_bar, 6, LV_ANIM_OFF);
lv_obj_t* reset_btn = lv_btn_create(content_);
lv_obj_t* container = lv_obj_create(content_);
lv_obj_set_size(container, lv_pct(100), 30);
lv_obj_set_layout(container, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(container, LV_FLEX_ALIGN_SPACE_EVENLY,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_t* reset_btn = lv_btn_create(container);
lv_obj_t* reset_label = lv_label_create(reset_btn);
lv_label_set_text(reset_label, "Update Database");
lv_group_add_obj(group_, reset_btn);
themes::Theme::instance()->ApplyStyle(reset_btn,
themes::Style::kButtonPrimary);
lv_bind(reset_btn, LV_EVENT_CLICKED, [&](lv_obj_t*) {
events::Ui().Dispatch(internal::ReindexDatabase{});
@ -479,18 +507,35 @@ Storage::Storage(models::TopBar& bar) : MenuScreen(bar, "Storage") {
FirmwareUpdate::FirmwareUpdate(models::TopBar& bar)
: MenuScreen(bar, "Firmware Update") {
label_pair(content_, "ESP32 FW:", "vIDKLOL");
lv_obj_set_flex_align(content_, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER,
LV_FLEX_ALIGN_CENTER);
label_pair(content_, "SAMD21 FW:", "vIDKLOL");
lv_obj_t* spacer = lv_obj_create(content_);
lv_obj_set_size(spacer, 1, 4);
lv_obj_t* flash_esp_btn = lv_btn_create(content_);
lv_obj_t* flash_esp_label = lv_label_create(flash_esp_btn);
lv_label_set_text(flash_esp_label, "Update ESP32");
lv_label_set_text(flash_esp_label, "Update");
lv_group_add_obj(group_, flash_esp_btn);
themes::Theme::instance()->ApplyStyle(flash_esp_btn,
themes::Style::kButtonPrimary);
spacer = lv_obj_create(content_);
lv_obj_set_size(spacer, 1, 8);
label_pair(content_, "ESP32 FW:", "vIDKLOL");
spacer = lv_obj_create(content_);
lv_obj_set_size(spacer, 1, 4);
lv_obj_t* flash_samd_btn = lv_btn_create(content_);
lv_obj_t* flash_samd_label = lv_label_create(flash_samd_btn);
lv_label_set_text(flash_samd_label, "Update SAMD21");
lv_label_set_text(flash_samd_label, "Update");
lv_group_add_obj(group_, flash_samd_btn);
themes::Theme::instance()->ApplyStyle(flash_samd_btn,
themes::Style::kButtonPrimary);
}
About::About(models::TopBar& bar) : MenuScreen(bar, "About") {

@ -1,7 +1,10 @@
#include "themes.hpp"
#include "core/lv_obj.h"
#include "core/lv_obj_tree.h"
#include "esp_log.h"
#include "misc/lv_color.h"
#include "misc/lv_style.h"
#include "widgets/lv_slider.h"
LV_FONT_DECLARE(font_fusion);
@ -15,12 +18,17 @@ static void theme_apply_cb(lv_theme_t* th, lv_obj_t* obj) {
Theme::Theme() {
/*Initialize the styles*/
lv_style_init(&button_style_);
lv_style_set_pad_all(&button_style_, 2);
lv_style_set_pad_left(&button_style_, 2);
lv_style_set_pad_right(&button_style_, 2);
lv_style_set_pad_top(&button_style_, 1);
lv_style_set_pad_bottom(&button_style_, 1);
lv_style_set_bg_color(&button_style_, lv_color_white());
lv_style_set_radius(&button_style_, 5);
lv_style_init(&button_style_focused_);
lv_style_set_bg_color(&button_style_focused_,
lv_palette_lighten(LV_PALETTE_BLUE_GREY, 2));
lv_palette_lighten(LV_PALETTE_BLUE, 5));
lv_style_set_bg_opa(&button_style_focused_, LV_OPA_COVER);
lv_theme_t* parent_theme = lv_disp_get_theme(NULL);
theme_ = *parent_theme;
@ -38,28 +46,125 @@ void Theme::Apply(void) {
void Theme::Callback(lv_obj_t* obj) {
lv_obj_set_style_text_font(obj, &font_fusion, 0);
lv_obj_set_style_text_color(obj, lv_color_black(), 0);
lv_obj_set_style_bg_opa(obj, LV_OPA_TRANSP, LV_PART_MAIN);
lv_obj_set_style_bg_color(obj, lv_palette_lighten(LV_PALETTE_BLUE, 5),
LV_PART_SELECTED | LV_STATE_CHECKED);
if (lv_obj_check_type(obj, &lv_btn_class) ||
lv_obj_check_type(obj, &lv_list_btn_class)) {
lv_obj_add_style(obj, &button_style_, LV_PART_MAIN);
lv_obj_add_style(obj, &button_style_focused_,
LV_PART_MAIN | LV_STATE_FOCUSED);
}
if (lv_obj_check_type(obj, &lv_list_btn_class)) {
lv_obj_set_style_radius(obj, 0, LV_PART_MAIN);
}
} else if (lv_obj_check_type(obj, &lv_slider_class)) {
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, LV_PART_MAIN);
lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_BLUE),
LV_PART_INDICATOR);
lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, LV_PART_KNOB);
lv_obj_set_style_pad_all(obj, 2, LV_PART_KNOB);
lv_obj_set_style_bg_color(obj, lv_color_white(), LV_PART_KNOB);
lv_obj_set_style_bg_color(obj, lv_palette_lighten(LV_PALETTE_BLUE, 4),
LV_PART_KNOB | LV_STATE_FOCUSED);
lv_obj_set_style_shadow_width(obj, 5, LV_PART_KNOB);
lv_obj_set_style_shadow_opa(obj, LV_OPA_COVER, LV_PART_KNOB);
} else if (lv_obj_check_type(obj, &lv_switch_class)) {
lv_obj_set_size(obj, 28, 18);
lv_obj_set_style_pad_all(obj, -2, LV_PART_KNOB);
lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, LV_PART_MAIN);
lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, LV_PART_INDICATOR);
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_GREY),
LV_PART_INDICATOR);
lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_BLUE),
LV_PART_INDICATOR | LV_STATE_CHECKED);
lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, LV_PART_KNOB);
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, LV_PART_KNOB);
lv_obj_set_style_bg_color(obj, lv_color_white(), LV_PART_KNOB);
lv_obj_set_style_bg_color(obj, lv_palette_lighten(LV_PALETTE_BLUE, 4),
LV_PART_KNOB | LV_STATE_FOCUSED);
} else if (lv_obj_check_type(obj, &lv_dropdown_class)) {
lv_obj_set_style_radius(obj, 2, LV_PART_MAIN);
lv_obj_set_style_pad_all(obj, 2, LV_PART_MAIN);
lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN);
lv_obj_set_style_border_color(obj, lv_palette_main(LV_PALETTE_BLUE),
LV_PART_MAIN);
lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_FULL, LV_PART_MAIN);
if (lv_obj_check_type(obj, &lv_switch_class)) {
lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN | LV_STATE_FOCUSED);
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_color(obj, lv_palette_lighten(LV_PALETTE_BLUE, 5),
LV_PART_MAIN | LV_STATE_FOCUSED);
}
}
void Theme::ApplyStyle(lv_obj_t* obj, Style style) {
if (style == Style::kTopBar) {
lv_obj_set_style_border_color(
obj, lv_palette_darken(LV_PALETTE_BLUE_GREY, 2), LV_PART_MAIN);
lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN);
lv_obj_set_style_border_side(
obj, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_TOP, LV_PART_MAIN);
lv_obj_set_style_pad_top(obj, 2, LV_PART_MAIN);
lv_obj_set_style_pad_bottom(obj, 2, LV_PART_MAIN);
switch (style) {
case Style::kTopBar:
lv_obj_set_style_pad_bottom(obj, 1, LV_PART_MAIN);
lv_obj_set_style_shadow_width(obj, 6, LV_PART_MAIN);
lv_obj_set_style_shadow_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_shadow_ofs_x(obj, 0, LV_PART_MAIN);
break;
case Style::kPopup:
lv_obj_set_style_shadow_width(obj, 6, LV_PART_MAIN);
lv_obj_set_style_shadow_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_shadow_ofs_x(obj, 0, LV_PART_MAIN);
lv_obj_set_style_shadow_ofs_y(obj, 0, LV_PART_MAIN);
lv_obj_set_style_radius(obj, 5, LV_PART_MAIN);
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_color(obj, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_pad_top(obj, 2, LV_PART_MAIN);
lv_obj_set_style_pad_bottom(obj, 2, LV_PART_MAIN);
lv_obj_set_style_pad_left(obj, 2, LV_PART_MAIN);
lv_obj_set_style_pad_right(obj, 2, LV_PART_MAIN);
break;
case Style::kTab:
lv_obj_set_style_radius(obj, 0, LV_PART_MAIN);
lv_obj_set_style_border_width(obj, 1, LV_STATE_CHECKED);
lv_obj_set_style_border_color(obj, lv_palette_main(LV_PALETTE_BLUE),
LV_STATE_CHECKED);
lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_BOTTOM,
LV_STATE_CHECKED);
break;
case Style::kButtonPrimary:
lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN);
lv_obj_set_style_border_color(obj, lv_palette_main(LV_PALETTE_BLUE),
LV_PART_MAIN);
lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_FULL, LV_PART_MAIN);
break;
case Style::kMenuSubheadFirst:
case Style::kMenuSubhead:
lv_obj_set_style_text_color(obj, lv_palette_darken(LV_PALETTE_GREY, 3),
LV_PART_MAIN);
lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN);
lv_obj_set_style_border_color(obj, lv_palette_lighten(LV_PALETTE_GREY, 3),
LV_PART_MAIN);
if (style == Style::kMenuSubhead) {
lv_obj_set_style_border_side(
obj, LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN);
} else {
lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN);
}
break;
default:
break;
}
}

@ -60,9 +60,12 @@ TopBar::TopBar(lv_obj_t* parent,
}
lv_obj_t* title_ = lv_label_create(container_);
lv_label_set_text(title_, config.title.c_str());
lv_obj_set_height(title_, 17);
lv_obj_set_flex_grow(title_, 1);
lv_label_set_text(title_, config.title.c_str());
lv_label_set_long_mode(title_, LV_LABEL_LONG_DOT);
lv_obj_t* playback = lv_img_create(container_);
bindings_.push_back(model.is_playing.onChangedAndNow([=](bool is_playing) {

Loading…
Cancel
Save