2 Star 1 Fork 1

ssda/LVGLBuilder

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
MainWindow.cpp 16.72 KB
一键复制 编辑 原始数据 按行查看 历史
#include "MainWindow.h"
#include <QDebug>
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QSettings>
#include <QSortFilterProxyModel>
#include "LVGLDialog.h"
#include "LVGLFontData.h"
#include "LVGLFontDialog.h"
#include "LVGLItem.h"
#include "LVGLNewDialog.h"
#include "LVGLObjectModel.h"
#include "LVGLProject.h"
#include "LVGLPropertyModel.h"
#include "LVGLSimulator.h"
#include "LVGLStyleModel.h"
#include "LVGLTabWidget.h"
#include "LVGLWidgetModel.h"
#include "ui_MainWindow.h"
#include "widgets/LVGLWidgets.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
m_ui(new Ui::MainWindow),
m_zoom_slider(new QSlider(Qt::Horizontal)),
m_project(nullptr),
m_maxFileNr(5),
m_firstrun(true),
m_simulator(new LVGLSimulator(this)),
m_lastindex(-1) {
m_ui->setupUi(this);
lvgl.init(320, 480);
m_zoom_slider->setRange(-2, 2);
connect(m_zoom_slider, &QSlider::valueChanged, m_simulator,
&LVGLSimulator::setZoomLevel);
m_ui->statusbar->addPermanentWidget(m_zoom_slider);
m_ui->button_remove_image->setEnabled(false);
m_ui->button_remove_font->setEnabled(false);
m_propertyModel = new LVGLPropertyModel;
connect(m_simulator, &LVGLSimulator::objectSelected, this,
&MainWindow::setCurrentObject);
connect(m_simulator, &LVGLSimulator::objectSelected, m_ui->property_tree,
&QTreeView::expandAll);
connect(m_simulator->item(), &LVGLItem::geometryChanged, this,
&MainWindow::updateProperty);
connect(m_ui->action_new, &QAction::triggered, this,
&MainWindow::openNewProject);
connect(m_simulator, &LVGLSimulator::objectAdded, m_ui->object_tree,
&QTreeView::expandAll);
m_ui->property_tree->setModel(m_propertyModel);
m_ui->property_tree->setItemDelegate(new LVGLPropertyDelegate);
m_objectModel = new LVGLObjectModel(this);
connect(m_simulator, &LVGLSimulator::objectSelected, m_objectModel,
&LVGLObjectModel::setCurrentObject);
connect(m_ui->object_tree, &QTreeView::doubleClicked, this,
[this](const QModelIndex &index) {
m_simulator->setSelectedObject(m_objectModel->object(index));
});
m_ui->object_tree->setModel(m_objectModel);
m_simulator->setObjectModel(m_objectModel);
m_simulator->setPropertyModel(m_propertyModel);
LVGLWidgetModel *widgetModel = new LVGLWidgetModel;
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
connect(m_ui->edit_filter, &QLineEdit::textChanged, proxyModel,
&QSortFilterProxyModel::setFilterWildcard);
proxyModel->setSourceModel(widgetModel);
proxyModel->sort(0);
m_ui->list_widgets->setModel(proxyModel);
m_styleModel = new LVGLStyleModel;
connect(m_styleModel, &LVGLStyleModel::styleChanged, this,
&MainWindow::styleChanged);
m_ui->style_tree->setModel(m_styleModel);
m_ui->style_tree->setItemDelegate(
new LVGLStyleDelegate(m_styleModel->styleBase()));
m_ui->style_tree->expandAll();
// recent configurations
QAction *recentFileAction = nullptr;
for (int i = 0; i < m_maxFileNr; i++) {
recentFileAction = new QAction(this);
recentFileAction->setVisible(false);
connect(recentFileAction, &QAction::triggered, this,
&MainWindow::loadRecent);
m_recentFileActionList.append(recentFileAction);
m_ui->menu_resent_filess->addAction(recentFileAction);
}
updateRecentActionList();
// add style editor dock to property dock and show the property dock
tabifyDockWidget(m_ui->PropertyEditor, m_ui->StyleEditor);
m_ui->PropertyEditor->raise();
// add font editor dock to image dock and show the image dock
tabifyDockWidget(m_ui->ImageEditor, m_ui->FontEditor);
m_ui->ImageEditor->raise();
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), this,
SLOT(tabchanged(int)));
}
MainWindow::~MainWindow() {
lvgl.removeAllObjects();
// m_simulator->setSelectedObject(nullptr);
delete m_propertyModel;
delete m_objectModel;
delete m_styleModel;
int curindex = m_ui->tabWidget->currentIndex();
for (int i = 0; i < m_ui->tabWidget->count(); ++i) {
if (i != curindex) {
auto tabw = static_cast<LVGLTabWidget *>(m_ui->tabWidget->widget(i));
tabw->removeAllObjects();
}
}
delete m_ui;
delete m_project;
}
LVGLSimulator *MainWindow::simulator() const { return m_simulator; }
void MainWindow::updateProperty() {
LVGLObject *o = m_simulator->selectedObject();
if (o == nullptr) return;
LVGLProperty *p = o->widgetClass()->property("Geometry");
if (p == nullptr) return;
for (int i = 0; i < p->count(); ++i) {
auto index = m_propertyModel->propIndex(p->child(i), o->widgetClass(), 1);
emit m_propertyModel->dataChanged(index, index);
}
}
void MainWindow::setCurrentObject(LVGLObject *obj) {
m_ui->combo_style->clear();
m_propertyModel->setObject(obj);
if (obj) {
m_ui->combo_style->addItems(obj->widgetClass()->styles());
m_styleModel->setStyle(obj->style(0),
obj->widgetClass()->editableStyles(0));
} else {
m_styleModel->setStyle(nullptr);
}
}
void MainWindow::styleChanged() {
LVGLObject *obj = m_simulator->selectedObject();
if (obj) {
int index = m_ui->combo_style->currentIndex();
obj->widgetClass()->setStyle(obj->obj(), index, obj->style(index));
// refresh_children_style(obj->obj());
// lv_obj_refresh_style(obj->obj());
}
}
void MainWindow::loadRecent() {
QAction *action = qobject_cast<QAction *>(QObject::sender());
if (action == nullptr) return;
loadProject(action->data().toString());
}
void MainWindow::openNewProject() {
LVGLNewDialog dialog(this);
if (dialog.exec() == QDialog::Accepted) {
if (m_firstrun) {
m_firstrun = false;
m_project =
new LVGLProject(dialog.selectedName(), dialog.selectedResolution());
const auto res = dialog.selectedResolution();
lvgl.changeResolution(res);
m_simulator->changeResolution(res);
}
setEnableBuilder(true);
LVGLTabWidget *tabW = new LVGLTabWidget(this);
tabW->setname(dialog.selectedName());
m_simulator->setobjParent(tabW->getparent());
m_ui->tabWidget->addTab(tabW, dialog.selectedName());
m_ui->tabWidget->setCurrentIndex(m_ui->tabWidget->count() - 1);
} else if (m_project == nullptr) {
setEnableBuilder(false);
setWindowTitle("LVGL Builder");
}
}
void MainWindow::addImage(LVGLImageData *img, QString name) {
LVGLImageDataCast cast;
cast.ptr = img;
QListWidgetItem *item = new QListWidgetItem(img->icon(), name);
item->setData(Qt::UserRole + 3, cast.i);
m_ui->list_images->addItem(item);
}
void MainWindow::updateImages() {
m_ui->list_images->clear();
for (LVGLImageData *i : lvgl.images()) {
if (i->fileName().isEmpty()) continue;
QString name = QFileInfo(i->fileName()).baseName() +
QString(" [%1x%2]").arg(i->width()).arg(i->height());
addImage(i, name);
}
}
void MainWindow::addFont(LVGLFontData *font, QString name) {
LVGLFontDataCast cast;
cast.ptr = font;
QListWidgetItem *item = new QListWidgetItem(name);
item->setData(Qt::UserRole + 3, cast.i);
m_ui->list_fonts->addItem(item);
}
void MainWindow::updateFonts() {
m_ui->list_fonts->clear();
for (const LVGLFontData *f : lvgl.customFonts())
addFont(const_cast<LVGLFontData *>(f), f->name());
}
void MainWindow::updateRecentActionList() {
QSettings settings("at.fhooe.lvgl", "LVGL Builder");
QStringList recentFilePaths;
for (const QString &f : settings.value("recentFiles").toStringList()) {
if (QFile(f).exists()) recentFilePaths.push_back(f);
}
int itEnd = m_maxFileNr;
if (recentFilePaths.size() <= m_maxFileNr) itEnd = recentFilePaths.size();
for (int i = 0; i < itEnd; i++) {
QString strippedName = QFileInfo(recentFilePaths.at(i)).fileName();
m_recentFileActionList.at(i)->setText(strippedName);
m_recentFileActionList.at(i)->setData(recentFilePaths.at(i));
m_recentFileActionList.at(i)->setVisible(true);
}
for (int i = itEnd; i < m_maxFileNr; i++)
m_recentFileActionList.at(i)->setVisible(false);
}
void MainWindow::adjustForCurrentFile(const QString &fileName) {
QSettings settings("at.fhooe.lvgl", "LVGL Builder");
QStringList recentFilePaths = settings.value("recentFiles").toStringList();
recentFilePaths.removeAll(fileName);
recentFilePaths.prepend(fileName);
while (recentFilePaths.size() > m_maxFileNr) recentFilePaths.removeLast();
settings.setValue("recentFiles", recentFilePaths);
updateRecentActionList();
}
void MainWindow::loadProject(const QString &fileName) {
delete m_project;
m_simulator->clear();
m_project = LVGLProject::load(fileName);
if (m_project == nullptr) {
QMessageBox::critical(this, "Error", "Could not load lvgl file!");
setWindowTitle("LVGL Builder");
setEnableBuilder(false);
} else {
adjustForCurrentFile(fileName);
setWindowTitle("LVGL Builder - [" + m_project->name() + "]");
lvgl.changeResolution(m_project->resolution());
m_simulator->changeResolution(m_project->resolution());
setEnableBuilder(true);
}
updateImages();
updateFonts();
}
void MainWindow::setEnableBuilder(bool enable) {
m_ui->action_save->setEnabled(enable);
m_ui->action_export_c->setEnabled(enable);
m_ui->action_run->setEnabled(enable);
m_ui->WidgeBox->setEnabled(enable);
m_ui->ImageEditor->setEnabled(enable);
m_ui->FontEditor->setEnabled(enable);
}
void MainWindow::on_action_load_triggered() {
QString path;
if (m_project != nullptr) path = m_project->fileName();
QString fileName =
QFileDialog::getOpenFileName(this, "Load lvgl", path, "LVGL (*.lvgl)");
if (fileName.isEmpty()) return;
loadProject(fileName);
}
void MainWindow::on_action_save_triggered() {
QString path;
if (m_project != nullptr) path = m_project->fileName();
QString fileName =
QFileDialog::getSaveFileName(this, "Save lvgl", path, "LVGL (*.lvgl)");
if (fileName.isEmpty()) return;
if (!m_project->save(fileName)) {
QMessageBox::critical(this, "Error", "Could not save lvgl file!");
} else {
adjustForCurrentFile(fileName);
}
}
void MainWindow::on_combo_style_currentIndexChanged(int index) {
LVGLObject *obj = m_simulator->selectedObject();
if (obj && (index >= 0) && (index < obj->widgetClass()->styles().size()))
m_styleModel->setStyle(obj->style(index),
obj->widgetClass()->editableStyles(index));
}
void MainWindow::on_action_export_c_triggered() {
QString dir;
if (m_project != nullptr) {
QFileInfo fi(m_project->fileName());
dir = fi.absoluteFilePath();
}
QString path = QFileDialog::getExistingDirectory(this, "Export C files", dir);
if (path.isEmpty()) return;
if (m_project->exportCode(path))
QMessageBox::information(this, "Export", "C project exported!");
}
void MainWindow::on_button_add_image_clicked() {
QString dir;
if (m_project != nullptr) {
QFileInfo fi(m_project->fileName());
dir = fi.absoluteFilePath();
}
QStringList fileNames = QFileDialog::getOpenFileNames(
this, "Import image", dir, "Image (*.png *.jpg *.bmp *.jpeg)");
for (const QString &fileName : fileNames) {
QImage image(fileName);
if (image.isNull()) continue;
if (image.width() >= 2048 || image.height() >= 2048) {
QMessageBox::critical(
this, "Error Image Size",
tr("Image size must be under 2048! (Src: '%1')").arg(fileName));
continue;
}
QString name = QFileInfo(fileName).baseName();
LVGLImageData *i = lvgl.addImage(fileName, name);
name += QString(" [%1x%2]").arg(i->width()).arg(i->height());
addImage(i, name);
}
}
void MainWindow::on_button_remove_image_clicked() {
QListWidgetItem *item = m_ui->list_images->currentItem();
if (item == nullptr) return;
const int row = m_ui->list_images->currentRow();
LVGLImageDataCast cast;
cast.i = item->data(Qt::UserRole + 3).toLongLong();
if (lvgl.removeImage(cast.ptr)) m_ui->list_images->takeItem(row);
}
void MainWindow::on_list_images_customContextMenuRequested(const QPoint &pos) {
QPoint item = m_ui->list_images->mapToGlobal(pos);
QListWidgetItem *listItem = m_ui->list_images->itemAt(pos);
if (listItem == nullptr) return;
QMenu menu;
QAction *save = menu.addAction("Save as ...");
QAction *color = menu.addAction("Set output color ...");
QAction *sel = menu.exec(item);
if (sel == save) {
LVGLImageDataCast cast;
cast.i = listItem->data(Qt::UserRole + 3).toLongLong();
QStringList options({"C Code (*.c)", "Binary (*.bin)"});
QString selected;
QString fileName = QFileDialog::getSaveFileName(
this, "Save image as c file", cast.ptr->codeName(), options.join(";;"),
&selected);
if (fileName.isEmpty()) return;
bool ok = false;
if (selected == options.at(0))
ok = cast.ptr->saveAsCode(fileName);
else if (selected == options.at(1))
ok = cast.ptr->saveAsBin(fileName);
if (!ok) {
QMessageBox::critical(this, "Error",
tr("Could not save image '%1'").arg(fileName));
}
} else if (sel == color) {
LVGLImageDataCast cast;
cast.i = listItem->data(Qt::UserRole + 3).toLongLong();
int index = static_cast<int>(cast.ptr->colorFormat());
QString ret =
QInputDialog::getItem(this, "Output color", "Select output color",
LVGLImageData::colorFormats(), index, false);
index = LVGLImageData::colorFormats().indexOf(ret);
if (index >= 0)
cast.ptr->setColorFormat(static_cast<LVGLImageData::ColorFormat>(index));
}
}
void MainWindow::on_list_images_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous) {
Q_UNUSED(previous)
m_ui->button_remove_image->setEnabled(current != nullptr);
}
void MainWindow::on_button_add_font_clicked() {
LVGLFontDialog dialog(this);
if (dialog.exec() != QDialog::Accepted) return;
LVGLFontData *f =
lvgl.addFont(dialog.selectedFontPath(), dialog.selectedFontSize());
if (f)
addFont(f, f->name());
else
QMessageBox::critical(this, "Error", "Could not load font!");
}
void MainWindow::on_button_remove_font_clicked() {
QListWidgetItem *item = m_ui->list_fonts->currentItem();
if (item == nullptr) return;
const int row = m_ui->list_fonts->currentRow();
LVGLFontDataCast cast;
cast.i = item->data(Qt::UserRole + 3).toLongLong();
if (lvgl.removeFont(cast.ptr)) m_ui->list_fonts->takeItem(row);
}
void MainWindow::on_list_fonts_customContextMenuRequested(const QPoint &pos) {
QPoint item = m_ui->list_fonts->mapToGlobal(pos);
QListWidgetItem *listItem = m_ui->list_fonts->itemAt(pos);
if (listItem == nullptr) return;
QMenu menu;
QAction *save = menu.addAction("Save as ...");
QAction *sel = menu.exec(item);
if (sel == save) {
LVGLFontDataCast cast;
cast.i = listItem->data(Qt::UserRole + 3).toLongLong();
QStringList options({"C Code (*.c)", "Binary (*.bin)"});
QString selected;
QString fileName = QFileDialog::getSaveFileName(
this, "Save font as c file", cast.ptr->codeName(), options.join(";;"),
&selected);
if (fileName.isEmpty()) return;
bool ok = false;
if (selected == options.at(0)) ok = cast.ptr->saveAsCode(fileName);
if (!ok) {
QMessageBox::critical(this, "Error",
tr("Could not save font '%1'").arg(fileName));
}
}
}
void MainWindow::on_list_fonts_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous) {
Q_UNUSED(previous)
m_ui->button_remove_font->setEnabled(current != nullptr);
}
void MainWindow::on_action_run_toggled(bool run) {
m_simulator->setMouseEnable(run);
m_simulator->setSelectedObject(nullptr);
}
void MainWindow::tabchanged(int index) {
if (m_lastindex != -1) {
auto oldtabw =
static_cast<LVGLTabWidget *>(m_ui->tabWidget->widget(m_lastindex));
auto objs = lvgl.allObjects();
oldtabw->setAllObjects(lvgl.allObjects());
for (int i = 0; i < objs.count(); ++i) {
m_objectModel->beginRemoveObject(objs[i]);
m_objectModel->endRemoveObject();
}
lvgl.objsclear();
}
m_lastindex = index;
auto tabw = static_cast<LVGLTabWidget *>(m_ui->tabWidget->widget(index));
m_simulator->setobjParent(tabw->getparent());
tabw->setSimulator(m_simulator);
auto objs = tabw->allObject();
lvgl.setAllObjects(objs);
m_project->setName(tabw->getname());
for (int i = 0; i < objs.count(); ++i) {
m_objectModel->beginInsertObject(objs[i]);
m_objectModel->endInsertObject();
}
m_ui->object_tree->update();
if (!objs.isEmpty()) m_simulator->setSelectedObject(lvgl.allObjects().at(0));
m_simulator->setSelectedObject(nullptr); // need it
}
void MainWindow::showEvent(QShowEvent *event) {
QMainWindow::showEvent(event);
if (m_project == nullptr)
QTimer::singleShot(50, this, SLOT(openNewProject()));
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/shaoshunda/LVGLBuilder.git
git@gitee.com:shaoshunda/LVGLBuilder.git
shaoshunda
LVGLBuilder
LVGLBuilder
master

搜索帮助