Finished Calendar widget and improved properties

This commit is contained in:
CURTLab 2020-07-30 15:54:45 +02:00
parent 875bf7fe92
commit ce5238a956
17 changed files with 552 additions and 245 deletions

View File

@ -67,6 +67,7 @@ SOURCES += \
properties/LVGLPropertyAssignTextArea.cpp \ properties/LVGLPropertyAssignTextArea.cpp \
properties/LVGLPropertyColor.cpp \ properties/LVGLPropertyColor.cpp \
properties/LVGLPropertyDate.cpp \ properties/LVGLPropertyDate.cpp \
properties/LVGLPropertyDateList.cpp \
properties/LVGLPropertyFlags.cpp \ properties/LVGLPropertyFlags.cpp \
properties/LVGLPropertyGeometry.cpp \ properties/LVGLPropertyGeometry.cpp \
properties/LVGLPropertyImage.cpp \ properties/LVGLPropertyImage.cpp \
@ -131,6 +132,7 @@ HEADERS += \
properties/LVGLPropertyAssignTextArea.h \ properties/LVGLPropertyAssignTextArea.h \
properties/LVGLPropertyColor.h \ properties/LVGLPropertyColor.h \
properties/LVGLPropertyDate.h \ properties/LVGLPropertyDate.h \
properties/LVGLPropertyDateList.h \
properties/LVGLPropertyFlags.h \ properties/LVGLPropertyFlags.h \
properties/LVGLPropertyGeometry.h \ properties/LVGLPropertyGeometry.h \
properties/LVGLPropertyImage.h \ properties/LVGLPropertyImage.h \

View File

@ -233,7 +233,7 @@ bool LVGLProject::exportCode(const QString &path) const
stream << "\n"; stream << "\n";
for (LVGLObject *o:objects) { for (LVGLObject *o:objects) {
QString ifdef = o->widgetClass()->className().toUpper().insert(3, "USE_"); QString ifdef = o->widgetClass()->className().toUpper().insert(3, "USE_");
stream << "#ifdef " << ifdef <<"\n"; stream << "#if " << ifdef <<"\n";
for (int i = 0; i < o->widgetClass()->styles().size(); ++i) { for (int i = 0; i < o->widgetClass()->styles().size(); ++i) {
if (o->hasCustomStyle(i)) { if (o->hasCustomStyle(i)) {

View File

@ -8,152 +8,6 @@
#include "LVGLObject.h" #include "LVGLObject.h"
/*void LVGLProperty::set(LVGLObject *obj, QVariant value) const
{
if (functionSet == "lv_obj_set_x")
lv_obj_set_x(obj, static_cast<lv_coord_t>(value.toInt()));
else if (functionSet == "lv_obj_set_y")
lv_obj_set_y(obj, static_cast<lv_coord_t>(value.toInt()));
else if (functionSet == "lv_obj_set_width")
lv_obj_set_width(obj, static_cast<lv_coord_t>(value.toInt()));
else if (functionSet == "lv_obj_set_height")
lv_obj_set_height(obj, static_cast<lv_coord_t>(value.toInt()));
else if (functionSet == "lv_btn_set_toggle")
lv_btn_set_toggle(obj, value.toBool());
else if (functionSet == "lv_img_set_offset_x")
lv_img_set_offset_x(obj, static_cast<lv_coord_t>(value.toInt()));
else if (functionSet == "lv_img_set_offset_y")
lv_img_set_offset_y(obj, static_cast<lv_coord_t>(value.toInt()));
else if (functionSet == "lv_img_set_auto_size")
lv_img_set_auto_size(obj, value.toBool());
else if (functionSet == "lv_img_set_src") {
lv_img_set_src(obj, lvgl.image(value.toString()));
} else if (functionSet == "lv_label_set_text")
lv_label_set_text(obj, qPrintable(value.toString()));
else if (functionSet == "lv_label_set_align") {
const QString align = value.toString();
if (align == "LV_LABEL_ALIGN_LEFT")
lv_label_set_align(obj, LV_LABEL_ALIGN_LEFT);
else if (align == "LV_LABEL_ALIGN_CENTER")
lv_label_set_align(obj, LV_LABEL_ALIGN_CENTER);
else if (align == "LV_LABEL_ALIGN_RIGHT")
lv_label_set_align(obj, LV_LABEL_ALIGN_RIGHT);
} else if (functionSet == "lv_label_set_long_mode") {
const QString mode = value.toString();
if (mode == "LV_LABEL_LONG_EXPAND")
lv_label_set_long_mode(obj, LV_LABEL_LONG_EXPAND);
else if (mode == "LV_LABEL_LONG_BREAK")
lv_label_set_long_mode(obj, LV_LABEL_LONG_BREAK);
else if (mode == "LV_LABEL_LONG_DOT")
lv_label_set_long_mode(obj, LV_LABEL_LONG_DOT);
else if (mode == "LV_LABEL_LONG_SROLL")
lv_label_set_long_mode(obj, LV_LABEL_LONG_SROLL);
else if (mode == "LV_LABEL_LONG_SROLL_CIRC")
lv_label_set_long_mode(obj, LV_LABEL_LONG_SROLL_CIRC);
else if (mode == "LV_LABEL_LONG_CROP")
lv_label_set_long_mode(obj, LV_LABEL_LONG_CROP);
} else if (functionSet == "lv_slider_set_value")
lv_slider_set_value(obj, static_cast<int16_t>(value.toInt()), LV_ANIM_OFF);
else if (functionSet == "lv_slider_set_min_value")
lv_slider_set_range(obj, static_cast<int16_t>(value.toInt()), lv_slider_get_max_value(obj));
else if (functionSet == "lv_slider_set_max_value")
lv_slider_set_range(obj, lv_slider_get_min_value(obj), static_cast<int16_t>(value.toInt()));
else if (functionSet == "lv_slider_set_knob_in")
lv_slider_set_knob_in(obj, value.toBool());
else if (functionSet == "lv_cb_set_text")
lv_cb_set_text(obj, qPrintable(value.toString()));
else if (functionSet == "lv_cb_set_checked")
lv_cb_set_checked(obj, value.toBool());
else if (functionSet == "lv_cb_set_inactive")
lv_btn_set_state(obj, value.toBool() ? LV_BTN_STATE_INA : (lv_cb_is_checked(obj) ? LV_BTN_STATE_TGL_REL : LV_BTN_STATE_REL));
else if (functionSet == "lv_sw_set_state") {
if (value.toBool())
lv_sw_on(obj, LV_ANIM_OFF);
else
lv_sw_off(obj, LV_ANIM_OFF);
} else if (functionSet == "lv_bar_set_value")
lv_bar_set_value(obj, static_cast<int16_t>(value.toInt()), LV_ANIM_OFF);
else if (functionSet == "lv_bar_set_min_value")
lv_bar_set_range(obj, static_cast<int16_t>(value.toInt()), lv_bar_get_max_value(obj));
else if (functionSet == "lv_bar_set_max_value")
lv_bar_set_range(obj, lv_bar_get_min_value(obj), static_cast<int16_t>(value.toInt()));
}
QVariant LVGLProperty::get(LVGLObject *obj) const
{
if (functionGet == "lv_obj_get_x")
return QVariant(lv_obj_get_x(obj));
else if (functionGet == "lv_obj_get_y")
return QVariant(lv_obj_get_y(obj));
else if (functionGet == "lv_obj_get_width")
return QVariant(lv_obj_get_width(obj));
else if (functionGet == "lv_obj_get_height")
return QVariant(lv_obj_get_height(obj));
else if (functionGet == "lv_btn_get_toggle")
return QVariant(lv_btn_get_toggle(obj));
else if (functionGet == "lv_img_get_offset_x")
return QVariant(lv_img_get_offset_x(obj));
else if (functionGet == "lv_img_get_offset_y")
return QVariant(lv_img_get_offset_y(obj));
else if (functionGet == "lv_img_get_auto_size")
return QVariant(lv_img_get_auto_size(obj));
else if (functionGet == "lv_img_get_auto_size")
return QVariant(lv_img_get_auto_size(obj));
else if (functionGet == "lv_img_get_src") {
const lv_img_dsc_t *dsc = reinterpret_cast<const lv_img_dsc_t*>(lv_img_get_src(obj));
if (dsc)
return lvgl.nameByImage(const_cast<lv_img_dsc_t *>(dsc));
else
return "default";
} else if (functionGet == "lv_label_get_text")
return QVariant(QString(lv_label_get_text(obj)));
else if (functionGet == "lv_label_get_align") {
const auto align = lv_label_get_align(obj);
if (align == LV_LABEL_ALIGN_LEFT)
return "LV_LABEL_ALIGN_LEFT";
else if (align == LV_LABEL_ALIGN_CENTER)
return "LV_LABEL_ALIGN_CENTER";
else if (align == LV_LABEL_ALIGN_RIGHT)
return "LV_LABEL_ALIGN_RIGHT";
} else if (functionGet == "lv_label_get_long_mode") {
const auto mode = lv_label_get_long_mode(obj);
if (mode == LV_LABEL_LONG_EXPAND)
return "LV_LABEL_LONG_EXPAND";
else if (mode == LV_LABEL_LONG_BREAK)
return "LV_LABEL_LONG_BREAK";
else if (mode == LV_LABEL_LONG_DOT)
return "LV_LABEL_LONG_DOT";
else if (mode == LV_LABEL_LONG_SROLL)
return "LV_LABEL_LONG_SROLL";
else if (mode == LV_LABEL_LONG_SROLL_CIRC)
return "LV_LABEL_LONG_SROLL_CIRC";
else if (mode == LV_LABEL_LONG_CROP)
return "LV_LABEL_LONG_CROP";
} else if (functionGet == "lv_slider_get_value")
return QVariant(lv_slider_get_value(obj));
else if (functionGet == "lv_slider_get_min_value")
return QVariant(lv_slider_get_min_value(obj));
else if (functionGet == "lv_slider_get_max_value")
return QVariant(lv_slider_get_max_value(obj));
else if (functionGet == "lv_slider_get_knob_in")
return QVariant(lv_slider_get_knob_in(obj));
else if (functionGet == "lv_cb_get_text")
return QVariant(lv_cb_get_text(obj));
else if (functionGet == "lv_cb_is_checked")
return QVariant(lv_cb_is_checked(obj));
else if (functionGet == "lv_cb_is_inactive")
return QVariant(!lv_cb_is_inactive(obj));
else if (functionGet == "lv_sw_get_state")
return QVariant(lv_sw_get_state(obj));
else if (functionGet == "lv_bar_get_value")
return QVariant(lv_bar_get_value(obj));
else if (functionGet == "lv_bar_get_min_value")
return QVariant(lv_bar_get_min_value(obj));
else if (functionGet == "lv_bar_get_max_value")
return QVariant(lv_bar_get_max_value(obj));
return QVariant();
}*/
LVGLProperty::LVGLProperty(LVGLProperty *parent) LVGLProperty::LVGLProperty(LVGLProperty *parent)
: m_parent(parent) : m_parent(parent)
{ {

View File

@ -189,8 +189,8 @@ class LVGLPropertyBool : public LVGLPropertyType<bool>
{ {
public: public:
LVGLPropertyBool(QString title = "", QString functionName = "", LVGLProperty *parent = nullptr); LVGLPropertyBool(QString title = "", QString functionName = "", LVGLProperty *parent = nullptr);
LVGLPropertyBool(QString title, LVGLPropertyBool(QString title, QString functionName,
QString functionName, std::function<void(lv_obj_t*, bool)> setter, std::function<void(lv_obj_t*, bool)> setter,
std::function<bool(lv_obj_t*)> getter, std::function<bool(lv_obj_t*)> getter,
LVGLProperty *parent = nullptr); LVGLProperty *parent = nullptr);
@ -218,10 +218,10 @@ class LVGLPropertyString : public LVGLPropertyType<QString>
{ {
public: public:
LVGLPropertyString(QString title = "", QString functionName = "", LVGLProperty *parent = nullptr); LVGLPropertyString(QString title = "", QString functionName = "", LVGLProperty *parent = nullptr);
LVGLPropertyString(QString title, LVGLPropertyString(QString title, QString functionName,
QString functionName, std::function<void(lv_obj_t*, const char*)> setter, std::function<void(lv_obj_t*, const char*)> setter,
std::function<const char*(lv_obj_t*)> getter, std::function<const char*(lv_obj_t*)> getter,
LVGLProperty *parent = nullptr); LVGLProperty *parent = nullptr);
QString name() const override; QString name() const override;

View File

@ -83,8 +83,14 @@ QVariant LVGLPropertyModel::data(const QModelIndex &index, int role) const
if (index.column() == 0) { if (index.column() == 0) {
return prop->name(); return prop->name();
} else if (index.column() == 1) { } else if (index.column() == 1) {
auto p = prop->value(m_obj); QVariant val = prop->value(m_obj);
return p; if (val.type() != QVariant::List)
return val;
QStringList ret;
for (const QVariant &v:val.toList())
ret << v.toString();
return "[" + ret.join(",") + "]";
} }
} else if (role == (Qt::UserRole + 1)) { } else if (role == (Qt::UserRole + 1)) {
LVGLObjectCast cast; LVGLObjectCast cast;

View File

@ -2,8 +2,18 @@
#include <QDateTimeEdit> #include <QDateTimeEdit>
LVGLPropertyDate::LVGLPropertyDate(LVGLProperty *parent) #include "LVGLObject.h"
LVGLPropertyDate::LVGLPropertyDate(QString title, QString functionName,
std::function<void(lv_obj_t*, lv_calendar_date_t*)> setter,
std::function<lv_calendar_date_t*(lv_obj_t*)> getter,
LVGLProperty *parent)
: LVGLProperty(parent) : LVGLProperty(parent)
, m_widget(nullptr)
, m_title(title)
, m_functionName(functionName)
, m_setter(setter)
, m_getter(getter)
{ {
} }
@ -51,3 +61,30 @@ void LVGLPropertyDate::setValue(LVGLObject *obj, QVariant value)
d.year = static_cast<uint16_t>(date.year()); d.year = static_cast<uint16_t>(date.year());
set(obj, &d); set(obj, &d);
} }
QString LVGLPropertyDate::name() const
{
return m_title;
}
QStringList LVGLPropertyDate::function(LVGLObject *obj) const
{
if (m_functionName.isEmpty())
return {};
QStringList ret;
lv_calendar_date_t *data = get(obj);
const QString varName = QString("date_%1_%2").arg(m_title.toLower().replace(' ', '_')).arg(obj->codeName());
ret << QString("lv_calendar_date_t %1 = {.year = %2, .month = %3, .day = %4};").arg(varName).arg(data->year).arg(data->month).arg(data->day);
ret << QString("%1(%2, &%3);").arg(m_functionName).arg(obj->codeName()).arg(varName);
return ret;
}
lv_calendar_date_t *LVGLPropertyDate::get(LVGLObject *obj) const
{
return m_getter(obj->obj());
}
void LVGLPropertyDate::set(LVGLObject *obj, lv_calendar_date_t *value)
{
m_setter(obj->obj(), value);
}

View File

@ -6,21 +6,31 @@
class LVGLPropertyDate : public LVGLProperty class LVGLPropertyDate : public LVGLProperty
{ {
public: public:
LVGLPropertyDate(LVGLProperty *parent = nullptr); LVGLPropertyDate(QString title, QString functionName,
std::function<void(lv_obj_t*, lv_calendar_date_t*)> setter,
std::function<lv_calendar_date_t*(lv_obj_t*)> getter,
LVGLProperty *parent = nullptr);
bool hasEditor() const; bool hasEditor() const override;
QWidget *editor(QWidget *parent); QWidget *editor(QWidget *parent) override;
void updateEditor(LVGLObject *obj); void updateEditor(LVGLObject *obj) override;
void updateWidget(LVGLObject *obj); void updateWidget(LVGLObject *obj) override;
QVariant value(LVGLObject *obj) const; QVariant value(LVGLObject *obj) const override;
void setValue(LVGLObject *obj, QVariant value); void setValue(LVGLObject *obj, QVariant value) override;
QString name() const override;
QStringList function(LVGLObject *obj) const override;
protected: protected:
virtual lv_calendar_date_t *get(LVGLObject *obj) const = 0; virtual lv_calendar_date_t *get(LVGLObject *obj) const;
virtual void set(LVGLObject *obj, lv_calendar_date_t *value) = 0; virtual void set(LVGLObject *obj, lv_calendar_date_t *value);
class QDateTimeEdit *m_widget; class QDateTimeEdit *m_widget;
QString m_title;
QString m_functionName;
std::function<void(lv_obj_t*, lv_calendar_date_t*)> m_setter;
std::function<lv_calendar_date_t*(lv_obj_t*)> m_getter;
}; };

View File

@ -0,0 +1,253 @@
#include "LVGLPropertyDateList.h"
#include <QDateTimeEdit>
#include <QTreeWidget>
#include <QToolButton>
#include <QDialogButtonBox>
#include <QVBoxLayout>
#include <QDialog>
#include <QJsonArray>
#include <QDate>
#include <QStyledItemDelegate>
#include "LVGLObject.h"
class LVGLPropertyDateListDelegate : public QStyledItemDelegate
{
public:
inline QWidget *createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
{
Q_UNUSED(option)
if (index.isValid()) {
QDateTimeEdit *widget = new QDateTimeEdit(parent);
//widget->setCalendarPopup(true);
widget->setDisplayFormat("dd.MM.yyyy");
return widget;
}
return nullptr;
}
inline void setEditorData(QWidget* editor, const QModelIndex& index) const override
{
if (index.isValid()) {
QDateTimeEdit *widget = qobject_cast<QDateTimeEdit*>(editor);
widget->setDate(index.data().toDate());
}
}
inline void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
{
if (index.isValid()) {
QDateTimeEdit *widget = qobject_cast<QDateTimeEdit*>(editor);
model->setData(index, widget->date());
}
}
};
class LVGLPropertyDateListDialog : public QDialog
{
public:
inline LVGLPropertyDateListDialog(QWidget *parent = nullptr) : QDialog(parent)
{
m_list = new QTreeWidget(this);
m_list->setColumnCount(1);
m_list->setHeaderLabels(QStringList() << "Date");
m_list->setItemDelegate(new LVGLPropertyDateListDelegate);
QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok |
QDialogButtonBox::Cancel);
QToolButton *add = new QToolButton();
add->setIcon(QIcon(":/icons/add.png"));
add->setIconSize(QSize(24, 24));
QToolButton *rem = new QToolButton();
rem->setIcon(QIcon(":/icons/delete.png"));
rem->setIconSize(QSize(24, 24));
box->addButton(add, QDialogButtonBox::ApplyRole);
box->addButton(rem, QDialogButtonBox::ApplyRole);
connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(box, &QDialogButtonBox::clicked, [this,add,rem](QAbstractButton *b) {
if (b == add) {
QTreeWidgetItem *item = new QTreeWidgetItem;
item->setData(0, Qt::DisplayRole, QDate::currentDate());
item->setFlags(item->flags() | Qt::ItemIsEditable);
m_list->addTopLevelItem(item);
} else if (b == rem) {
int index = m_list->indexOfTopLevelItem(m_list->currentItem());
m_list->takeTopLevelItem(index);
}
});
QVBoxLayout *layout1 = new QVBoxLayout;
layout1->addWidget(m_list);
layout1->addWidget(box);
setLayout(layout1);
}
inline QVariant get() const {
QVariantList ret;
for (int i = 0; i < m_list->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = m_list->topLevelItem(i);
ret << item->data(0, Qt::DisplayRole);
}
return ret;
}
inline void set(QVariant value) {
m_list->clear();
if (value.type() != QVariant::List)
return;
QVariantList list = value.toList();
for (const QVariant &p:list) {
if (p.type() != QVariant::Date)
continue;
QTreeWidgetItem *item = new QTreeWidgetItem;
item->setData(0, Qt::DisplayRole, p);
item->setFlags(item->flags() | Qt::ItemIsEditable);
m_list->addTopLevelItem(item);
}
}
private:
QTreeWidget *m_list;
};
LVGLPropertyDateList::LVGLPropertyDateList(QString title, QString functionName,
std::function<void (lv_obj_t *, lv_calendar_date_t *, uint16_t)> setter,
std::function<lv_calendar_date_t *(lv_obj_t *)> getter,
std::function<uint16_t(lv_obj_t *)> count,
LVGLProperty *parent)
: LVGLProperty(parent)
, m_widget(nullptr)
, m_title(title)
, m_functionName(functionName)
, m_setter(setter)
, m_getter(getter)
, m_count(count)
{
}
LVGLPropertyDateList::~LVGLPropertyDateList()
{
for (lv_calendar_date_t *d:m_garbageCollector)
delete [] d;
}
bool LVGLPropertyDateList::hasEditor() const
{
return true;
}
QWidget *LVGLPropertyDateList::editor(QWidget *parent)
{
m_widget = new LVGLPropertyDateListDialog(parent);
return m_widget;
}
void LVGLPropertyDateList::updateEditor(LVGLObject *obj)
{
m_widget->set(value(obj));
}
void LVGLPropertyDateList::updateWidget(LVGLObject *obj)
{
if (m_widget->result() == QDialog::Accepted)
setValue(obj, m_widget->get());
}
QVariant LVGLPropertyDateList::value(LVGLObject *obj) const
{
const uint16_t num = count(obj);
if (num == 0)
return "None";
const lv_calendar_date_t *items = get(obj);
QVariantList ret;
for (uint16_t i = 0; i < num; ++i)
ret << QDate(items[i].year, items[i].month, items[i].day);
return ret;
}
void LVGLPropertyDateList::setValue(LVGLObject *obj, QVariant value)
{
if (value.type() != QVariant::List)
return;
QVariantList list = value.toList();
QVector<lv_calendar_date_t> dateVector;
for (const QVariant &p:list) {
QDate d = p.toDate();
if (!d.isValid() || d.isNull())
continue;
lv_calendar_date_t data{static_cast<uint16_t>(d.year()),
static_cast<int8_t>(d.month()),
static_cast<int8_t>(d.day())};
dateVector << data;
}
// in order to not allocate unneeded memory
if (dateVector.isEmpty())
return;
// Due to the doc: ONLY A POINTER WILL BE SAVED! CANT BE LOCAL ARRAY.
lv_calendar_date_t *data = new lv_calendar_date_t[dateVector.size()];
memcpy(data, dateVector.data(), dateVector.size() * sizeof(lv_calendar_date_t));
m_garbageCollector << data;
set(obj, data, dateVector.size());
}
QJsonValue LVGLPropertyDateList::toJson(LVGLObject *obj) const
{
QJsonArray ret;
const uint16_t num = count(obj);
if (num == 0)
return {};
const lv_calendar_date_t *items = get(obj);
for (uint16_t i = 0; i < num; ++i)
ret << QJsonValue::fromVariant(QDate(items[i].year, items[i].month, items[i].day));
return ret;
}
QString LVGLPropertyDateList::name() const
{
return m_title;
}
QStringList LVGLPropertyDateList::function(LVGLObject *obj) const
{
const uint16_t num = count(obj);
if (m_functionName.isEmpty() || (num == 0))
return {};
QStringList ret;
const QString varName = QString("highlihted_days_%1_%2").arg(m_title.toLower().replace(' ', '_')).arg(obj->codeName());
QStringList items;
const lv_calendar_date_t *dates = get(obj);
for (uint16_t i = 0; i < num; ++i)
items << QString("{.year = %2, .month = %3, .day = %4}").arg(dates[i].year).arg(dates[i].month).arg(dates[i].day);
ret << QString("static lv_calendar_date_t %1[%2] = {%3};").arg(varName).arg(num).arg(items.join(","));
ret << QString("%1(%2, %3, %4);").arg(m_functionName).arg(obj->codeName()).arg(varName).arg(num);
return ret;
}
uint16_t LVGLPropertyDateList::count(LVGLObject *obj) const
{
return m_count(obj->obj());
}
lv_calendar_date_t *LVGLPropertyDateList::get(LVGLObject *obj) const
{
return m_getter(obj->obj());
}
void LVGLPropertyDateList::set(LVGLObject *obj, lv_calendar_date_t *value, uint16_t num)
{
m_setter(obj->obj(), value, num);
}

View File

@ -0,0 +1,46 @@
#ifndef LVGLPROPERTYDATELIST_H
#define LVGLPROPERTYDATELIST_H
#include "LVGLProperty.h"
class LVGLPropertyDateList : public LVGLProperty
{
public:
LVGLPropertyDateList(QString title, QString functionName,
std::function<void(lv_obj_t*, lv_calendar_date_t*,uint16_t)> setter,
std::function<lv_calendar_date_t*(lv_obj_t*)> getter,
std::function<uint16_t(lv_obj_t*)> count,
LVGLProperty *parent = nullptr);
~LVGLPropertyDateList();
bool hasEditor() const override;
QWidget *editor(QWidget *parent) override;
void updateEditor(LVGLObject *obj) override;
void updateWidget(LVGLObject *obj) override;
QVariant value(LVGLObject *obj) const override;
void setValue(LVGLObject *obj, QVariant value) override;
QJsonValue toJson(LVGLObject *obj) const override;
QString name() const override;
QStringList function(LVGLObject *obj) const override;
protected:
class LVGLPropertyDateListDialog *m_widget;
virtual uint16_t count(LVGLObject *obj) const;
virtual lv_calendar_date_t *get(LVGLObject *obj) const;
virtual void set(LVGLObject *obj, lv_calendar_date_t *value, uint16_t num);
QString m_title;
QString m_functionName;
std::function<void(lv_obj_t*, lv_calendar_date_t*,uint16_t)> m_setter;
std::function<lv_calendar_date_t*(lv_obj_t*)> m_getter;
std::function<uint16_t(lv_obj_t*)> m_count;
QList<lv_calendar_date_t*> m_garbageCollector;
};
#endif // LVGLPROPERTYDATELIST_H

View File

@ -8,7 +8,6 @@ public:
inline LVGLPropertyMin(LVGLProperty *p) : LVGLPropertyInt(INT16_MIN, INT16_MAX, p) {} inline LVGLPropertyMin(LVGLProperty *p) : LVGLPropertyInt(INT16_MIN, INT16_MAX, p) {}
inline QString name() const override { return "Min"; } inline QString name() const override { return "Min"; }
protected:
inline int get(LVGLObject *obj) const override { inline int get(LVGLObject *obj) const override {
const LVGLPropertyRange *r = reinterpret_cast<const LVGLPropertyRange *>(m_parent); const LVGLPropertyRange *r = reinterpret_cast<const LVGLPropertyRange *>(m_parent);
return r->getMin(obj); return r->getMin(obj);
@ -26,7 +25,6 @@ public:
inline LVGLPropertyMax(LVGLProperty *p) : LVGLPropertyInt(INT16_MIN, INT16_MAX, p) {} inline LVGLPropertyMax(LVGLProperty *p) : LVGLPropertyInt(INT16_MIN, INT16_MAX, p) {}
inline QString name() const override { return "Max"; } inline QString name() const override { return "Max"; }
protected:
inline int get(LVGLObject *obj) const override { inline int get(LVGLObject *obj) const override {
const LVGLPropertyRange *r = reinterpret_cast<const LVGLPropertyRange *>(m_parent); const LVGLPropertyRange *r = reinterpret_cast<const LVGLPropertyRange *>(m_parent);
return r->getMax(obj); return r->getMax(obj);
@ -53,8 +51,7 @@ QString LVGLPropertyRange::name() const
QVariant LVGLPropertyRange::value(LVGLObject *obj) const QVariant LVGLPropertyRange::value(LVGLObject *obj) const
{ {
return QString("[%1,%2]").arg(m_min->value(obj).toInt()) return QString("[%1,%2]").arg(getMin(obj)).arg(getMax(obj));
.arg(m_max->value(obj).toInt());
} }
void LVGLPropertyRange::setValue(LVGLObject *obj, QVariant value) void LVGLPropertyRange::setValue(LVGLObject *obj, QVariant value)

View File

@ -15,16 +15,16 @@ public:
QJsonValue toJson(LVGLObject *obj) const override; QJsonValue toJson(LVGLObject *obj) const override;
protected: protected:
LVGLProperty *m_min; friend class LVGLPropertyMin;
LVGLProperty *m_max; friend class LVGLPropertyMax;
LVGLPropertyMin *m_min;
LVGLPropertyMax *m_max;
virtual int getMin(LVGLObject *obj) const = 0; virtual int getMin(LVGLObject *obj) const = 0;
virtual int getMax(LVGLObject *obj) const = 0; virtual int getMax(LVGLObject *obj) const = 0;
virtual void set(LVGLObject *obj, int min, int max) = 0; virtual void set(LVGLObject *obj, int min, int max) = 0;
friend class LVGLPropertyMin;
friend class LVGLPropertyMax;
}; };
#endif // LVGLPROPERTYRANGE_H #endif // LVGLPROPERTYRANGE_H

View File

@ -10,33 +10,36 @@
class LVGLPropertyTextListDialog : public QDialog class LVGLPropertyTextListDialog : public QDialog
{ {
public: public:
inline LVGLPropertyTextListDialog(QWidget *parent = nullptr) : QDialog(parent) inline LVGLPropertyTextListDialog(bool canInsert, QWidget *parent = nullptr) : QDialog(parent)
{ {
m_list = new QListWidget(this); m_list = new QListWidget(this);
QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok |
QDialogButtonBox::Cancel); QDialogButtonBox::Cancel);
QToolButton *add = new QToolButton();
add->setIcon(QIcon(":/icons/add.png"));
add->setIconSize(QSize(24, 24));
QToolButton *rem = new QToolButton();
rem->setIcon(QIcon(":/icons/delete.png"));
rem->setIconSize(QSize(24, 24));
box->addButton(add, QDialogButtonBox::ApplyRole);
box->addButton(rem, QDialogButtonBox::ApplyRole);
connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(box, &QDialogButtonBox::clicked, [this,add,rem](QAbstractButton *b) {
if (b == add) { if (canInsert) {
QListWidgetItem *item = new QListWidgetItem("New text"); QToolButton *add = new QToolButton();
item->setFlags(item->flags() | Qt::ItemIsEditable); add->setIcon(QIcon(":/icons/add.png"));
m_list->addItem(item); add->setIconSize(QSize(24, 24));
} else if (b == rem) { QToolButton *rem = new QToolButton();
m_list->takeItem(m_list->currentRow()); rem->setIcon(QIcon(":/icons/delete.png"));
} rem->setIconSize(QSize(24, 24));
});
box->addButton(add, QDialogButtonBox::ApplyRole);
box->addButton(rem, QDialogButtonBox::ApplyRole);
connect(box, &QDialogButtonBox::clicked, [this,add,rem](QAbstractButton *b) {
if (b == add) {
QListWidgetItem *item = new QListWidgetItem("New text");
item->setFlags(item->flags() | Qt::ItemIsEditable);
m_list->addItem(item);
} else if (b == rem) {
m_list->takeItem(m_list->currentRow());
}
});
}
QVBoxLayout *layout1 = new QVBoxLayout; QVBoxLayout *layout1 = new QVBoxLayout;
layout1->addWidget(m_list); layout1->addWidget(m_list);
@ -63,12 +66,13 @@ public:
} }
private: private:
class QListWidget *m_list; QListWidget *m_list;
}; };
LVGLPropertyTextList::LVGLPropertyTextList(LVGLProperty *parent) LVGLPropertyTextList::LVGLPropertyTextList(bool canInsert, LVGLProperty *parent)
: LVGLProperty(parent) : LVGLProperty(parent)
, m_canInsert(false)
{ {
} }
@ -79,7 +83,7 @@ bool LVGLPropertyTextList::hasEditor() const
QWidget *LVGLPropertyTextList::editor(QWidget *parent) QWidget *LVGLPropertyTextList::editor(QWidget *parent)
{ {
m_widget = new LVGLPropertyTextListDialog(parent); m_widget = new LVGLPropertyTextListDialog(m_canInsert, parent);
return m_widget; return m_widget;
} }

View File

@ -6,7 +6,7 @@
class LVGLPropertyTextList : public LVGLProperty class LVGLPropertyTextList : public LVGLProperty
{ {
public: public:
LVGLPropertyTextList(LVGLProperty *parent = nullptr); LVGLPropertyTextList(bool canInsert = true, LVGLProperty *parent = nullptr);
bool hasEditor() const; bool hasEditor() const;
QWidget *editor(QWidget *parent); QWidget *editor(QWidget *parent);
@ -20,6 +20,7 @@ public:
protected: protected:
class LVGLPropertyTextListDialog *m_widget; class LVGLPropertyTextListDialog *m_widget;
bool m_canInsert;
virtual QStringList get(LVGLObject *obj) const = 0; virtual QStringList get(LVGLObject *obj) const = 0;
virtual void set(LVGLObject *obj, QStringList list) = 0; virtual void set(LVGLObject *obj, QStringList list) = 0;

View File

@ -6,7 +6,6 @@
template<class T> template<class T>
LVGLPropertyVal2<T>::LVGLPropertyVal::LVGLPropertyVal(size_t idx, T min, T max, QString value, std::function<T (lv_obj_t *)> getter, LVGLPropertyVal2 *parent) LVGLPropertyVal2<T>::LVGLPropertyVal::LVGLPropertyVal(size_t idx, T min, T max, QString value, std::function<T (lv_obj_t *)> getter, LVGLPropertyVal2 *parent)
: LVGLPropertyType<T>(parent) : LVGLPropertyType<T>(parent)
, m_p(parent)
, m_idx(idx) , m_idx(idx)
, m_widget(nullptr) , m_widget(nullptr)
, m_min(min), m_max(max), m_value(value) , m_min(min), m_max(max), m_value(value)
@ -49,10 +48,11 @@ T LVGLPropertyVal2<T>::LVGLPropertyVal::get(LVGLObject *obj) const
template<class T> template<class T>
void LVGLPropertyVal2<T>::LVGLPropertyVal::set(LVGLObject *obj, T value) void LVGLPropertyVal2<T>::LVGLPropertyVal::set(LVGLObject *obj, T value)
{ {
LVGLPropertyVal2<T> *d = reinterpret_cast<LVGLPropertyVal2<T> *>(const_cast<LVGLProperty*>(m_parent));
if (m_idx == 0) if (m_idx == 0)
m_p->m_setter(obj->obj(), value, m_p->m_item2->get(obj)); d->m_setter(obj->obj(), value, d->m_item2->get(obj));
else if (m_idx == 1) else if (m_idx == 1)
m_p->m_setter(obj->obj(), m_p->m_item1->get(obj), value); d->m_setter(obj->obj(), d->m_item1->get(obj), value);
} }
template<class T> template<class T>

View File

@ -30,7 +30,6 @@ private:
T get(LVGLObject *obj) const override; T get(LVGLObject *obj) const override;
void set(LVGLObject *obj, T value) override; void set(LVGLObject *obj, T value) override;
protected: protected:
LVGLPropertyVal2 *m_p;
size_t m_idx; size_t m_idx;
QSpinBox *m_widget; QSpinBox *m_widget;
T m_min; T m_min;

View File

@ -3,41 +3,13 @@
#include <QIcon> #include <QIcon>
#include "LVGLObject.h" #include "LVGLObject.h"
#include "properties/LVGLPropertyVal2.h"
class LVGLPropertyAngleStart : public LVGLPropertyInt
{
public:
inline LVGLPropertyAngleStart() : LVGLPropertyInt(0, 360) {}
inline QString name() const override { return "Start angle"; }
inline int get(LVGLObject *obj) const override { return lv_arc_get_angle_start(obj->obj()); }
inline void set(LVGLObject *obj, int value) override {
lv_obj_t *o = obj->obj();
lv_arc_set_angles(o, static_cast<uint16_t>(value),
lv_arc_get_angle_end(o));
}
};
class LVGLPropertyAngleEnd : public LVGLPropertyInt
{
public:
inline LVGLPropertyAngleEnd() : LVGLPropertyInt(0, 360) {}
inline QString name() const override { return "End angle"; }
inline int get(LVGLObject *obj) const override { return lv_arc_get_angle_end(obj->obj()); }
inline void set(LVGLObject *obj, int value) override {
lv_obj_t *o = obj->obj();
lv_arc_set_angles(o, lv_arc_get_angle_start(o),
static_cast<uint16_t>(value));
}
};
LVGLArc::LVGLArc() LVGLArc::LVGLArc()
{ {
m_properties << new LVGLPropertyAngleStart; m_properties << new LVGLPropertyVal2UInt16(0, 360, "Start", lv_arc_get_angle_start,
m_properties << new LVGLPropertyAngleEnd; 0, 360, "End", lv_arc_get_angle_end,
"lv_arc_set_angles", lv_arc_set_angles, "Angles");
m_editableStyles << LVGL::StyleParts(LVGL::Body | LVGL::Line); // LV_GAUGE_STYLE_MAIN m_editableStyles << LVGL::StyleParts(LVGL::Body | LVGL::Line); // LV_GAUGE_STYLE_MAIN
} }

View File

@ -3,32 +3,158 @@
#include <QIcon> #include <QIcon>
#include "LVGLObject.h" #include "LVGLObject.h"
#include "properties/LVGLPropertyDate.h" #include "properties/LVGLPropertyDate.h"
#include "properties/LVGLPropertyDateList.h"
#include "properties/LVGLPropertyTextList.h"
class LVGLPropertyCalendarCurrentDate : public LVGLPropertyDate class LVGLPropertyDayNames : public LVGLPropertyTextList
{ {
public: public:
QString name() const { return "Current date"; } inline LVGLPropertyDayNames() : LVGLPropertyTextList(false) {}
inline ~LVGLPropertyDayNames() {
for (const char **d:m_garbageCollector) {
for (uint8_t i = 0; i < N; ++i)
delete [] d[i];
delete [] d;
}
}
inline QString name() const override { return "Day names"; }
inline QStringList function(LVGLObject *obj) const override
{
const QStringList list = get(obj);
if (!isDifferent(list))
return {};
QStringList days;
for (uint8_t i = 0; i < N; ++i)
days << "\"" + list[i] + "\"";
QStringList ret;
const QString varName = QString("days_%1").arg(obj->codeName());
ret << QString("static const char *%1[7] = {%2};").arg(varName).arg(days.join(", "));
ret << QString("lv_calendar_set_day_names(%1, %2);").arg(obj->codeName()).arg(varName);
return ret;
}
protected: protected:
lv_calendar_date_t *get(LVGLObject *obj) const { return lv_calendar_get_today_date(obj->obj()); } QList<const char **> m_garbageCollector;
void set(LVGLObject *obj, lv_calendar_date_t *date) { lv_calendar_set_today_date(obj->obj(), date); } static constexpr uint8_t N = 7;
static constexpr const char *DEFAULT[N] = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
inline bool isDifferent(QStringList list) const {
for (uint8_t i = 0; i < N; ++i) {
if (list[i] != QString(DEFAULT[i]))
return true;
}
return false;
}
inline QStringList get(LVGLObject *obj) const override {
const char **names = lv_calendar_get_day_names(obj->obj());
if (names == nullptr)
return {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};
QStringList ret;
for (uint8_t i = 0; i < N; ++i)
ret << QString(names[i]);
return ret;
}
inline void set(LVGLObject *obj, QStringList list) override {
if (!isDifferent(list))
return;
const char **data = new const char *[N];
for (uint8_t i = 0; i < N; ++i) {
const QString &s = list[i];
char *string = new char[s.size()+1];
memcpy(string, qPrintable(s), s.size());
string[s.size()] = '\0';
data[i] = string;
}
m_garbageCollector << data;
lv_calendar_set_day_names(obj->obj(), data);
}
}; };
class LVGLPropertyCalendarShownDate : public LVGLPropertyDate class LVGLPropertyMonthNames : public LVGLPropertyTextList
{ {
public: public:
QString name() const { return "Shown date"; } inline LVGLPropertyMonthNames() : LVGLPropertyTextList(false) {}
inline ~LVGLPropertyMonthNames() {
for (const char **d:m_garbageCollector) {
for (uint8_t i = 0; i < N; ++i)
delete [] d[i];
delete [] d;
}
}
inline QString name() const override { return "Month names"; }
inline QStringList function(LVGLObject *obj) const override
{
const QStringList list = get(obj);
if (!isDifferent(list))
return {};
QStringList months;
for (uint8_t i = 0; i < N; ++i)
months << "\"" + list[i] + "\"";
QStringList ret;
const QString varName = QString("months_%1").arg(obj->codeName());
ret << QString("static const char *%1[12] = {%2};").arg(varName).arg(months.join(", "));
ret << QString("lv_calendar_set_month_names(%1, %2);").arg(obj->codeName()).arg(varName);
return ret;
}
protected: protected:
lv_calendar_date_t *get(LVGLObject *obj) const { return lv_calendar_get_showed_date(obj->obj()); } QList<const char **> m_garbageCollector;
void set(LVGLObject *obj, lv_calendar_date_t *date) { lv_calendar_set_showed_date(obj->obj(), date); } static constexpr uint8_t N = 12;
}; static constexpr const char *DEFAULT[N] = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
inline bool isDifferent(QStringList list) const {
for (uint8_t i = 0; i < N; ++i) {
if (list[i] != QString(DEFAULT[i]))
return true;
}
return false;
}
inline QStringList get(LVGLObject *obj) const override {
const char **names = lv_calendar_get_month_names(obj->obj());
if (names == nullptr)
return {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
QStringList ret;
for (uint8_t i = 0; i < N; ++i)
ret << QString(names[i]);
return ret;
}
inline void set(LVGLObject *obj, QStringList list) override {
if (!isDifferent(list))
return;
const char **data = new const char *[N];
for (uint8_t i = 0; i < N; ++i) {
const QString &s = list[i];
char *string = new char[s.size()+1];
memcpy(string, qPrintable(s), s.size());
string[s.size()] = '\0';
data[i] = string;
}
m_garbageCollector << data;
lv_calendar_set_month_names(obj->obj(), data);
}
};
LVGLCalendar::LVGLCalendar() LVGLCalendar::LVGLCalendar()
{ {
m_properties << new LVGLPropertyCalendarCurrentDate; m_properties << new LVGLPropertyDate("Current date", "lv_calendar_set_today_date", lv_calendar_set_today_date, lv_calendar_get_today_date);
m_properties << new LVGLPropertyCalendarShownDate; m_properties << new LVGLPropertyDate("Shown date", "lv_calendar_set_showed_date", lv_calendar_set_showed_date, lv_calendar_get_showed_date);
m_properties << new LVGLPropertyDateList("Highlighted dates", "lv_calendar_set_highlighted_dates",
lv_calendar_set_highlighted_dates, lv_calendar_get_highlighted_dates, lv_calendar_get_highlighted_dates_num);
m_properties << new LVGLPropertyDayNames;
m_properties << new LVGLPropertyMonthNames;
m_editableStyles << LVGL::StyleParts(LVGL::Body | LVGL::Text); // LV_CALENDAR_STYLE_BG m_editableStyles << LVGL::StyleParts(LVGL::Body | LVGL::Text); // LV_CALENDAR_STYLE_BG
m_editableStyles << LVGL::StyleParts(LVGL::Body | LVGL::Text); // LV_CALENDAR_STYLE_HEADER m_editableStyles << LVGL::StyleParts(LVGL::Body | LVGL::Text); // LV_CALENDAR_STYLE_HEADER