1. basic changes to mirror libopnui window hierararchy to lvgl object hierarchy
2. basic scroll support 3. Basic layer support (still pretty broken), multiple screen support 4. Preliminary impelemntation of TextEdit using lvgl. 5. Preliminary implementation of StaticText using lvgl. 6. Preliminary implementation of TextButton using lvgl.
This commit is contained in:
committed by
Raphael Coeffic
parent
e538138ade
commit
6b70baf63a
+71
-33
@@ -76,44 +76,82 @@ void Button::checkEvents()
|
||||
checkHandler();
|
||||
}
|
||||
|
||||
|
||||
TextButton::TextButton(FormGroup* parent, const rect_t& rect, std::string text,
|
||||
std::function<uint8_t(void)> pressHandler,
|
||||
WindowFlags windowFlags,
|
||||
LcdFlags textFlags) :
|
||||
Button(parent, rect, std::move(pressHandler), windowFlags, textFlags),
|
||||
text(std::move(text))
|
||||
{
|
||||
if (lvobj != nullptr) {
|
||||
lv_obj_del(lvobj);
|
||||
}
|
||||
lvobj = lv_btn_create(parent->getLvObj());
|
||||
lv_obj_set_pos(lvobj, rect.x, rect.y); /*Set its position*/
|
||||
lv_obj_set_size(lvobj, rect.w, rect.h); /*Set its size*/
|
||||
setTextFlags(textFlags | COLOR_THEME_PRIMARY1);
|
||||
|
||||
#if 1
|
||||
auto color = COLOR_VAL(COLOR_THEME_PRIMARY2);
|
||||
auto r = GET_RED(color), g = GET_GREEN(color), b = GET_BLUE(color);
|
||||
|
||||
lv_style_init(&style_btn);
|
||||
lv_style_set_radius(&style_btn, 0);
|
||||
lv_obj_set_style_bg_color(lvobj, lv_color_make(r, g, b), LV_PART_MAIN);
|
||||
|
||||
lv_obj_add_style(lvobj, &style_btn,0);
|
||||
|
||||
label = lv_label_create(lvobj);
|
||||
lv_label_set_text(label, this->text.c_str());
|
||||
lv_obj_center(label);
|
||||
color = COLOR_VAL(this->getTextFlags());
|
||||
lv_obj_set_style_text_color(label, lv_color_make(GET_RED(color), GET_GREEN(color), GET_BLUE(color)), LV_PART_MAIN);
|
||||
#endif
|
||||
}
|
||||
|
||||
TextButton::~TextButton()
|
||||
{
|
||||
}
|
||||
|
||||
void TextButton::paint(BitmapBuffer * dc)
|
||||
{
|
||||
auto textColor = getTextFlags();
|
||||
auto bgColor = COLOR_THEME_SECONDARY2;
|
||||
// auto textColor = getTextFlags();
|
||||
// auto bgColor = COLOR_THEME_SECONDARY2;
|
||||
|
||||
if (bgColorHandler) {
|
||||
bgColor = bgColorHandler();
|
||||
} else if (checked()) {
|
||||
bgColor = COLOR_THEME_ACTIVE;
|
||||
} else if (hasFocus()) {
|
||||
bgColor = COLOR_THEME_FOCUS;
|
||||
textColor = COLOR_THEME_PRIMARY2;
|
||||
}
|
||||
// if (bgColorHandler) {
|
||||
// bgColor = bgColorHandler();
|
||||
// } else if (checked()) {
|
||||
// bgColor = COLOR_THEME_ACTIVE;
|
||||
// } else if (hasFocus()) {
|
||||
// bgColor = COLOR_THEME_FOCUS;
|
||||
// textColor = COLOR_THEME_PRIMARY2;
|
||||
// }
|
||||
|
||||
if (checked()) {
|
||||
if (hasFocus()) {
|
||||
dc->drawSolidRect(0, 0, rect.w, rect.h, 2, COLOR_THEME_FOCUS);
|
||||
dc->drawSolidFilledRect(3, 3, rect.w - 6, rect.h - 6, bgColor);
|
||||
} else {
|
||||
dc->drawSolidFilledRect(0, 0, rect.w, rect.h, bgColor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dc->drawSolidFilledRect(0, 0, rect.w, rect.h, bgColor);
|
||||
if (windowFlags & BUTTON_BACKGROUND) {
|
||||
if (hasFocus()) {
|
||||
textColor = COLOR_THEME_PRIMARY2;
|
||||
}
|
||||
} else if (hasFocus()) {
|
||||
dc->drawSolidRect(0, 0, rect.w, rect.h, 2, COLOR_THEME_FOCUS);
|
||||
}
|
||||
else {
|
||||
dc->drawSolidRect(0, 0, rect.w, rect.h, 1, COLOR_THEME_SECONDARY2);
|
||||
}
|
||||
}
|
||||
// if (checked()) {
|
||||
// if (hasFocus()) {
|
||||
// dc->drawSolidRect(0, 0, rect.w, rect.h, 2, COLOR_THEME_FOCUS);
|
||||
// dc->drawSolidFilledRect(3, 3, rect.w - 6, rect.h - 6, bgColor);
|
||||
// } else {
|
||||
// dc->drawSolidFilledRect(0, 0, rect.w, rect.h, bgColor);
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// dc->drawSolidFilledRect(0, 0, rect.w, rect.h, bgColor);
|
||||
// if (windowFlags & BUTTON_BACKGROUND) {
|
||||
// if (hasFocus()) {
|
||||
// textColor = COLOR_THEME_PRIMARY2;
|
||||
// }
|
||||
// } else if (hasFocus()) {
|
||||
// dc->drawSolidRect(0, 0, rect.w, rect.h, 2, COLOR_THEME_FOCUS);
|
||||
// }
|
||||
// else {
|
||||
// dc->drawSolidRect(0, 0, rect.w, rect.h, 1, COLOR_THEME_SECONDARY2);
|
||||
// }
|
||||
// }
|
||||
|
||||
dc->drawText(rect.w / 2, 1 + (rect.h - getFontHeight(textFlags)) / 2,
|
||||
text.c_str(), CENTERED | textColor);
|
||||
// dc->drawText(rect.w / 2, 1 + (rect.h - getFontHeight(textFlags)) / 2,
|
||||
// text.c_str(), CENTERED | textColor);
|
||||
}
|
||||
|
||||
void IconButton::paint(BitmapBuffer * dc)
|
||||
|
||||
+12
-9
@@ -87,19 +87,18 @@ class Button: public FormField
|
||||
void onPress();
|
||||
};
|
||||
|
||||
|
||||
extern void my_btn_event_cb(lv_event_t * e);
|
||||
|
||||
class TextButton: public Button
|
||||
{
|
||||
public:
|
||||
TextButton(FormGroup* parent, const rect_t& rect, std::string text,
|
||||
std::function<uint8_t(void)> pressHandler = nullptr,
|
||||
WindowFlags windowFlags = BUTTON_BACKGROUND | OPAQUE,
|
||||
LcdFlags textFlags = 0) :
|
||||
Button(parent, rect, std::move(pressHandler), windowFlags, textFlags),
|
||||
text(std::move(text))
|
||||
{
|
||||
setTextFlags(textFlags | COLOR_THEME_PRIMARY1);
|
||||
}
|
||||
|
||||
LcdFlags textFlags = 0);
|
||||
~TextButton();
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
@@ -111,6 +110,7 @@ class TextButton: public Button
|
||||
{
|
||||
if (value != text) {
|
||||
text = std::move(value);
|
||||
lv_label_set_text(label, text.c_str());
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
@@ -123,8 +123,11 @@ class TextButton: public Button
|
||||
void paint(BitmapBuffer* dc) override;
|
||||
|
||||
protected:
|
||||
std::string text;
|
||||
std::function<LcdFlags(void)> bgColorHandler = nullptr;
|
||||
lv_obj_t * label = nullptr;
|
||||
lv_style_t style_btn;
|
||||
|
||||
std::string text;
|
||||
std::function<LcdFlags(void)> bgColorHandler = nullptr;
|
||||
};
|
||||
|
||||
class IconButton: public Button
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@
|
||||
#include "bitmapbuffer.h"
|
||||
#include "libopenui_config.h"
|
||||
|
||||
FormField::FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags, LcdFlags textFlags) :
|
||||
Window(parent, rect, windowFlags, textFlags)
|
||||
FormField::FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags, LcdFlags textFlags, bool isScreen) :
|
||||
Window(parent, rect, windowFlags, textFlags, isScreen)
|
||||
{
|
||||
if (!(windowFlags & NO_FOCUS)) {
|
||||
auto * form = dynamic_cast<FormGroup *>(parent);
|
||||
|
||||
+4
-4
@@ -30,7 +30,7 @@ constexpr WindowFlags FORM_FLAGS_LAST = FORM_NO_BORDER;
|
||||
class FormField: public Window
|
||||
{
|
||||
public:
|
||||
FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0);
|
||||
FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0, bool isScreen = false);
|
||||
|
||||
virtual void changeEnd(bool forceChanged = false)
|
||||
{
|
||||
@@ -128,7 +128,7 @@ class FormField: public Window
|
||||
class FormGroup: public FormField
|
||||
{
|
||||
public:
|
||||
FormGroup(Window * parent, const rect_t & rect, WindowFlags windowflags = 0) :
|
||||
FormGroup(Window * parent, const rect_t & rect, WindowFlags windowflags = 0, bool isScreen = false) :
|
||||
FormField(parent, rect, windowflags)
|
||||
{
|
||||
}
|
||||
@@ -212,8 +212,8 @@ class FormGroup: public FormField
|
||||
class FormWindow: public FormGroup
|
||||
{
|
||||
public:
|
||||
FormWindow(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0) :
|
||||
FormGroup(parent, rect, windowFlags)
|
||||
FormWindow(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, bool isScreen = false) :
|
||||
FormGroup(parent, rect, windowFlags, isScreen)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+15
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "window.h"
|
||||
extern lv_obj_t * canvas;
|
||||
|
||||
class Layer
|
||||
{
|
||||
@@ -36,10 +37,20 @@ class Layer
|
||||
|
||||
static void push(Window * window)
|
||||
{
|
||||
// if (window->getLvObj()->parent != nullptr) {
|
||||
// TRACE("Layers must have lvgl parent to be null");
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!stack.empty()) {
|
||||
Layer & parentLayer = stack.back();
|
||||
parentLayer.focus = Window::getFocus();
|
||||
}
|
||||
|
||||
// layers are screens in lvgl
|
||||
lv_scr_load(window->getLvObj());
|
||||
lv_obj_set_parent(canvas, window->getLvObj());
|
||||
|
||||
stack.emplace_back(Layer(window));
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
@@ -55,6 +66,8 @@ class Layer
|
||||
if (stack.back().main == window) {
|
||||
stack.pop_back();
|
||||
const auto & back = stack.back();
|
||||
lv_obj_set_parent(canvas, back.main->getLvObj());
|
||||
lv_scr_load(back.main->getLvObj()); // load the screen.
|
||||
if (back.focus) {
|
||||
back.focus->setFocus(SET_FOCUS_DEFAULT);
|
||||
}
|
||||
@@ -63,6 +76,8 @@ class Layer
|
||||
// TODO it would be better to do it in reverse order
|
||||
for (auto it = stack.begin(); it != stack.end(); it++) {
|
||||
if (it->main == window) {
|
||||
lv_obj_set_parent(canvas, it->main->getLvObj());
|
||||
lv_scr_load(it->main->getLvObj());
|
||||
stack.erase(it);
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ class MainWindow: public Window
|
||||
protected:
|
||||
// singleton
|
||||
MainWindow():
|
||||
Window(nullptr, {0, 0, LCD_W, LCD_H}),
|
||||
Window(nullptr, {0, 0, LCD_W, LCD_H}, 0, 0, true),
|
||||
invalidatedRect(rect)
|
||||
{
|
||||
Layer::push(this);
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
#include "layer.h"
|
||||
|
||||
ModalWindow::ModalWindow(Window * parent, bool closeWhenClickOutside):
|
||||
Window(parent->getFullScreenWindow(), {0, 0, LCD_W, LCD_H}),
|
||||
Window(parent->getFullScreenWindow(), {0, 0, LCD_W, LCD_H}, 0, 0, true),
|
||||
closeWhenClickOutside(closeWhenClickOutside)
|
||||
{
|
||||
Layer::push(this);
|
||||
|
||||
+28
-28
@@ -22,35 +22,35 @@
|
||||
|
||||
void StaticText::paint(BitmapBuffer * dc)
|
||||
{
|
||||
if (bgColor) {
|
||||
dc->drawSolidFilledRect(0, 0, rect.w, rect.h, bgColor);
|
||||
}
|
||||
// if (bgColor) {
|
||||
// dc->drawSolidFilledRect(0, 0, rect.w, rect.h, bgColor);
|
||||
// }
|
||||
|
||||
coord_t x;
|
||||
if (textFlags & CENTERED)
|
||||
x = rect.w / 2;
|
||||
else if (textFlags & RIGHT)
|
||||
x = rect.w;
|
||||
else
|
||||
x = 0;
|
||||
// coord_t x;
|
||||
// if (textFlags & CENTERED)
|
||||
// x = rect.w / 2;
|
||||
// else if (textFlags & RIGHT)
|
||||
// x = rect.w;
|
||||
// else
|
||||
// x = 0;
|
||||
|
||||
coord_t y = (textFlags & VCENTERED) ? (rect.h - getFontHeight(textFlags)) / 2
|
||||
: FIELD_PADDING_TOP;
|
||||
// coord_t y = (textFlags & VCENTERED) ? (rect.h - getFontHeight(textFlags)) / 2
|
||||
// : FIELD_PADDING_TOP;
|
||||
|
||||
auto start = text.c_str();
|
||||
auto nextline = findNextLine(start);
|
||||
if (nextline) {
|
||||
auto current = start;
|
||||
do {
|
||||
dc->drawText(x, y,
|
||||
text.substr(current - start, nextline - current).c_str(),
|
||||
textFlags);
|
||||
current = nextline + 1;
|
||||
nextline = findNextLine(current);
|
||||
y += getFontHeight(textFlags) + 2;
|
||||
} while (nextline);
|
||||
dc->drawText(x, y, current, textFlags);
|
||||
} else {
|
||||
dc->drawText(x, y, start, textFlags);
|
||||
}
|
||||
// auto start = text.c_str();
|
||||
// auto nextline = findNextLine(start);
|
||||
// if (nextline) {
|
||||
// auto current = start;
|
||||
// do {
|
||||
// dc->drawText(x, y,
|
||||
// text.substr(current - start, nextline - current).c_str(),
|
||||
// textFlags);
|
||||
// current = nextline + 1;
|
||||
// nextline = findNextLine(current);
|
||||
// y += getFontHeight(textFlags) + 2;
|
||||
// } while (nextline);
|
||||
// dc->drawText(x, y, current, textFlags);
|
||||
// } else {
|
||||
// dc->drawText(x, y, start, textFlags);
|
||||
// }
|
||||
}
|
||||
|
||||
+16
-1
@@ -29,7 +29,18 @@ class StaticText: public Window
|
||||
Window(parent, rect, windowFlags, textFlags),
|
||||
text(std::move(text))
|
||||
{
|
||||
label = lv_label_create(lvobj);
|
||||
lv_label_set_text(label, this->text.c_str());
|
||||
|
||||
auto color = COLOR_VAL(textFlags);
|
||||
lv_obj_set_style_text_color(label, lv_color_make(GET_RED(color), GET_GREEN(color), GET_BLUE(color)), LV_PART_MAIN);
|
||||
if (textFlags & CENTERED)
|
||||
lv_obj_center(label);
|
||||
if (textFlags & FONT(BOLD)) {
|
||||
}
|
||||
|
||||
if (windowFlags & BUTTON_BACKGROUND) {
|
||||
lv_obj_set_style_bg_opa(lvobj, LV_OPA_100, LV_PART_MAIN);
|
||||
setBackgroundColor(COLOR_THEME_SECONDARY2);
|
||||
}
|
||||
}
|
||||
@@ -47,16 +58,20 @@ class StaticText: public Window
|
||||
{
|
||||
if (text != value) {
|
||||
text = std::move(value);
|
||||
invalidate();
|
||||
lv_label_set_text(label, this->text.c_str());
|
||||
// invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void setBackgroundColor(LcdFlags color)
|
||||
{
|
||||
bgColor = color;
|
||||
auto actualColor = COLOR_VAL(bgColor);
|
||||
lv_obj_set_style_bg_color(lvobj, lv_color_make(GET_RED(actualColor), GET_GREEN(actualColor), GET_BLUE(actualColor)), LV_PART_MAIN);
|
||||
}
|
||||
|
||||
protected:
|
||||
lv_obj_t *label = nullptr;
|
||||
std::string text;
|
||||
LcdFlags bgColor = 0;
|
||||
};
|
||||
|
||||
+108
-41
@@ -42,44 +42,111 @@
|
||||
#include "clipboard.h"
|
||||
#endif
|
||||
|
||||
|
||||
static void ta_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
if(code == LV_EVENT_CLICKED || code == LV_EVENT_FOCUSED) {
|
||||
/*Focus on the clicked text area*/
|
||||
if(kb != NULL)
|
||||
lv_keyboard_set_textarea(kb, ta);
|
||||
else {
|
||||
/*Create a keyboard*/
|
||||
kb = lv_keyboard_create(lv_scr_act());
|
||||
lv_obj_set_size(kb, LV_HOR_RES, LV_VER_RES / 2);
|
||||
lv_keyboard_set_textarea(kb, ta);
|
||||
}
|
||||
}
|
||||
else if (code == LV_EVENT_DEFOCUSED) {
|
||||
if (kb != nullptr) {
|
||||
lv_obj_del(kb);
|
||||
kb = nullptr;
|
||||
}
|
||||
}
|
||||
else if(code == LV_EVENT_READY) {
|
||||
LV_LOG_USER("Ready, current text: %s", lv_textarea_get_text(ta));
|
||||
}
|
||||
}
|
||||
|
||||
TextEdit::TextEdit(Window * parent, const rect_t & rect, char * value, uint8_t length,
|
||||
LcdFlags windowFlags, const char * _extra_chars) :
|
||||
FormField(parent, rect, windowFlags),
|
||||
value(value),
|
||||
length(length)
|
||||
{
|
||||
if (getLvObj() != nullptr) {
|
||||
lv_obj_del(lvobj);
|
||||
}
|
||||
|
||||
lvobj = lv_textarea_create(parent->getLvObj());
|
||||
lv_obj_add_event_cb(lvobj, ta_event_cb, LV_EVENT_ALL, NULL);
|
||||
lv_obj_set_pos(lvobj, rect.x, rect.y);
|
||||
lv_obj_set_size(lvobj, rect.w, rect.h);
|
||||
lv_obj_set_scrollbar_mode(lvobj, LV_SCROLLBAR_MODE_OFF);
|
||||
lv_obj_set_style_border_width(lvobj, 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_radius(lvobj, 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_top(lvobj, 2, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_bottom(lvobj, 2, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_left(lvobj, 4, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_right(lvobj, 4, LV_PART_MAIN);
|
||||
|
||||
|
||||
lv_textarea_set_password_mode(lvobj, false);
|
||||
lv_textarea_set_one_line(lvobj, true);
|
||||
lv_textarea_set_text(lvobj, value);
|
||||
lv_textarea_set_placeholder_text(lvobj, "---");
|
||||
lv_textarea_set_max_length(lvobj, length);
|
||||
|
||||
lv_obj_set_style_text_font(lvobj, &lv_font_montserrat_12, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_line_space(lvobj, 0, LV_PART_MAIN);
|
||||
|
||||
auto color = COLOR_VAL(COLOR_THEME_SECONDARY1);
|
||||
auto label = lv_textarea_get_label(lvobj);
|
||||
lv_obj_set_style_text_color(label, lv_color_make(GET_RED(color), GET_GREEN(color), GET_BLUE(color)), LV_PART_MAIN);
|
||||
|
||||
extra_chars = (_extra_chars) ? _extra_chars : extra_chars_default;
|
||||
}
|
||||
|
||||
|
||||
void TextEdit::paint(BitmapBuffer * dc)
|
||||
{
|
||||
FormField::paint(dc);
|
||||
// FormField::paint(dc);
|
||||
|
||||
if (editMode) {
|
||||
dc->drawSizedText(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, value, length,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
coord_t left = (cursorPos == 0 ? 0 : getTextWidth(value, cursorPos));
|
||||
#if defined(SOFTWARE_KEYBOARD)
|
||||
dc->drawSolidFilledRect(left + 2, 2, 2, height() - 4, COLOR_THEME_PRIMARY2);
|
||||
#else
|
||||
char s[] = {value[cursorPos], '\0'};
|
||||
dc->drawSolidFilledRect(FIELD_PADDING_LEFT + left - 1,
|
||||
FIELD_PADDING_TOP - 1, getTextWidth(s, 1) + 1,
|
||||
height() - 2, COLOR_THEME_PRIMARY2);
|
||||
dc->drawText(FIELD_PADDING_LEFT + left, FIELD_PADDING_TOP, s,
|
||||
COLOR_THEME_SECONDARY1);
|
||||
#endif
|
||||
} else {
|
||||
const char * displayedValue = value;
|
||||
LcdFlags textColor = COLOR_THEME_PRIMARY2;
|
||||
if (hasFocus()) {
|
||||
if (strlen(value) == 0) {
|
||||
displayedValue = "---";
|
||||
}
|
||||
textColor = COLOR_THEME_PRIMARY2;
|
||||
}
|
||||
else {
|
||||
if (strlen(value) == 0) {
|
||||
displayedValue = "---";
|
||||
textColor = COLOR_THEME_DISABLED;
|
||||
}
|
||||
else {
|
||||
textColor = COLOR_THEME_SECONDARY1;
|
||||
}
|
||||
}
|
||||
dc->drawSizedText(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, displayedValue, length, textColor);
|
||||
}
|
||||
// if (editMode) {
|
||||
// dc->drawSizedText(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, value, length,
|
||||
// COLOR_THEME_PRIMARY2);
|
||||
// coord_t left = (cursorPos == 0 ? 0 : getTextWidth(value, cursorPos));
|
||||
// #if defined(SOFTWARE_KEYBOARD)
|
||||
// dc->drawSolidFilledRect(left + 2, 2, 2, height() - 4, COLOR_THEME_PRIMARY2);
|
||||
// #else
|
||||
// char s[] = {value[cursorPos], '\0'};
|
||||
// dc->drawSolidFilledRect(FIELD_PADDING_LEFT + left - 1,
|
||||
// FIELD_PADDING_TOP - 1, getTextWidth(s, 1) + 1,
|
||||
// height() - 2, COLOR_THEME_PRIMARY2);
|
||||
// dc->drawText(FIELD_PADDING_LEFT + left, FIELD_PADDING_TOP, s,
|
||||
// COLOR_THEME_SECONDARY1);
|
||||
// #endif
|
||||
// } else {
|
||||
// const char * displayedValue = value;
|
||||
// LcdFlags textColor = COLOR_THEME_PRIMARY2;
|
||||
// if (hasFocus()) {
|
||||
// if (strlen(value) == 0) {
|
||||
// displayedValue = "---";
|
||||
// }
|
||||
// textColor = COLOR_THEME_PRIMARY2;
|
||||
// }
|
||||
// else {
|
||||
// if (strlen(value) == 0) {
|
||||
// displayedValue = "---";
|
||||
// textColor = COLOR_THEME_DISABLED;
|
||||
// }
|
||||
// else {
|
||||
// textColor = COLOR_THEME_SECONDARY1;
|
||||
// }
|
||||
// }
|
||||
// dc->drawSizedText(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, displayedValue, length, textColor);
|
||||
// }
|
||||
}
|
||||
|
||||
void TextEdit::trim()
|
||||
@@ -254,9 +321,9 @@ bool TextEdit::onTouchEnd(coord_t x, coord_t y)
|
||||
setFocus(SET_FOCUS_DEFAULT);
|
||||
}
|
||||
|
||||
#if defined(SOFTWARE_KEYBOARD)
|
||||
TextKeyboard::show(this);
|
||||
#endif
|
||||
// #if defined(SOFTWARE_KEYBOARD)
|
||||
// TextKeyboard::show(this);
|
||||
// #endif
|
||||
|
||||
coord_t rest = x;
|
||||
for (cursorPos = 0; cursorPos < length; cursorPos++) {
|
||||
@@ -276,9 +343,9 @@ bool TextEdit::onTouchEnd(coord_t x, coord_t y)
|
||||
|
||||
void TextEdit::onFocusLost()
|
||||
{
|
||||
#if defined(SOFTWARE_KEYBOARD)
|
||||
TextKeyboard::hide();
|
||||
#endif
|
||||
// #if defined(SOFTWARE_KEYBOARD)
|
||||
// TextKeyboard::hide();
|
||||
// #endif
|
||||
|
||||
changeEnd();
|
||||
FormField::onFocusLost();
|
||||
|
||||
+3
-7
@@ -23,17 +23,13 @@
|
||||
|
||||
const char extra_chars_default[] = ":;<=>";
|
||||
|
||||
static lv_obj_t *kb = nullptr;
|
||||
|
||||
class TextEdit : public FormField {
|
||||
friend class TextKeyboard;
|
||||
|
||||
public:
|
||||
TextEdit(Window * parent, const rect_t & rect, char * value, uint8_t length, LcdFlags windowFlags = 0, const char * _extra_chars = nullptr) :
|
||||
FormField(parent, rect, windowFlags),
|
||||
value(value),
|
||||
length(length)
|
||||
{
|
||||
extra_chars = (_extra_chars) ? _extra_chars : extra_chars_default;
|
||||
}
|
||||
TextEdit(Window * parent, const rect_t & rect, char * value, uint8_t length, LcdFlags windowFlags = 0, const char * _extra_chars = nullptr);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
|
||||
+36
-1
@@ -19,13 +19,29 @@
|
||||
|
||||
#include "window.h"
|
||||
#include "touch.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
Window * Window::focusWindow = nullptr;
|
||||
Window * Window::slidingWindow = nullptr;
|
||||
Window * Window::capturedWindow = nullptr;
|
||||
std::list<Window *> Window::trash;
|
||||
|
||||
Window::Window(Window * parent, const rect_t & rect, WindowFlags windowFlags, LcdFlags textFlags):
|
||||
|
||||
static void window_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
Window *window = (Window *) lv_event_get_user_data(e);
|
||||
if (code == LV_EVENT_GET_SELF_SIZE) {
|
||||
lv_point_t * p = (lv_point_t *)lv_event_get_param(e);
|
||||
if (p->x >= 0) {
|
||||
p->x = window->getInnerWidth();
|
||||
}
|
||||
if (p->y >= 0)
|
||||
p->y = window->getInnerHeight();
|
||||
}
|
||||
}
|
||||
|
||||
Window::Window(Window * parent, const rect_t & rect, WindowFlags windowFlags, LcdFlags textFlags, bool isScreen) :
|
||||
parent(parent),
|
||||
rect(rect),
|
||||
innerWidth(rect.w),
|
||||
@@ -33,6 +49,18 @@ Window::Window(Window * parent, const rect_t & rect, WindowFlags windowFlags, Lc
|
||||
windowFlags(windowFlags),
|
||||
textFlags(textFlags)
|
||||
{
|
||||
lvobj = lv_obj_create(isScreen ? nullptr : parent != nullptr ? parent->lvobj : nullptr);
|
||||
lv_obj_set_pos(lvobj, rect.x, rect.y);
|
||||
lv_obj_set_size(lvobj, rect.w, rect.h);
|
||||
|
||||
lv_obj_set_style_pad_all(lvobj, 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_opa(lvobj, LV_OPA_TRANSP, LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(lvobj, 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_radius(lvobj, 0, LV_PART_MAIN);
|
||||
lv_obj_set_scrollbar_mode(lvobj, LV_SCROLLBAR_MODE_OFF);
|
||||
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_SCROLL_ELASTIC);
|
||||
lv_obj_add_event_cb(lvobj, window_event_cb, LV_EVENT_ALL, this);
|
||||
|
||||
if (parent) {
|
||||
parent->addChild(this, windowFlags & PUSH_FRONT);
|
||||
if (!(windowFlags & TRANSPARENT)) {
|
||||
@@ -44,6 +72,11 @@ Window::Window(Window * parent, const rect_t & rect, WindowFlags windowFlags, Lc
|
||||
Window::~Window()
|
||||
{
|
||||
TRACE_WINDOWS("Destroy %p %s", this, getWindowDebugString().c_str());
|
||||
if (lvobj != nullptr)
|
||||
{
|
||||
lv_obj_del(lvobj);
|
||||
lvobj = nullptr;
|
||||
}
|
||||
|
||||
if (focusWindow == this) {
|
||||
focusWindow = nullptr;
|
||||
@@ -153,6 +186,7 @@ void Window::setScrollPositionX(coord_t value)
|
||||
auto newScrollPosition = max<coord_t>(0, min<coord_t>(innerWidth - width(), value));
|
||||
if (newScrollPosition != scrollPositionX) {
|
||||
scrollPositionX = newScrollPosition;
|
||||
lv_obj_scroll_to_x(lvobj, scrollPositionX, LV_ANIM_OFF);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
@@ -167,6 +201,7 @@ void Window::setScrollPositionY(coord_t value)
|
||||
|
||||
if (newScrollPosition != scrollPositionY) {
|
||||
scrollPositionY = newScrollPosition;
|
||||
lv_obj_scroll_to_y(lvobj, value, LV_ANIM_OFF);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -30,6 +30,7 @@
|
||||
#include "libopenui_defines.h"
|
||||
#include "libopenui_helpers.h"
|
||||
#include "libopenui_config.h"
|
||||
#include "../../lvgl/src/lvgl.h"
|
||||
|
||||
typedef uint32_t WindowFlags;
|
||||
|
||||
@@ -63,7 +64,7 @@ class Window
|
||||
friend class GridLayout;
|
||||
|
||||
public:
|
||||
Window(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0);
|
||||
Window(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0, bool isScreen = false);
|
||||
|
||||
virtual ~Window();
|
||||
|
||||
@@ -384,7 +385,10 @@ class Window
|
||||
return _deleted;
|
||||
}
|
||||
|
||||
inline lv_obj_t *getLvObj() { return lvobj; }
|
||||
|
||||
protected:
|
||||
lv_obj_t *lvobj = nullptr;
|
||||
Window * parent;
|
||||
std::list<Window *> children;
|
||||
rect_t rect;
|
||||
|
||||
Reference in New Issue
Block a user