theme editor: some fixes and new listbox implementation based on TableField
This commit is contained in:
committed by
Raphael Coeffic
parent
df366e442a
commit
97513ffe33
@@ -25,7 +25,7 @@
|
||||
ColorList::ColorList(
|
||||
Window *parent, const rect_t &rect, std::vector<ColorEntry> colors,
|
||||
WindowFlags windowFlag, LcdFlags lcdFlags) :
|
||||
ListBase(parent, rect, getColorListNames(colors), nullptr, nullptr),
|
||||
ListBase(parent, rect, getColorListNames(colors)),
|
||||
_colorList(colors),
|
||||
_tp(ThemePersistance::instance())
|
||||
{
|
||||
@@ -43,11 +43,30 @@ std::vector<std::string> ColorList::getColorListNames(std::vector<ColorEntry> co
|
||||
return names;
|
||||
}
|
||||
|
||||
void ColorList::drawLine(BitmapBuffer *dc, const rect_t &rect, uint32_t index, LcdFlags lcdFlags)
|
||||
void ColorList::onDrawEnd(uint16_t row, uint16_t col, lv_obj_draw_part_dsc_t* dsc)
|
||||
{
|
||||
ListBase::drawLine(dc, rect, index, lcdFlags);
|
||||
auto fontHeight = getFontHeight(FONT(STD));
|
||||
dc->drawSolidFilledRect(rect.w - 22, rect.y, 16, fontHeight,
|
||||
COLOR2FLAGS(_colorList[index].colorValue));
|
||||
dc->drawSolidRect(rect.w - 22, rect.y, 16, fontHeight, 1, COLOR2FLAGS(BLACK));
|
||||
lv_draw_rect_dsc_t rect_dsc;
|
||||
lv_draw_rect_dsc_init(&rect_dsc);
|
||||
|
||||
lv_area_t coords;
|
||||
lv_coord_t area_h = lv_area_get_height(dsc->draw_area);
|
||||
|
||||
auto box_h = getFontHeight(FONT(STD));
|
||||
auto box_w = 3 * box_h / 4;
|
||||
lv_coord_t cell_right = lv_obj_get_style_pad_right(lvobj, LV_PART_ITEMS);
|
||||
|
||||
coords.x2 = dsc->draw_area->x2 - cell_right;
|
||||
coords.x1 = coords.x2 - box_w;
|
||||
coords.y1 = dsc->draw_area->y1 + (area_h - box_h) / 2;
|
||||
coords.y2 = coords.y1 + box_h - 1;
|
||||
|
||||
rect_dsc.border_color = makeLvColor(COLOR_THEME_PRIMARY1);
|
||||
rect_dsc.border_opa = LV_OPA_100;
|
||||
rect_dsc.border_width = lv_dpx(1);
|
||||
|
||||
uint16_t color = _colorList[row].colorValue;
|
||||
rect_dsc.bg_color = lv_color_make(GET_RED(color), GET_GREEN(color), GET_BLUE(color));
|
||||
rect_dsc.bg_opa = LV_OPA_100;
|
||||
|
||||
lv_draw_rect(dsc->draw_ctx, &rect_dsc, &coords);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,9 @@ class ColorList : public ListBase
|
||||
|
||||
inline ColorEntry getSelectedColor()
|
||||
{
|
||||
return _colorList[selected];
|
||||
auto idx = getSelected();
|
||||
if (idx < 0) return ColorEntry{};
|
||||
return _colorList[idx];
|
||||
}
|
||||
|
||||
std::vector<std::string> getColorListNames(std::vector<ColorEntry> colors);
|
||||
@@ -48,10 +50,10 @@ class ColorList : public ListBase
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void drawLine(BitmapBuffer *dc, const rect_t &rect, uint32_t index, LcdFlags lcdFlags) override;
|
||||
|
||||
protected:
|
||||
std::vector<ColorEntry> _colorList;
|
||||
ThemePersistance *_tp;
|
||||
|
||||
void onDrawEnd(uint16_t row, uint16_t col, lv_obj_draw_part_dsc_t* dsc);
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ extern inline tmr10ms_t getTicks()
|
||||
|
||||
|
||||
FileCarosell::FileCarosell(Window *parent, const rect_t &rect,
|
||||
std::vector<std::string> fileNames, FormField *nextCtrl) :
|
||||
std::vector<std::string> fileNames) :
|
||||
FormGroup(parent, rect, NO_FOCUS | FORM_NO_BORDER),
|
||||
_fileNames(fileNames),
|
||||
fp(new FilePreview(this, {0, 0, rect.w, rect.h}, false))
|
||||
|
||||
@@ -31,7 +31,7 @@ class FileCarosell : public FormGroup
|
||||
{
|
||||
public:
|
||||
FileCarosell(Window *parent, const rect_t &rect,
|
||||
std::vector<std::string> fileNames, FormField *nextCtrl = nullptr);
|
||||
std::vector<std::string> fileNames);
|
||||
~FileCarosell();
|
||||
|
||||
inline void setSelected(int n);
|
||||
|
||||
@@ -20,246 +20,126 @@
|
||||
*/
|
||||
#include "listbox.h"
|
||||
|
||||
constexpr int LONG_PRESS_10MS = 40;
|
||||
constexpr int ACTIVE_RADIUS = 5;
|
||||
|
||||
extern inline tmr10ms_t getTicks()
|
||||
// TODO:
|
||||
// - split this into 2 handlers:
|
||||
// - key_cb: PRESSED / LONG_PRESSED (always on)
|
||||
// - focus_cb: for FOCUSED / DEFOCUSED (only w/ 'auto-edit' mode)
|
||||
// - add 'auto-edit' mode (add / remove 'focus_cb')
|
||||
// - when turned on, ESC gets out of the edit-mode
|
||||
// and ENTER gets into edit-mode
|
||||
//
|
||||
void ListBase::event_cb(lv_event_t* e)
|
||||
{
|
||||
return g_tmr10ms;
|
||||
static bool _nested = false;
|
||||
if (_nested) return;
|
||||
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t* obj = lv_event_get_target(e);
|
||||
if (!obj) return;
|
||||
|
||||
ListBase* lb = (ListBase*)lv_event_get_user_data(e);
|
||||
if (!lb) return;
|
||||
|
||||
if (code == LV_EVENT_FOCUSED && lb->getAutoEdit()) {
|
||||
lv_group_set_editing((lv_group_t*)lv_obj_get_group(obj), true);
|
||||
} else if (code == LV_EVENT_DEFOCUSED) {
|
||||
// Hack to get rid of 'FOCUSED' event sent
|
||||
// when calling 'lv_group_set_editing()'
|
||||
_nested = true;
|
||||
lv_group_set_editing((lv_group_t*)lv_obj_get_group(obj), false);
|
||||
_nested = false;
|
||||
}
|
||||
else if (code == LV_EVENT_LONG_PRESSED) {
|
||||
lb->onLongPressed();
|
||||
lv_obj_clear_state(obj, LV_STATE_PRESSED);
|
||||
lv_indev_wait_release(lv_indev_get_act());
|
||||
}
|
||||
}
|
||||
|
||||
ListBase::ListBase(Window *parent, const rect_t &rect, std::vector<std::string> names,
|
||||
std::function<uint32_t()> getValue,
|
||||
std::function<void(uint32_t)> setValue,
|
||||
uint8_t lineHeight,
|
||||
WindowFlags windowFlags, LcdFlags lcdFlags) :
|
||||
FormField(parent, rect, windowFlags),
|
||||
names(names),
|
||||
_getValue(std::move(getValue)),
|
||||
_setValue(std::move(setValue)),
|
||||
lineHeight(lineHeight)
|
||||
ListBase::ListBase(Window* parent, const rect_t& rect,
|
||||
const std::vector<std::string>& names, uint8_t lineHeight,
|
||||
WindowFlags windowFlags) :
|
||||
TableField(parent, rect, windowFlags)
|
||||
{
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
duration10ms = 0;
|
||||
#endif
|
||||
if (_getValue != nullptr)
|
||||
setSelected(_getValue());
|
||||
else
|
||||
setSelected(0);
|
||||
lv_obj_add_event_cb(lvobj, ListBase::event_cb, LV_EVENT_ALL, this);
|
||||
|
||||
setColumnCount(1);
|
||||
setColumnWidth(0, rect.w);
|
||||
|
||||
setLineHeight(lineHeight);
|
||||
setNames(names);
|
||||
}
|
||||
|
||||
void ListBase::setAutoEdit(bool enable)
|
||||
{
|
||||
if (autoEdit == enable) return;
|
||||
|
||||
autoEdit = enable;
|
||||
if (autoEdit && hasFocus()) {
|
||||
lv_group_t* g = (lv_group_t*)lv_obj_get_group(lvobj);
|
||||
if (g) lv_group_set_editing(g, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ListBase::setNames(const std::vector<std::string>& names)
|
||||
{
|
||||
setRowCount(names.size());
|
||||
|
||||
uint16_t row = 0;
|
||||
for (const auto& name: names) {
|
||||
lv_table_set_cell_value(lvobj, row, 0, name.c_str());
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
void ListBase::setLineHeight(uint8_t height)
|
||||
{
|
||||
lv_obj_set_style_max_height(lvobj, height, LV_PART_ITEMS);
|
||||
}
|
||||
|
||||
void ListBase::setSelected(int selected)
|
||||
{
|
||||
int count = (int)names.size();
|
||||
if(selected < 0 || selected >= count)
|
||||
return;
|
||||
|
||||
if(selectionType == LISTBOX_SINGLE_SELECT) {
|
||||
if (selected != this->selected) {
|
||||
this->selected = selected;
|
||||
lv_obj_scroll_to_y(lvobj, lineHeight * this->selected - lineHeight, LV_ANIM_OFF);
|
||||
if (_setValue != nullptr) {
|
||||
_setValue(this->selected);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
} else if(selectionType == LISTBOX_MULTI_SELECT) {
|
||||
this->selected = selected;
|
||||
if(selectedIndexes.find(selected) != selectedIndexes.end()) { // Already selected -> Deselect it
|
||||
selectedIndexes.erase(selected);
|
||||
lv_obj_scroll_to_y(lvobj, lineHeight * this->selected - lineHeight, LV_ANIM_OFF);
|
||||
if(_multiSelectHandler != nullptr)
|
||||
_multiSelectHandler(selectedIndexes);
|
||||
invalidate();
|
||||
} else { // Not Selected -> Select it
|
||||
selectedIndexes.insert(selected);
|
||||
lv_obj_scroll_to_y(lvobj, lineHeight * this->selected - lineHeight, LV_ANIM_OFF);
|
||||
if (_setValue != nullptr) {
|
||||
_setValue(this->selected);
|
||||
}
|
||||
if(_multiSelectHandler != nullptr)
|
||||
_multiSelectHandler(selectedIndexes);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
select(selected, 0);
|
||||
}
|
||||
|
||||
void ListBase::setFocusLine(int selected)
|
||||
int ListBase::getSelected() const
|
||||
{
|
||||
if(selectionType == LISTBOX_MULTI_SELECT) {
|
||||
int count = (int)names.size();
|
||||
if(selected < 0 || selected >= count)
|
||||
return;
|
||||
|
||||
this->selected = selected;
|
||||
invalidate();
|
||||
}
|
||||
uint16_t row, col;
|
||||
lv_table_get_selected_cell(lvobj, &row, &col);
|
||||
if (row != LV_TABLE_CELL_NONE) { return row; }
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ListBase::drawLine(BitmapBuffer *dc, const rect_t &rect, uint32_t index, LcdFlags lcdFlags)
|
||||
void ListBase::onPress(uint16_t row, uint16_t col)
|
||||
{
|
||||
std::string name = names[index];
|
||||
int x = rect.x;
|
||||
if (row == LV_TABLE_CELL_NONE) return;
|
||||
|
||||
if ((uint32_t)activeIndex == index) {
|
||||
LcdFlags circleColor = index == (uint32_t) selected ? COLOR_THEME_PRIMARY2 : COLOR_THEME_PRIMARY1;
|
||||
auto textWidth = getTextWidth(name.c_str(), name.length(), lcdFlags);
|
||||
auto fontHeight = getFontHeight(FONT(STD));
|
||||
|
||||
dc->drawFilledCircle(rect.x + 4 + textWidth + ACTIVE_RADIUS, rect.y + fontHeight / 2, ACTIVE_RADIUS, circleColor);
|
||||
}
|
||||
|
||||
dc->drawText(x, rect.y, name.c_str(), lcdFlags);
|
||||
TRACE("SHORT_PRESS");
|
||||
if (pressHandler) { pressHandler(); }
|
||||
}
|
||||
|
||||
void ListBase::paint(BitmapBuffer *dc)
|
||||
void ListBase::onLongPressed()
|
||||
{
|
||||
dc->clear(COLOR_THEME_SECONDARY3);
|
||||
|
||||
int curY = 0;
|
||||
for (int n = 0; n < (int)names.size(); n++) {
|
||||
LcdFlags bgcolor = COLOR_THEME_PRIMARY2;
|
||||
LcdFlags textColor = COLOR_THEME_SECONDARY1;
|
||||
|
||||
// Color selected line(s)
|
||||
if((selectionType == LISTBOX_SINGLE_SELECT && n == selected) ||
|
||||
(selectionType == LISTBOX_MULTI_SELECT && (selectedIndexes.find(n) != selectedIndexes.end()))) {
|
||||
bgcolor = COLOR_THEME_FOCUS;
|
||||
textColor = COLOR_THEME_PRIMARY2;
|
||||
}
|
||||
|
||||
dc->drawSolidFilledRect(1, curY, rect.w - 2, lineHeight, bgcolor);
|
||||
|
||||
// Draw a dotted line around the current item
|
||||
if(n == selected && selectionType == LISTBOX_MULTI_SELECT &&
|
||||
hasFocus()) {
|
||||
dc->drawRect(2, curY, rect.w - 4, lineHeight, 2, DOTTED);
|
||||
}
|
||||
|
||||
auto fontHeight = getFontHeight(FONT(STD));
|
||||
drawLine(dc, { 8, curY + (lineHeight - fontHeight) / 2, rect.w, lineHeight}, n, textColor);
|
||||
|
||||
curY += lineHeight;
|
||||
}
|
||||
if (!(windowFlags & (FORM_NO_BORDER | FORM_FORWARD_FOCUS))) {
|
||||
dc->drawSolidRect(0, 0, rect.w, rect.h, 2, COLOR_THEME_FOCUS);
|
||||
}
|
||||
TRACE("LONG_PRESS");
|
||||
if (longPressHandler) { longPressHandler(); }
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void ListBase::onEvent(event_t event)
|
||||
{
|
||||
int oldSelected = selected;
|
||||
switch (event) {
|
||||
case EVT_ROTARY_RIGHT:
|
||||
oldSelected = (selected + 1) % names.size();
|
||||
if(selectionType == LISTBOX_SINGLE_SELECT)
|
||||
setSelected(oldSelected);
|
||||
else
|
||||
setFocusLine(oldSelected);
|
||||
onKeyPress();
|
||||
break;
|
||||
case EVT_ROTARY_LEFT:
|
||||
oldSelected--;
|
||||
if (oldSelected < 0) oldSelected = names.size() - 1;
|
||||
if(selectionType == LISTBOX_SINGLE_SELECT)
|
||||
setSelected(oldSelected);
|
||||
else
|
||||
setFocusLine(oldSelected);
|
||||
onKeyPress();
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_ENTER):
|
||||
if (longPressHandler) {
|
||||
killEvents(event);
|
||||
longPressHandler(event);
|
||||
}
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_ENTER):
|
||||
if(selectionType == LISTBOX_MULTI_SELECT)
|
||||
setSelected(this->selected);
|
||||
if (pressHandler) {
|
||||
killEvents(event);
|
||||
pressHandler(event);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FormField::onEvent(event);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
bool ListBase::isLongPress()
|
||||
// TODO: !auto-edit
|
||||
void ListBase::onClicked()
|
||||
{
|
||||
unsigned int curTimer = getTicks();
|
||||
return // slidingWindow == nullptr &&
|
||||
duration10ms != 0 && curTimer - duration10ms > LONG_PRESS_10MS;
|
||||
}
|
||||
|
||||
void ListBase::checkEvents(void)
|
||||
{
|
||||
Window::checkEvents();
|
||||
|
||||
if (isLongPress()) {
|
||||
if (longPressHandler) {
|
||||
if(selectionType == LISTBOX_SINGLE_SELECT)
|
||||
setSelected(yDown / lineHeight);
|
||||
else
|
||||
setFocusLine(yDown / lineHeight);
|
||||
longPressHandler(0);
|
||||
killAllEvents();
|
||||
duration10ms = 0;
|
||||
waslongpress = true;
|
||||
return;
|
||||
}
|
||||
if (!getAutoEdit()) {
|
||||
lv_group_set_editing((lv_group_t*)lv_obj_get_group(lvobj), true);
|
||||
} else {
|
||||
TableField::onClicked();
|
||||
}
|
||||
}
|
||||
|
||||
bool ListBase::onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY)
|
||||
void ListBase::onCancel()
|
||||
{
|
||||
if (touchState.event == TE_SLIDE_END) {
|
||||
duration10ms = 0;
|
||||
lv_group_t* g = (lv_group_t*)lv_obj_get_group(lvobj);
|
||||
if (!getAutoEdit() && lv_group_get_editing(g)) {
|
||||
lv_group_set_editing(g, false);
|
||||
} else {
|
||||
TableField::onCancel();
|
||||
}
|
||||
|
||||
return FormField::onTouchSlide(x, y, startX, startY, slideX, slideY);
|
||||
}
|
||||
|
||||
bool ListBase::onTouchStart(coord_t x, coord_t y)
|
||||
{
|
||||
waslongpress = false;
|
||||
if (duration10ms == 0) {
|
||||
duration10ms = getTicks();
|
||||
}
|
||||
|
||||
yDown = y;
|
||||
|
||||
return true; // stop the processing and say that i handled it
|
||||
}
|
||||
|
||||
bool ListBase::onTouchEnd(coord_t x, coord_t y)
|
||||
{
|
||||
if (!isEnabled()) return false;
|
||||
if (// slidingWindow ||
|
||||
waslongpress)
|
||||
return false; // if we slide then this is not a selection
|
||||
|
||||
auto selected = yDown / lineHeight;
|
||||
setSelected(selected);
|
||||
|
||||
duration10ms = 0;
|
||||
|
||||
// if (!hasFocus()) {
|
||||
// setFocus(SET_FOCUS_DEFAULT);
|
||||
// }
|
||||
|
||||
if (pressHandler != nullptr) {
|
||||
pressHandler(0);
|
||||
}
|
||||
invalidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -19,137 +19,66 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
#include "bitmapbuffer.h"
|
||||
#include "libopenui.h"
|
||||
#include "touch.h"
|
||||
|
||||
// base class for lists of elements with names
|
||||
class ListBase : public FormField
|
||||
class ListBase : public TableField
|
||||
{
|
||||
public:
|
||||
ListBase(Window *parent, const rect_t &rect, std::vector<std::string> names,
|
||||
std::function<uint32_t()> getValue = nullptr,
|
||||
std::function<void(uint32_t)> setValue = nullptr,
|
||||
uint8_t lineHeight = MENUS_LINE_HEIGHT,
|
||||
WindowFlags windowFlags = 0, LcdFlags lcdFlags = 0);
|
||||
std::function<void()> longPressHandler = nullptr;
|
||||
std::function<void()> pressHandler = nullptr;
|
||||
bool autoEdit = false;
|
||||
|
||||
typedef enum {
|
||||
LISTBOX_SINGLE_SELECT,
|
||||
LISTBOX_MULTI_SELECT
|
||||
} selecttype_e;
|
||||
public:
|
||||
ListBase(Window* parent, const rect_t& rect, const std::vector<std::string>& names,
|
||||
uint8_t lineHeight = MENUS_LINE_HEIGHT, WindowFlags windowFlags = 0);
|
||||
|
||||
// draw one line of the list. Default implementation just draws the names. Oher types of lists
|
||||
// can draw anything they want.
|
||||
virtual void drawLine(BitmapBuffer *dc, const rect_t &rect, uint32_t index, LcdFlags lcdFlags);
|
||||
void paint (BitmapBuffer *dc) override;
|
||||
bool getAutoEdit() const { return autoEdit; }
|
||||
void setAutoEdit(bool enable);
|
||||
|
||||
virtual void setSelected(int selected);
|
||||
virtual void setFocusLine(int selected);
|
||||
void clearSelection() {selectedIndexes.clear(); invalidate();}
|
||||
void setNames(const std::vector<std::string>& names);
|
||||
void setLineHeight(uint8_t height);
|
||||
|
||||
void setMultiSelectHandler(std::function<void(std::set<uint32_t>)> handler)
|
||||
{
|
||||
_multiSelectHandler = std::move(handler);
|
||||
}
|
||||
virtual void setSelected(int selected);
|
||||
int getSelected() const;
|
||||
|
||||
void setLongPressHandler(std::function<void(event_t)> handler)
|
||||
{
|
||||
longPressHandler = std::move(handler);
|
||||
}
|
||||
void setLongPressHandler(std::function<void()> handler)
|
||||
{
|
||||
longPressHandler = std::move(handler);
|
||||
}
|
||||
|
||||
void setPressHandler(std::function<void(event_t)> handler)
|
||||
{
|
||||
pressHandler = std::move(handler);
|
||||
}
|
||||
|
||||
void setSelectionMode(selecttype_e st)
|
||||
{
|
||||
selectionType = st;
|
||||
}
|
||||
|
||||
void setActiveIndex(int index)
|
||||
{
|
||||
if (index >= 0 && index < (int) names.size()) {
|
||||
activeIndex = index;
|
||||
} else {
|
||||
activeIndex = -1;
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
inline int getSelected()
|
||||
{
|
||||
return selected;
|
||||
}
|
||||
|
||||
inline void setLineHeight(uint8_t height)
|
||||
{
|
||||
lineHeight = height;
|
||||
}
|
||||
|
||||
inline void setNames(std::vector<std::string> names)
|
||||
{
|
||||
this->names.assign(names.begin(), names.end());
|
||||
invalidate();
|
||||
}
|
||||
void setPressHandler(std::function<void()> handler)
|
||||
{
|
||||
pressHandler = std::move(handler);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "ListBox";
|
||||
}
|
||||
std::string getName() const override { return "ListBox"; }
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void onEvent(event_t event) override;
|
||||
#endif
|
||||
protected:
|
||||
static void event_cb(lv_event_t* e);
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
void checkEvents(void) override;
|
||||
bool onTouchEnd(coord_t x, coord_t y) override;
|
||||
bool onTouchStart(coord_t x, coord_t y) override;
|
||||
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY) override;
|
||||
bool isLongPress();
|
||||
#endif
|
||||
void onPress(uint16_t row, uint16_t col) override;
|
||||
void onLongPressed();
|
||||
|
||||
protected:
|
||||
std::function<void(event_t)> longPressHandler = nullptr;
|
||||
std::function<void(event_t)> pressHandler = nullptr;
|
||||
std::vector<std::string> names;
|
||||
std::function<uint32_t()> _getValue;
|
||||
std::function<void(uint32_t)> _setValue;
|
||||
std::function<void(std::set<uint32_t>)> _multiSelectHandler = nullptr;
|
||||
int lineHeight;
|
||||
int32_t selected = -1;
|
||||
int32_t activeIndex = -1;
|
||||
std::set<uint32_t> selectedIndexes;
|
||||
selecttype_e selectionType = LISTBOX_SINGLE_SELECT;
|
||||
bool waslongpress = false;
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
uint32_t duration10ms;
|
||||
coord_t yDown;
|
||||
#endif
|
||||
void onClicked() override;
|
||||
void onCancel() override;
|
||||
};
|
||||
|
||||
|
||||
class ListBox : public ListBase
|
||||
{
|
||||
std::string title;
|
||||
|
||||
public:
|
||||
using ListBase::ListBase;
|
||||
|
||||
inline void setTitle(std::string title)
|
||||
{
|
||||
this->title = title;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string title;
|
||||
inline void setTitle(std::string title) { this->title = title; }
|
||||
};
|
||||
|
||||
|
||||
@@ -228,6 +228,10 @@ class PreviewWindow : public FormGroup
|
||||
std::vector<ColorEntry> colorList) :
|
||||
FormGroup(window, rect, NO_FOCUS), _colorList(colorList)
|
||||
{
|
||||
// reset default group to avoid focus
|
||||
lv_group_t* def_group = lv_group_get_default();
|
||||
lv_group_set_default(nullptr);
|
||||
|
||||
new ThemedStaticText(this, {5, 40, 100, LINE_HEIGHT}, "Checkbox", COLOR_THEME_PRIMARY1_INDEX);
|
||||
new ThemedCheckBox(this, {100 + 15, 40, 20, LINE_HEIGHT}, true);
|
||||
new ThemedCheckBox(this, {140 + 15, 40, 20, LINE_HEIGHT}, false);
|
||||
@@ -247,6 +251,8 @@ class PreviewWindow : public FormGroup
|
||||
new ThemedTextEdit(this, {110, 160, 100, LINE_HEIGHT + 1}, FocusText,
|
||||
COLOR_THEME_FOCUS_INDEX, COLOR_THEME_PRIMARY2_INDEX);
|
||||
ticks = getTicks();
|
||||
|
||||
lv_group_set_default(def_group);
|
||||
}
|
||||
|
||||
void setColorList(std::vector<ColorEntry> colorList)
|
||||
@@ -268,7 +274,7 @@ class PreviewWindow : public FormGroup
|
||||
BitmapBuffer *getBitmap(const uint8_t *maskData, uint32_t bgColor,
|
||||
uint32_t fgColor, int *width)
|
||||
{
|
||||
auto mask = BitmapBuffer::load8bitMask(maskData);
|
||||
auto mask = BitmapBuffer::load8bitMaskLZ4(maskData);
|
||||
BitmapBuffer *newBm =
|
||||
new BitmapBuffer(BMP_RGB565, mask->width(), mask->height());
|
||||
newBm->clear(bgColor);
|
||||
|
||||
@@ -372,20 +372,14 @@ class ThemeEditPage : public Page
|
||||
});
|
||||
return 0;
|
||||
}, BUTTON_BACKGROUND | OPAQUE, textFont);
|
||||
|
||||
// setup the prev next controls so save and details are in the mix
|
||||
// _cList->setNextField(_detailButton);
|
||||
// _cList->setPreviousField(_detailButton);
|
||||
// _detailButton->setNextField(_cList);
|
||||
// _detailButton->setPreviousField(_cList);
|
||||
}
|
||||
|
||||
void buildBody(FormGroup *window)
|
||||
{
|
||||
rect_t r = { LEFT_LIST_OFFSET, TOP_LIST_OFFSET, COLOR_LIST_WIDTH, COLOR_LIST_HEIGHT};
|
||||
_cList = new ColorList(window, r, _theme.getColorList());
|
||||
_cList->setLongPressHandler([=] (event_t event) { editColorPage(); });
|
||||
_cList->setPressHandler([=] (event_t event) { editColorPage(); });
|
||||
_cList->setLongPressHandler([=] () { editColorPage(); });
|
||||
_cList->setPressHandler([=] () { editColorPage(); });
|
||||
|
||||
if (LCD_W > LCD_H) {
|
||||
r = {
|
||||
@@ -458,7 +452,6 @@ void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp)
|
||||
tp->setDefaultTheme(listBox->getSelected());
|
||||
nameText->setTextFlags(COLOR_THEME_PRIMARY1);
|
||||
authorText->setTextFlags(COLOR_THEME_PRIMARY1);
|
||||
listBox->setActiveIndex(tp->getThemeIndex());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -533,7 +526,8 @@ void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp)
|
||||
if (confirmationDialog("Delete Theme?", tp->getThemeByIndex(listBox->getSelected())->getName())) {
|
||||
tp->deleteThemeByIndex(listBox->getSelected());
|
||||
listBox->setNames(tp->getNames());
|
||||
listBox->setSelected(min<int>(currentTheme, tp->getNames().size() - 1));
|
||||
currentTheme = min<int>(currentTheme, tp->getNames().size() - 1);
|
||||
listBox->setSelected(currentTheme);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -541,28 +535,22 @@ void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp)
|
||||
|
||||
void ThemeSetupPage::setupListbox(FormWindow *window, rect_t r, ThemePersistance *tp)
|
||||
{
|
||||
listBox = new ListBox(
|
||||
window, r, tp->getNames(),
|
||||
[=]() {
|
||||
return currentTheme;
|
||||
},
|
||||
[=](uint8_t value) {
|
||||
if (themeColorPreview && authorText && nameText && fileCarosell != nullptr) {
|
||||
ThemeFile *theme = tp->getThemeByIndex(value);
|
||||
themeColorPreview->setColorList(theme->getColorList());
|
||||
setAuthor(theme);
|
||||
nameText->setText(theme->getName());
|
||||
fileCarosell->setFileNames(theme->getThemeImageFileNames());
|
||||
}
|
||||
currentTheme = value;
|
||||
});
|
||||
listBox->setActiveIndex(tp->getThemeIndex());
|
||||
listBox->setTitle(STR_THEME + std::string("s"));
|
||||
listBox->setLongPressHandler([=] (event_t event) { displayThemeMenu(window, tp); });
|
||||
listBox->setPressHandler([=] (event_t event) {
|
||||
if (event != 0)
|
||||
displayThemeMenu(window, tp);
|
||||
});
|
||||
listBox = new ListBox(window, r, tp->getNames());
|
||||
listBox->setAutoEdit(true);
|
||||
listBox->setSelected(currentTheme);
|
||||
listBox->setTitle(STR_THEME + std::string("s")); // TODO: fix this!
|
||||
listBox->setLongPressHandler([=] () { displayThemeMenu(window, tp); });
|
||||
listBox->setPressHandler([=] () {
|
||||
auto value = listBox->getSelected();
|
||||
if (themeColorPreview && authorText && nameText && fileCarosell) {
|
||||
ThemeFile *theme = tp->getThemeByIndex(value);
|
||||
themeColorPreview->setColorList(theme->getColorList());
|
||||
setAuthor(theme);
|
||||
nameText->setText(theme->getName());
|
||||
fileCarosell->setFileNames(theme->getThemeImageFileNames());
|
||||
}
|
||||
currentTheme = value;
|
||||
});
|
||||
}
|
||||
|
||||
void ThemeSetupPage::build(FormWindow *window)
|
||||
@@ -609,7 +597,7 @@ void ThemeSetupPage::build(FormWindow *window)
|
||||
r.h = LEFT_LIST_HEIGHT - COLOR_PREVIEW_HEIGHT - 50;
|
||||
}
|
||||
auto fileNames = theme != nullptr ? theme->getThemeImageFileNames() : std::vector<std::string>();
|
||||
fileCarosell = new FileCarosell(window, r, fileNames, listBox);
|
||||
fileCarosell = new FileCarosell(window, r, fileNames);
|
||||
|
||||
// author and name of theme on right side of screen
|
||||
r.x += 7;
|
||||
|
||||
@@ -286,7 +286,7 @@ static void style_init(void)
|
||||
lv_style_set_bg_color(&styles.btn, makeLvColor(COLOR_THEME_SECONDARY2));
|
||||
|
||||
lv_style_set_border_opa(&styles.btn, LV_OPA_0);
|
||||
lv_style_set_border_width(&styles.btn, lv_disp_dpx(theme.disp, 2));
|
||||
lv_style_set_border_width(&styles.btn, BORDER_WIDTH);
|
||||
|
||||
lv_style_set_text_color(&styles.btn, color_text);
|
||||
lv_style_set_pad_hor(&styles.btn, PAD_SMALL);
|
||||
@@ -311,7 +311,7 @@ static void style_init(void)
|
||||
style_init_reset(&styles.focus_border);
|
||||
lv_style_set_border_color(&styles.focus_border, makeLvColor(COLOR_THEME_FOCUS));
|
||||
lv_style_set_border_opa(&styles.focus_border, LV_OPA_100);
|
||||
lv_style_set_border_width(&styles.focus_border, lv_disp_dpx(theme.disp, 2));
|
||||
lv_style_set_border_width(&styles.focus_border, BORDER_WIDTH);
|
||||
|
||||
style_init_reset(&styles.clip_corner);
|
||||
lv_style_set_clip_corner(&styles.clip_corner, true);
|
||||
@@ -823,7 +823,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
||||
|
||||
#if LV_USE_TABLE
|
||||
else if(lv_obj_check_type(obj, &lv_table_class)) {
|
||||
// lv_obj_add_style(obj, &styles.card, 0);
|
||||
lv_obj_add_style(obj, &styles.pad_zero, 0);
|
||||
lv_obj_add_style(obj, &styles.no_radius, 0);
|
||||
lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR);
|
||||
@@ -832,7 +831,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
||||
lv_obj_add_style(obj, &styles.table_cell, LV_PART_ITEMS);
|
||||
lv_obj_add_style(obj, &styles.pad_small, LV_PART_ITEMS);
|
||||
lv_obj_add_style(obj, &styles.pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
|
||||
lv_obj_add_style(obj, &styles.bg_color_focus, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
|
||||
lv_obj_add_style(obj, &styles.bg_color_focus, LV_PART_ITEMS | LV_STATE_EDITED);
|
||||
}
|
||||
#endif
|
||||
|
||||
Vendored
+1
-1
Submodule radio/src/thirdparty/libopenui updated: fa67cf2d56...1ae025f640
Reference in New Issue
Block a user