Model setup: use single buttons instead of button matrix for sub-screens
This commit is contained in:
committed by
Raphael Coeffic
parent
e31a1cc1fc
commit
b1cbbc4fc6
@@ -84,12 +84,140 @@ struct ModelBitmapEdit : public FileChoice {
|
||||
}
|
||||
};
|
||||
|
||||
struct SubScreenButtonMatrix : public ButtonMatrix {
|
||||
SubScreenButtonMatrix(Window* parent, const rect_t& rect);
|
||||
struct TimerBtnMatrix : public ButtonMatrix {
|
||||
TimerBtnMatrix(Window* parent, const rect_t& rect);
|
||||
void onPress(uint8_t btn_id) override;
|
||||
bool isActive(uint8_t btn_id) override;
|
||||
};
|
||||
|
||||
class SubScreenButton : public Button
|
||||
{
|
||||
std::string text;
|
||||
|
||||
public:
|
||||
SubScreenButton(Window* parent, const char* text,
|
||||
std::function<void(void)> pressHandler);
|
||||
|
||||
protected:
|
||||
virtual bool isActive() { return false; }
|
||||
static void event_cb(lv_event_t* e);
|
||||
};
|
||||
|
||||
SubScreenButton::SubScreenButton(Window* parent, const char* text,
|
||||
std::function<void(void)> pressHandler) :
|
||||
Button(parent, rect_t{}, [=]() -> uint8_t {
|
||||
pressHandler();
|
||||
return 0;
|
||||
}, 0, 0, lv_btn_create),
|
||||
text(text)
|
||||
{
|
||||
lv_obj_add_event_cb(lvobj, SubScreenButton::event_cb, LV_EVENT_ALL, nullptr);
|
||||
}
|
||||
|
||||
// TODO: move code to TextButton with BEGIN/END in main and using events
|
||||
// to grab lv_draw_label_dsc_t (see lv_btnmatrix.c)
|
||||
//
|
||||
void SubScreenButton::event_cb(lv_event_t* e)
|
||||
{
|
||||
auto obj = lv_event_get_target(e);
|
||||
auto btn = (SubScreenButton*)lv_obj_get_user_data(obj);
|
||||
if (!btn) return;
|
||||
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
if (code == LV_EVENT_DRAW_PART_BEGIN) {
|
||||
|
||||
lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
|
||||
if (dsc->part != LV_PART_MAIN) return;
|
||||
|
||||
if (btn->isActive()) {
|
||||
dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_ACTIVE);
|
||||
} else {
|
||||
dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
|
||||
} else if (code == LV_EVENT_DRAW_PART_END) {
|
||||
|
||||
if (btn->text.empty()) return;
|
||||
|
||||
lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
|
||||
if (dsc->part != LV_PART_MAIN) return;
|
||||
|
||||
lv_area_t txt_coords;
|
||||
lv_obj_get_content_coords(obj, &txt_coords);
|
||||
|
||||
lv_draw_label_dsc_t label_draw_dsc;
|
||||
lv_draw_label_dsc_init(&label_draw_dsc);
|
||||
|
||||
lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_draw_dsc);
|
||||
label_draw_dsc.align = LV_TEXT_ALIGN_CENTER;
|
||||
|
||||
if (btn->isActive()) {
|
||||
label_draw_dsc.color = makeLvColor(COLOR_THEME_PRIMARY2);
|
||||
} else {
|
||||
label_draw_dsc.color = makeLvColor(COLOR_THEME_SECONDARY1);
|
||||
}
|
||||
|
||||
lv_area_t txt_clip;
|
||||
bool is_common = _lv_area_intersect(&txt_clip, &txt_coords, dsc->draw_ctx->clip_area);
|
||||
if (!is_common) return;
|
||||
|
||||
lv_draw_label(dsc->draw_ctx, &label_draw_dsc, &txt_coords, btn->text.c_str(), nullptr);
|
||||
|
||||
} else if (code == LV_EVENT_GET_SELF_SIZE) {
|
||||
|
||||
// from lv_label_t with some simplifications
|
||||
lv_point_t size;
|
||||
const lv_font_t* font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);
|
||||
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN);
|
||||
lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN);
|
||||
lv_text_flag_t flag = LV_TEXT_FLAG_NONE;
|
||||
|
||||
lv_coord_t w = lv_obj_get_content_width(obj);
|
||||
if (lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT && !obj->w_layout)
|
||||
w = LV_COORD_MAX;
|
||||
else
|
||||
w = lv_obj_get_content_width(obj);
|
||||
|
||||
lv_txt_get_size(&size, btn->text.c_str(), font, letter_space, line_space, w, flag);
|
||||
|
||||
lv_point_t* self_size = (lv_point_t*)lv_event_get_param(e);
|
||||
self_size->x = LV_MAX(self_size->x, size.x);
|
||||
self_size->y = LV_MAX(self_size->y, size.y);
|
||||
}
|
||||
}
|
||||
|
||||
struct IntmoduleButton : public SubScreenButton {
|
||||
IntmoduleButton(Window* parent) :
|
||||
SubScreenButton(parent, STR_INTERNALRF,
|
||||
[]() { new ModulePage(INTERNAL_MODULE); })
|
||||
{
|
||||
}
|
||||
bool isActive() override
|
||||
{
|
||||
return g_model.moduleData[INTERNAL_MODULE].type > 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExtmoduleButton : public SubScreenButton {
|
||||
ExtmoduleButton(Window* parent) :
|
||||
SubScreenButton(parent, STR_EXTERNALRF,
|
||||
[]() { new ModulePage(EXTERNAL_MODULE); })
|
||||
{
|
||||
}
|
||||
bool isActive() override
|
||||
{
|
||||
return g_model.moduleData[EXTERNAL_MODULE].type > 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct TrainerModuleButton : public SubScreenButton {
|
||||
TrainerModuleButton(Window* parent) :
|
||||
SubScreenButton(parent, STR_TRAINER, []() { new TrainerPage(); })
|
||||
{
|
||||
}
|
||||
bool isActive() override { return g_model.trainerData.mode > 0; }
|
||||
};
|
||||
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
@@ -98,6 +226,7 @@ static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
void ModelSetupPage::build(FormWindow * window)
|
||||
{
|
||||
window->setFlexLayout();
|
||||
|
||||
FlexGridLayout grid(line_col_dsc, line_row_dsc, 2);
|
||||
|
||||
// Model name
|
||||
@@ -128,82 +257,68 @@ void ModelSetupPage::build(FormWindow * window)
|
||||
new Choice(line, rect_t{}, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.jitterFilter));
|
||||
|
||||
// Sub-screens
|
||||
new SubScreenButtonMatrix(window, rect_t{});
|
||||
// Modules
|
||||
auto form = new FormGroup(window, rect_t{});
|
||||
form->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, lv_dpx(8));
|
||||
lv_obj_set_style_pad_all(form->getLvObj(), lv_dpx(8), 0);
|
||||
|
||||
new IntmoduleButton(form);
|
||||
new ExtmoduleButton(form);
|
||||
new TrainerModuleButton(form);
|
||||
|
||||
// Timer buttons
|
||||
form = new FormGroup(window, rect_t{});
|
||||
form->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, lv_dpx(8));
|
||||
lv_obj_set_style_pad_all(form->getLvObj(), lv_dpx(8), 0);
|
||||
|
||||
new SubScreenButton(form, TR_TIMER "1",
|
||||
[]() { new TimerWindow(0); });
|
||||
new SubScreenButton(form, TR_TIMER "2",
|
||||
[]() { new TimerWindow(1); });
|
||||
new SubScreenButton(form, TR_TIMER "3",
|
||||
[]() { new TimerWindow(2); });
|
||||
|
||||
form = new FormGroup(window, rect_t{});
|
||||
form->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, lv_dpx(8));
|
||||
lv_obj_set_style_pad_all(form->getLvObj(), lv_dpx(8), 0);
|
||||
|
||||
new SubScreenButton(form, STR_PREFLIGHT,
|
||||
[]() { new ModulePage(EXTERNAL_MODULE); });
|
||||
new SubScreenButton(form, STR_TRIMS,
|
||||
[]() { new ModulePage(EXTERNAL_MODULE); });
|
||||
new SubScreenButton(form, STR_THROTTLE_LABEL,
|
||||
[]() { new ModulePage(EXTERNAL_MODULE); });
|
||||
}
|
||||
|
||||
#define MAX_SUBSCREEN_BTNS 9
|
||||
|
||||
SubScreenButtonMatrix::SubScreenButtonMatrix(Window* parent, const rect_t& r) :
|
||||
TimerBtnMatrix::TimerBtnMatrix(Window* parent, const rect_t& r) :
|
||||
ButtonMatrix(parent, r)
|
||||
{
|
||||
initBtnMap(3, MAX_SUBSCREEN_BTNS);
|
||||
|
||||
setText(0, STR_INTERNALRF);
|
||||
setText(1, STR_EXTERNALRF);
|
||||
setText(2, STR_TRAINER);
|
||||
|
||||
setText(3, STR_PREFLIGHT);
|
||||
setText(4, STR_TRIMS);
|
||||
setText(5, STR_THROTTLE_LABEL);
|
||||
setText(6, TR_TIMER "1");
|
||||
setText(7, TR_TIMER "2");
|
||||
setText(8, TR_TIMER "3");
|
||||
initBtnMap(3, MAX_TIMERS);
|
||||
setText(0, TR_TIMER "1");
|
||||
setText(1, TR_TIMER "2");
|
||||
setText(2, TR_TIMER "3");
|
||||
update();
|
||||
|
||||
lv_btnmatrix_set_btn_width(lvobj, 3, 2);
|
||||
lv_obj_set_width(lvobj, lv_pct(100));
|
||||
lv_obj_set_height(lvobj, (4 * LV_DPI_DEF) / 3);
|
||||
lv_obj_set_height(lvobj, LV_DPI_DEF / 2);
|
||||
|
||||
lv_obj_set_style_bg_opa(lvobj, LV_OPA_0, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_all(lvobj, LV_DPI_DEF / 10, LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_opa(lvobj, LV_OPA_0, 0);
|
||||
lv_obj_set_style_pad_all(lvobj, lv_dpx(8), 0);
|
||||
|
||||
lv_obj_set_style_pad_row(lvobj, 8, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_column(lvobj, 8, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_row(lvobj, lv_dpx(8), 0);
|
||||
lv_obj_set_style_pad_column(lvobj, lv_dpx(8), 0);
|
||||
}
|
||||
|
||||
void SubScreenButtonMatrix::onPress(uint8_t btn_id)
|
||||
void TimerBtnMatrix::onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_SUBSCREEN_BTNS) return;
|
||||
|
||||
Window* w = nullptr;
|
||||
switch (btn_id) {
|
||||
case 0:
|
||||
w = new ModulePage(INTERNAL_MODULE);
|
||||
break;
|
||||
case 1:
|
||||
w = new ModulePage(EXTERNAL_MODULE);
|
||||
break;
|
||||
case 2:
|
||||
w = new TrainerPage();
|
||||
break;
|
||||
case 3:
|
||||
w = new PreflightChecks();
|
||||
break;
|
||||
case 4:
|
||||
w = new TrimsSetup();
|
||||
break;
|
||||
case 5:
|
||||
w = new ThrottleParams();
|
||||
break;
|
||||
default:
|
||||
w = new TimerWindow((uint8_t)(btn_id - 6));
|
||||
break;
|
||||
}
|
||||
|
||||
// if (w) w->setFocus();
|
||||
if (btn_id >= MAX_TIMERS) return;
|
||||
new TimerWindow((uint8_t)(btn_id));
|
||||
}
|
||||
|
||||
bool SubScreenButtonMatrix::isActive(uint8_t btn_id)
|
||||
bool TimerBtnMatrix::isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id == 0)
|
||||
return g_model.moduleData[INTERNAL_MODULE].type > 0;
|
||||
|
||||
if (btn_id == 1)
|
||||
return g_model.moduleData[EXTERNAL_MODULE].type > 0;
|
||||
|
||||
if (btn_id == 2)
|
||||
return g_model.trainerData.mode > 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user