Implement form drawing via styles rather than paint() method

This commit is contained in:
Raphael Coeffic
2022-06-11 15:13:11 +02:00
committed by Raphael Coeffic
parent e53c334aed
commit 9804ff9f21
4 changed files with 165 additions and 208 deletions
+1 -2
View File
@@ -34,6 +34,7 @@ class Button: public FormField
FormField(parent, rect, windowFlags, textFlags, factory),
pressHandler(std::move(pressHandler))
{
lv_obj_set_style_bg_opa(lvobj, LV_OPA_TRANSP, LV_PART_MAIN);
}
#if defined(DEBUG_WINDOWS)
@@ -116,8 +117,6 @@ class TextButton: public Button
bgColorHandler = std::move(handler);
}
void paint(BitmapBuffer* dc) override {}
protected:
lv_obj_t * label = nullptr;
-2
View File
@@ -65,8 +65,6 @@ class CheckBox : public FormField {
{
_setValue = std::move(handler);
}
void paint(BitmapBuffer* dc) override {}
protected:
std::string label;
+43 -33
View File
@@ -21,15 +21,34 @@
#include "bitmapbuffer.h"
#include "libopenui_config.h"
FormField::FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags, LcdFlags textFlags, LvglWidgetFactory *factory) :
Window(parent, rect, windowFlags, textFlags, factory)
static lv_style_t bg_style;
static lv_style_t focus_style;
static lv_style_t edit_style;
FormField::FormField(Window* parent, const rect_t& rect,
WindowFlags windowFlags, LcdFlags textFlags,
LvglWidgetFactory* factory) :
Window(parent, rect, windowFlags, textFlags, factory)
{
if (!(windowFlags & NO_FOCUS)) {
auto * form = dynamic_cast<FormGroup *>(parent);
auto* form = dynamic_cast<FormGroup*>(parent);
if (form) {
form->addField(this, windowFlags & PUSH_FRONT);
}
}
lv_style_init(&bg_style);
lv_style_set_bg_color(&bg_style, makeLvColor(COLOR_THEME_PRIMARY2));
lv_style_set_bg_opa(&bg_style, LV_OPA_COVER);
lv_obj_add_style(lvobj, &bg_style, LV_PART_MAIN);
lv_style_init(&focus_style);
lv_style_set_bg_color(&focus_style, makeLvColor(COLOR_THEME_FOCUS));
lv_obj_add_style(lvobj, &focus_style, LV_PART_MAIN | LV_STATE_FOCUSED);
lv_style_init(&edit_style);
lv_style_set_bg_color(&edit_style, makeLvColor(COLOR_THEME_EDIT));
lv_obj_add_style(lvobj, &edit_style, LV_PART_MAIN | LV_STATE_EDITED);
}
#if defined(HARDWARE_KEYS)
@@ -90,25 +109,28 @@ void FormField::setFocus(uint8_t flag, Window * from)
}
}
void FormField::paint(BitmapBuffer * dc)
{
uint32_t bgColor = 0;
if (backgroundHandler) {
bgColor = backgroundHandler(this);
} else {
if (editMode) {
bgColor = COLOR_THEME_EDIT;
} else if (hasFocus()) {
bgColor = COLOR_THEME_FOCUS;
} else {
bgColor = COLOR_THEME_PRIMARY2;
}
}
static lv_style_t border_style;
static lv_style_t focus_border_style;
if (editMode || ! (windowFlags & FORM_NO_BORDER)) {
dc->drawSolidFilledRect(0, 0, rect.w, rect.h, bgColor);
if (!editMode)
dc->drawSolidRect(0, 0, rect.w, rect.h, 1, COLOR_THEME_SECONDARY2);
FormGroup::FormGroup(Window* parent, const rect_t& rect,
WindowFlags windowflags, LvglWidgetFactory* factory) :
FormField(parent, rect, windowflags)
{
lv_obj_set_style_bg_opa(lvobj, LV_OPA_TRANSP, LV_PART_MAIN);
if (!(windowFlags & (FORM_NO_BORDER | FORM_FORWARD_FOCUS))) {
lv_style_init(&border_style);
lv_style_set_border_width(&border_style, 2);
lv_style_set_border_color(&border_style, makeLvColor(COLOR_THEME_FOCUS));
lv_obj_add_style(lvobj, &border_style, LV_PART_MAIN | LV_STATE_FOCUSED);
if (!(windowFlags & FORM_BORDER_FOCUS_ONLY)) {
lv_style_init(&focus_border_style);
lv_style_set_border_width(&focus_border_style, 1);
lv_style_set_border_color(&focus_border_style, makeLvColor(COLOR_THEME_SECONDARY2));
lv_obj_add_style(lvobj, &focus_border_style, LV_PART_MAIN);
}
}
}
@@ -276,18 +298,6 @@ void FormGroup::onEvent(event_t event)
}
#endif
void FormGroup::paint(BitmapBuffer * dc)
{
if (!(windowFlags & (FORM_NO_BORDER | FORM_FORWARD_FOCUS))) {
if (!editMode && hasFocus()) {
dc->drawSolidRect(0, 0, rect.w, rect.h, 2, COLOR_THEME_FOCUS);
}
else if (!(windowFlags & FORM_BORDER_FOCUS_ONLY)) {
dc->drawSolidRect(0, 0, rect.w, rect.h, 1, COLOR_THEME_SECONDARY2);
}
}
}
#if defined(HARDWARE_KEYS)
void FormWindow::onEvent(event_t event)
{
+121 -171
View File
@@ -27,222 +27,172 @@ constexpr WindowFlags FORM_BORDER_FOCUS_ONLY = WINDOW_FLAGS_LAST << 3;
constexpr WindowFlags FORM_NO_BORDER = WINDOW_FLAGS_LAST << 4;
constexpr WindowFlags FORM_FLAGS_LAST = FORM_NO_BORDER;
class FormField: public Window
class FormField : public Window
{
public:
FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0, LvglWidgetFactory *factory = nullptr);
public:
FormField(Window *parent, const rect_t &rect, WindowFlags windowFlags = 0,
LcdFlags textFlags = 0, LvglWidgetFactory *factory = nullptr);
virtual void changeEnd(bool forceChanged = false)
{
if (changeHandler) {
changeHandler();
}
virtual void changeEnd(bool forceChanged = false)
{
if (changeHandler) {
changeHandler();
}
void setChangeHandler(std::function<void()> handler)
{
changeHandler = std::move(handler);
}
void setChangeHandler(std::function<void()> handler)
{
changeHandler = std::move(handler);
}
void setBackgroundHandler(std::function<uint32_t(FormField *field)> handler)
{
backgroundHandler = std::move(handler);
}
inline void setNextField(FormField *field) { next = field; }
inline void setPreviousField(FormField *field) { previous = field; }
inline FormField *getPreviousField() { return previous; }
inline FormField *getNextField() { return next; }
inline bool isEditMode() const { return editMode; }
virtual void setEditMode(bool newEditMode)
{
editMode = newEditMode;
if (lvobj != nullptr) {
lv_group_t *grp = (lv_group_t *)lv_obj_get_group(lvobj);
if (grp != nullptr) lv_group_set_editing(grp, editMode);
}
void setBackgroundHandler(std::function<uint32_t(FormField *field)> handler)
{
backgroundHandler = std::move(handler);
if (editMode && lvobj != nullptr) {
lv_obj_add_state(lvobj, LV_STATE_EDITED | LV_STATE_FOCUSED);
} else if (lvobj != nullptr) {
lv_obj_clear_state(lvobj, LV_STATE_EDITED);
}
invalidate();
}
inline void setNextField(FormField *field)
{
next = field;
}
void enable(bool value = true)
{
enabled = value;
invalidate();
}
inline void setPreviousField(FormField * field)
{
previous = field;
}
bool isEnabled() const { return enabled; }
void disable() { enable(false); }
inline FormField * getPreviousField()
{
return previous;
}
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT,
Window *from = nullptr) override;
inline FormField * getNextField()
{
return next;
}
void onFocusLost() override
{
setEditMode(false);
Window::onFocusLost();
}
inline bool isEditMode() const
{
return editMode;
}
virtual void setEditMode(bool newEditMode)
{
editMode = newEditMode;
if(lvobj != nullptr)
{
lv_group_t* grp = (lv_group_t*)lv_obj_get_group(lvobj);
if(grp != nullptr)
lv_group_set_editing(grp, editMode);
}
if (editMode && lvobj != nullptr) {
lv_obj_add_state(lvobj, LV_STATE_EDITED | LV_STATE_FOCUSED);
} else if (lvobj != nullptr) {
lv_obj_clear_state(lvobj, LV_STATE_EDITED);
}
invalidate();
}
void enable(bool value = true)
{
enabled = value;
invalidate();
}
bool isEnabled() const
{
return enabled;
}
void disable()
{
enable(false);
}
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override;
void onFocusLost() override
{
setEditMode(false);
Window::onFocusLost();
}
inline static void link(FormField * previous, FormField * next)
{
previous->setNextField(next);
next->setPreviousField(previous);
}
void paint(BitmapBuffer * dc) override;
inline static void link(FormField *previous, FormField *next)
{
previous->setNextField(next);
next->setPreviousField(previous);
}
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
void onEvent(event_t event) override;
#endif
protected:
FormField * next = nullptr;
FormField * previous = nullptr;
bool editMode = false;
bool enabled = true;
std::function<void()> changeHandler = nullptr;
std::function<uint32_t(FormField *)> backgroundHandler = nullptr;
protected:
FormField *next = nullptr;
FormField *previous = nullptr;
bool editMode = false;
bool enabled = true;
std::function<void()> changeHandler = nullptr;
std::function<uint32_t(FormField *)> backgroundHandler = nullptr;
};
class FormGroup: public FormField
class FormGroup : public FormField
{
public:
FormGroup(Window * parent, const rect_t & rect, WindowFlags windowflags = 0, LvglWidgetFactory *factory = nullptr) :
FormField(parent, rect, windowflags)
{
}
public:
FormGroup(Window *parent, const rect_t &rect, WindowFlags windowflags = 0,
LvglWidgetFactory *factory = nullptr);
#if defined(DEBUG_WINDOWS)
std::string getName() const override
{
return "FormGroup";
}
std::string getName() const override { return "FormGroup"; }
#endif
void clear()
{
Window::clear();
first = nullptr;
last = nullptr;
if (previous && (windowFlags & FORM_FORWARD_FOCUS)) {
previous->setNextField(this);
}
void clear()
{
Window::clear();
first = nullptr;
last = nullptr;
if (previous && (windowFlags & FORM_FORWARD_FOCUS)) {
previous->setNextField(this);
}
}
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override;
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT,
Window *from = nullptr) override;
virtual void addField(FormField * field, bool front = false);
virtual void addField(FormField *field, bool front = false);
virtual void removeField(FormField *field);
virtual void removeField(FormField * field);
void setFirstField(FormField *field) { first = field; }
void setLastField(FormField *field) { last = field; }
FormField *getFirstField() const { return first; }
FormField *getLastField() const { return last; }
void setFirstField(FormField * field)
{
first = field;
void setFocusOnFirstVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const
{
auto field = getFirstField();
while (field && !field->isInsideParentScrollingArea()) {
field = field->getNextField();
}
void setLastField(FormField * field)
{
last = field;
if (field) {
field->setFocus(flag);
}
}
FormField * getFirstField() const
{
return first;
void setFocusOnLastVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const
{
auto field = getLastField();
while (field && !field->isInsideParentScrollingArea()) {
field = field->getPreviousField();
}
FormField * getLastField() const
{
return last;
if (field) {
field->setFocus(flag);
}
}
void setFocusOnFirstVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const
{
auto field = getFirstField();
while (field && !field->isInsideParentScrollingArea()) {
field = field->getNextField();
}
if (field) {
field->setFocus(flag);
}
}
void setFocusOnLastVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const
{
auto field = getLastField();
while (field && !field->isInsideParentScrollingArea()) {
field = field->getPreviousField();
}
if (field) {
field->setFocus(flag);
}
}
protected:
FormField * first = nullptr;
FormField * last = nullptr;
protected:
FormField *first = nullptr;
FormField *last = nullptr;
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
void onEvent(event_t event) override;
#endif
void paint(BitmapBuffer * dc) override;
};
class FormWindow: public FormGroup
class FormWindow : public FormGroup
{
public:
FormWindow(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LvglWidgetFactory *factory = nullptr) :
public:
FormWindow(Window *parent, const rect_t &rect, WindowFlags windowFlags = 0,
LvglWidgetFactory *factory = nullptr) :
FormGroup(parent, rect, windowFlags, factory)
{
}
{
}
#if defined(DEBUG_WINDOWS)
std::string getName() const override
{
return "FormWindow";
}
std::string getName() const override { return "FormWindow"; }
#endif
protected:
void paint(BitmapBuffer *) override
{
}
protected:
void paint(BitmapBuffer *) override {}
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
void onEvent(event_t event) override;
#endif
};