Theme Editor: Added code generate/undo functionality to SkinViewer

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27704 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Robert Bieber 2010-08-05 00:43:33 +00:00
parent 4674518787
commit 054a85fdca
15 changed files with 154 additions and 39 deletions

View file

@ -311,8 +311,6 @@ void RBViewport::saveGeometry()
node->modParam(static_cast<int>(origin.y()), baseParam + 1);
node->modParam(static_cast<int>(bounds.width()), baseParam + 2);
node->modParam(static_cast<int>(bounds.height()), baseParam + 3);
doc->genCode();
}
void RBViewport::alignLeft()

View file

@ -428,7 +428,7 @@ void EditorWindow::shiftTab(int index)
ui->actionCopy->setEnabled(false);
ui->actionPaste->setEnabled(false);
ui->actionFind_Replace->setEnabled(false);
viewer->setScene(0);
viewer->connectSkin(0);
}
else if(widget->type() == TabContent::Config)
{
@ -441,7 +441,7 @@ void EditorWindow::shiftTab(int index)
ui->actionCopy->setEnabled(false);
ui->actionPaste->setEnabled(false);
ui->actionFind_Replace->setEnabled(false);
viewer->setScene(0);
viewer->connectSkin(0);
}
else if(widget->type() == TabContent::Skin)
{
@ -465,7 +465,8 @@ void EditorWindow::shiftTab(int index)
sizeColumns();
/* Syncing the preview */
viewer->setScene(doc->scene());
viewer->connectSkin(doc);
}
@ -513,7 +514,7 @@ void EditorWindow::closeProject()
dynamic_cast<SkinDocument*>(doc)->setProject(project);
if(i == ui->editorTabs->currentIndex())
{
viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
viewer->connectSkin(dynamic_cast<SkinDocument*>(doc));
}
}
}
@ -630,7 +631,7 @@ void EditorWindow::configFileChanged(QString configFile)
dynamic_cast<SkinDocument*>(doc)->setProject(project);
if(i == ui->editorTabs->currentIndex())
{
viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
viewer->connectSkin(dynamic_cast<SkinDocument*>(doc));
}
}
}
@ -858,7 +859,7 @@ void EditorWindow::loadProjectFile(QString fileName)
dynamic_cast<SkinDocument*>(doc)->setProject(project);
if(i == ui->editorTabs->currentIndex())
{
viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
viewer->connectSkin(dynamic_cast<SkinDocument*>(doc));
}
}
}

View file

@ -36,7 +36,8 @@ const int SkinDocument::updateInterval = 500;
SkinDocument::SkinDocument(QLabel* statusLabel, ProjectModel* project,
DeviceState* device, QWidget *parent)
:TabContent(parent), statusLabel(statusLabel),
project(project), device(device)
project(project), device(device),
treeInSync(true)
{
setupUI();
@ -53,7 +54,7 @@ SkinDocument::SkinDocument(QLabel* statusLabel, QString file,
QWidget *parent)
:TabContent(parent), fileName(file),
statusLabel(statusLabel), project(project),
device(device)
device(device), treeInSync(true)
{
setupUI();
blockUpdate = false;
@ -163,6 +164,9 @@ void SkinDocument::setupUI()
/* Setting up the model */
model = new ParseTreeModel("");
QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(modelChanged()));
/* Connecting the editor's signal */
QObject::connect(editor, SIGNAL(textChanged()),
this, SLOT(codeChanged()));
@ -260,6 +264,10 @@ void SkinDocument::codeChanged()
editor->clearErrors();
parseStatus = model->changeTree(editor->document()->
toPlainText().toAscii());
treeInSync = true;
emit antiSync(false);
if(skin_error_line() > 0)
parseStatus = tr("Errors in document");
statusLabel->setText(parseStatus);
@ -313,6 +321,12 @@ void SkinDocument::codeChanged()
}
void SkinDocument::modelChanged()
{
treeInSync = false;
emit antiSync(true);
}
void SkinDocument::save()
{
QFile fout(fileName);

View file

@ -66,7 +66,6 @@ public:
QString title() const{ return titleText; }
QString getStatus(){ return parseStatus; }
CodeEditor* getEditor(){ return editor; }
void genCode(){ editor->document()->setPlainText(model->genCode()); }
void setProject(ProjectModel* project){ this->project = project; }
void save();
@ -84,14 +83,21 @@ public:
void showFind(){ findReplace->show(); }
void hideFind(){ findReplace->hide(); }
bool isSynced(){ return treeInSync; }
signals:
void antiSync(bool outOfSync);
public slots:
void settingsChanged();
void cursorChanged();
void parseCode(){ codeChanged(); }
void genCode(){ editor->document()->setPlainText(model->genCode()); }
private slots:
void codeChanged();
void modelChanged();
void deviceChanged(){ scene(); }
private:
@ -122,6 +128,8 @@ private:
QTime lastUpdate;
static const int updateInterval;
QTimer checkUpdate;
bool treeInSync;
};
#endif // SKINDOCUMENT_H

View file

@ -54,9 +54,38 @@ void SkinViewer::changeEvent(QEvent *e)
}
}
void SkinViewer::setScene(QGraphicsScene *scene)
void SkinViewer::connectSkin(SkinDocument *skin)
{
ui->viewer->setScene(scene);
if(skin)
{
ui->viewer->setScene(skin->scene());
QObject::connect(skin, SIGNAL(antiSync(bool)),
ui->codeGenButton, SLOT(setEnabled(bool)));
QObject::connect(skin, SIGNAL(antiSync(bool)),
ui->codeUndoButton, SLOT(setEnabled(bool)));
QObject::connect(ui->codeGenButton, SIGNAL(pressed()),
skin, SLOT(genCode()));
QObject::connect(ui->codeUndoButton, SIGNAL(pressed()),
skin, SLOT(parseCode()));
doc = skin;
}
else
{
ui->viewer->setScene(0);
doc = 0;
}
bool antiSync;
if(skin && !skin->isSynced())
antiSync = true;
else
antiSync = false;
ui->codeGenButton->setEnabled(antiSync);
ui->codeUndoButton->setEnabled(antiSync);
}
void SkinViewer::zoomIn()

View file

@ -25,6 +25,8 @@
#include <QWidget>
#include <QGraphicsScene>
#include "skindocument.h"
namespace Ui {
class SkinViewer;
}
@ -35,18 +37,22 @@ public:
SkinViewer(QWidget *parent = 0);
~SkinViewer();
void setScene(QGraphicsScene* scene);
void connectSkin(SkinDocument* skin);
public slots:
void zoomIn();
void zoomOut();
void zoomEven();
private slots:
protected:
void changeEvent(QEvent *e);
private:
Ui::SkinViewer *ui;
SkinDocument* doc;
};
#endif // SKINVIEWER_H

View file

@ -26,6 +26,34 @@
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="codeGenButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/resources/resources/applications-system.png</normaloff>:/resources/resources/applications-system.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="codeUndoButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/resources/resources/edit-undo.png</normaloff>:/resources/resources/edit-undo.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">

View file

@ -40,7 +40,7 @@ ParseTreeModel::ParseTreeModel(const char* document, QObject* parent):
this->tree = skin_parse(document);
if(tree)
this->root = new ParseTreeNode(tree);
this->root = new ParseTreeNode(tree, this);
else
this->root = 0;
@ -77,7 +77,7 @@ QString ParseTreeModel::changeTree(const char *document)
return error;
}
ParseTreeNode* temp = new ParseTreeNode(test);
ParseTreeNode* temp = new ParseTreeNode(test, this);
if(root)
{
@ -364,3 +364,17 @@ QGraphicsScene* ParseTreeModel::render(ProjectModel* project,
return scene;
}
void ParseTreeModel::paramChanged(ParseTreeNode *param)
{
QModelIndex index = indexFromPointer(param);
emit dataChanged(index, index);
}
QModelIndex ParseTreeModel::indexFromPointer(ParseTreeNode *p)
{
/* Recursively finding an index for an arbitrary pointer within the tree */
if(!p->getParent())
return QModelIndex();
return index(p->getRow(), 0, indexFromPointer(p->getParent()));
}

View file

@ -53,6 +53,8 @@ public:
QString genCode();
/* Changes the parse tree to a new document */
QString changeTree(const char* document);
/* Model implementation stuff */
QModelIndex index(int row, int column, const QModelIndex& parent) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
@ -74,6 +76,8 @@ public:
return fallback;
}
void paramChanged(ParseTreeNode* param);
QModelIndex indexFromPointer(ParseTreeNode* p);
private:
ParseTreeNode* root;

View file

@ -36,19 +36,21 @@ int ParseTreeNode::openConditionals = 0;
bool ParseTreeNode::breakFlag = false;
/* Root element constructor */
ParseTreeNode::ParseTreeNode(struct skin_element* data)
: parent(0), element(0), param(0), children()
ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeModel* model)
: parent(0), element(0), param(0), children(), model(model)
{
while(data)
{
children.append(new ParseTreeNode(data, this));
children.append(new ParseTreeNode(data, this, model));
data = data->next;
}
}
/* Normal element constructor */
ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent)
: parent(parent), element(data), param(0), children()
ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent,
ParseTreeModel* model)
: parent(parent), element(data), param(0),
children(), model(model)
{
switch(element->type)
{
@ -58,29 +60,30 @@ ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent)
{
if(element->params[i].type == skin_tag_parameter::CODE)
children.append(new ParseTreeNode(element->params[i].data.code,
this));
this, model));
else
children.append(new ParseTreeNode(&element->params[i], this));
children.append(new ParseTreeNode(&element->params[i], this,
model));
}
break;
case CONDITIONAL:
for(int i = 0; i < element->params_count; i++)
children.append(new ParseTreeNode(&data->params[i], this));
children.append(new ParseTreeNode(&data->params[i], this, model));
for(int i = 0; i < element->children_count; i++)
children.append(new ParseTreeNode(data->children[i], this));
children.append(new ParseTreeNode(data->children[i], this, model));
break;
case LINE_ALTERNATOR:
for(int i = 0; i < element->children_count; i++)
{
children.append(new ParseTreeNode(data->children[i], this));
children.append(new ParseTreeNode(data->children[i], this, model));
}
break;
case VIEWPORT:
for(int i = 0; i < element->params_count; i++)
children.append(new ParseTreeNode(&data->params[i], this));
children.append(new ParseTreeNode(&data->params[i], this, model));
/* Deliberate fall-through here */
case LINE:
@ -89,7 +92,7 @@ case VIEWPORT:
for(struct skin_element* current = data->children[i]; current;
current = current->next)
{
children.append(new ParseTreeNode(current, this));
children.append(new ParseTreeNode(current, this, model));
}
}
break;
@ -100,8 +103,10 @@ case VIEWPORT:
}
/* Parameter constructor */
ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent)
: parent(parent), element(0), param(data), children()
ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent,
ParseTreeModel *model)
: parent(parent), element(0), param(data),
children(), model(model)
{
}
@ -1085,5 +1090,7 @@ void ParseTreeNode::modParam(QVariant value, int index)
param->data.number = value.toInt();
}
model->paramChanged(this);
}
}

View file

@ -34,9 +34,11 @@
class ParseTreeNode
{
public:
ParseTreeNode(struct skin_element* data);
ParseTreeNode(struct skin_element* data, ParseTreeNode* parent);
ParseTreeNode(struct skin_tag_parameter* data, ParseTreeNode* parent);
ParseTreeNode(struct skin_element* data, ParseTreeModel* model);
ParseTreeNode(struct skin_element* data, ParseTreeNode* parent,
ParseTreeModel* model);
ParseTreeNode(struct skin_tag_parameter* data, ParseTreeNode* parent,
ParseTreeModel* model);
virtual ~ParseTreeNode();
QString genCode() const;
@ -84,6 +86,8 @@ private:
static bool breakFlag;
QGraphicsItem* rendered;
ParseTreeModel* model;
};
#endif // PARSETREENODE_H

View file

@ -23,6 +23,7 @@
<file>resources/edit-cut.png</file>
<file>resources/edit-paste.png</file>
<file>resources/edit-find-replace.png</file>
<file>resources/applications-system.png</file>
</qresource>
<qresource prefix="/render">
<file alias="scenebg.png">resources/render/scenebg.png</file>

View file

@ -1,8 +1,8 @@
The files edit-cut.png, edit-copy.png, edit-paste.png, edit-find-replace.png,
edit-undo.png, edit-redo.png, ffwd.png, rwnd.png, play.png, pause.png,
document-new.png, document-open.png, document-save-as.png, and document-save.png
came from the Tango Desktop Project (http://www.tango.freedesktop.org) and are
in the public domain.
The files applications-system.png, edit-cut.png, edit-copy.png, edit-paste.png,
edit-find-replace.png, edit-undo.png, edit-redo.png, ffwd.png, rwnd.png,
play.png, pause.png, document-new.png, document-open.png, document-save-as.png,
and document-save.png came from the Tango Desktop Project
(http://www.tango.freedesktop.org) and are in the public domain.
The files zoomin.png, zoomout.png, and zoomeven.png came from the Tango Project
with modifications by Robert Bieber, also in the public domain.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -182,7 +182,8 @@ OTHER_FILES += README \
resources/edit-paste.png \
resources/edit-cut.png \
resources/edit-copy.png \
resources/edit-find-replace.png
resources/edit-find-replace.png \
resources/applications-system.png
FORMS += gui/editorwindow.ui \
gui/preferencesdialog.ui \
gui/configdocument.ui \