Theme Editor: Began in implementing tag rendering, %X tag now recognized

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27043 a1c6a512-1295-4272-9138-f99709370657
diff --git a/utils/themeeditor/graphics/rbimage.cpp b/utils/themeeditor/graphics/rbimage.cpp
new file mode 100644
index 0000000..5105c95
--- /dev/null
+++ b/utils/themeeditor/graphics/rbimage.cpp
@@ -0,0 +1,38 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Robert Bieber
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <QPainter>
+
+#include "rbimage.h"
+
+RBImage::RBImage(QString file, int tiles)
+    :image(file), tiles(tiles)
+{
+}
+
+void RBImage::draw(QPainter *painter, int x, int y, int tile)
+{
+    if(tiles == 0)
+        painter->drawPixmap(x, y, image.width(), image.height(), image);
+    else
+        painter->drawPixmap(x, y, image, 0, tile * (image.height() / tiles),
+                            image.width(), image.height() / tiles);
+}
diff --git a/utils/themeeditor/graphics/rbimage.h b/utils/themeeditor/graphics/rbimage.h
new file mode 100644
index 0000000..2eaf9b6
--- /dev/null
+++ b/utils/themeeditor/graphics/rbimage.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Robert Bieber
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef RBIMAGE_H
+#define RBIMAGE_H
+
+#include <QPixmap>
+
+class RBImage
+{
+public:
+    RBImage(QString file, int tiles = 0);
+    void draw(QPainter* painter, int x, int y, int tile = 0);
+
+private:
+    QPixmap image;
+    int tiles;
+
+};
+
+#endif // RBIMAGE_H
diff --git a/utils/themeeditor/graphics/rbscreen.cpp b/utils/themeeditor/graphics/rbscreen.cpp
index 065bea6..0a04037 100644
--- a/utils/themeeditor/graphics/rbscreen.cpp
+++ b/utils/themeeditor/graphics/rbscreen.cpp
@@ -38,13 +38,16 @@
     QString fg = info.settings()->value("foreground color", "FFFFFF");
     fgColor = stringToColor(fg, Qt::black);
 
-    /* Loading backdrop if available */
-    QString base = info.settings()->value("themebase", "");
-    QString backdropFile = info.settings()->value("backdrop", "");
+    settings = info.settings();
 
-    if(QFile::exists(base + "/backdrops/" + backdropFile))
+    /* Loading backdrop if available */
+    themeBase = info.settings()->value("themebase", "");
+    QString backdropFile = info.settings()->value("backdrop", "");
+    backdropFile.replace("/.rockbox/backdrops/", "");
+
+    if(QFile::exists(themeBase + "/backdrops/" + backdropFile))
     {
-        backdrop = new QPixmap(base + "/backdrops/" + backdropFile);
+        backdrop = new QPixmap(themeBase + "/backdrops/" + backdropFile);
 
         /* If a backdrop has been found, use its width and height */
         if(!backdrop->isNull())
@@ -100,6 +103,19 @@
     update();
 }
 
+void RBScreen::setBackdrop(QString filename)
+{
+
+    if(backdrop)
+        delete backdrop;
+
+    filename = settings->value("imagepath", "") + "/" + filename;
+
+    if(QFile::exists(filename))
+        backdrop = new QPixmap(filename);
+    else
+        backdrop = 0;
+}
 
 QColor RBScreen::stringToColor(QString str, QColor fallback)
 {
diff --git a/utils/themeeditor/graphics/rbscreen.h b/utils/themeeditor/graphics/rbscreen.h
index 6a9da2f..b60705b 100644
--- a/utils/themeeditor/graphics/rbscreen.h
+++ b/utils/themeeditor/graphics/rbscreen.h
@@ -26,6 +26,7 @@
 
 #include "projectmodel.h"
 #include "rbrenderinfo.h"
+#include "rbimage.h"
 
 class RBViewport;
 
@@ -50,6 +51,14 @@
     }
     void showViewport(QString name);
 
+    void loadImage(QString name, RBImage* image)
+    {
+        images.insert(name, image);
+    }
+    RBImage* getImage(QString name){ return images.value(name, 0); }
+
+    void setBackdrop(QString filename);
+
     static QColor stringToColor(QString str, QColor fallback);
 
 
@@ -59,10 +68,13 @@
     QColor bgColor;
     QColor fgColor;
     QPixmap* backdrop;
+    QString themeBase;
 
     ProjectModel* project;
 
     QMap<QString, RBViewport*> namedViewports;
+    QMap<QString, RBImage*> images;
+    QMap<QString, QString>* settings;
 
 };
 
diff --git a/utils/themeeditor/graphics/rbviewport.cpp b/utils/themeeditor/graphics/rbviewport.cpp
index 9045016..9d94967 100644
--- a/utils/themeeditor/graphics/rbviewport.cpp
+++ b/utils/themeeditor/graphics/rbviewport.cpp
@@ -41,11 +41,11 @@
         if(info.model()->rowCount(QModelIndex()) > 1)
         {
             /* If there is more than one viewport in the document */
-            displayed = false;
+            setVisible(false);
         }
         else
         {
-            displayed = true;
+            setVisible(true);
         }
     }
     else
@@ -58,7 +58,6 @@
         {
         case '\0':
             customUI = false;
-            displayed = true;
             param = 0;
             break;
 
@@ -66,7 +65,7 @@
             /* A preloaded viewport definition */
             ident = node->params[0].data.text;
             customUI = false;
-            displayed = false;
+            hide();
             info.screen()->loadViewport(ident, this);
             param = 1;
             break;
@@ -77,11 +76,11 @@
             param = 1;
             if(node->params[0].type == skin_tag_parameter::DEFAULT)
             {
-                displayed = true;
+                setVisible(true);
             }
             else
             {
-                displayed = false;
+                hide();
                 info.screen()->loadViewport(ident, this);
             }
             break;
@@ -124,7 +123,11 @@
                        const QStyleOptionGraphicsItem *option, QWidget *widget)
 {
     QColor color = customUI ? Qt::blue : Qt::red;
-    if(displayed)
-        painter->fillRect(size, color);
+    painter->fillRect(size, color);
 }
 
+/* Called at the end of a logical line */
+void RBViewport::newline()
+{
+
+}
diff --git a/utils/themeeditor/graphics/rbviewport.h b/utils/themeeditor/graphics/rbviewport.h
index 5d59ea4..6f67bae 100644
--- a/utils/themeeditor/graphics/rbviewport.h
+++ b/utils/themeeditor/graphics/rbviewport.h
@@ -40,14 +40,13 @@
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                QWidget *widget);
 
-    void show(){ displayed = true; }
+    void newline();
 
 private:
     QRectF size;
     QColor background;
     QColor foreground;
 
-    bool displayed;
     bool customUI;
 
 };
diff --git a/utils/themeeditor/gui/skindocument.cpp b/utils/themeeditor/gui/skindocument.cpp
index 6d28de3..8c98255 100644
--- a/utils/themeeditor/gui/skindocument.cpp
+++ b/utils/themeeditor/gui/skindocument.cpp
@@ -257,7 +257,7 @@
     else
         emit titleChanged(titleText);
 
-    model->render(project);
+    model->render(project, &fileName);
 
     cursorChanged();
 
diff --git a/utils/themeeditor/models/parsetreemodel.cpp b/utils/themeeditor/models/parsetreemodel.cpp
index 4e94bfa..830a646 100644
--- a/utils/themeeditor/models/parsetreemodel.cpp
+++ b/utils/themeeditor/models/parsetreemodel.cpp
@@ -32,6 +32,8 @@
 #include <QMap>
 #include <QDir>
 
+#include <iostream>
+
 ParseTreeModel::ParseTreeModel(const char* document, QObject* parent):
         QAbstractItemModel(parent)
 {
@@ -293,6 +295,16 @@
         settings.insert("themebase", base.canonicalPath());
     }
 
+    if(file)
+    {
+        QString skinFile = *file;
+        QStringList decomp = skinFile.split("/");
+        skinFile = decomp[decomp.count() - 1];
+        skinFile.chop(skinFile.length() - skinFile.lastIndexOf("."));
+        settings.insert("imagepath", settings.value("themebase","") + "/wps/" +
+                        skinFile);
+    }
+
     RBScreen* screen = 0;
     RBRenderInfo info(this, project, &settings, screen);
 
diff --git a/utils/themeeditor/models/parsetreenode.cpp b/utils/themeeditor/models/parsetreenode.cpp
index a74dd23..ed518a4 100644
--- a/utils/themeeditor/models/parsetreenode.cpp
+++ b/utils/themeeditor/models/parsetreenode.cpp
@@ -475,6 +475,7 @@
     return parent;
 }
 
+/* This version is called for the root node and for viewports */
 void ParseTreeNode::render(const RBRenderInfo& info)
 {
     /* Parameters don't get rendered */
@@ -500,5 +501,41 @@
     }
 
     rendered = new RBViewport(element, info);
+
+    for(int i = element->params_count; i < children.count(); i++)
+        children[i]->render(info, dynamic_cast<RBViewport*>(rendered));
 }
 
+/* This version is called for logical lines and such */
+void ParseTreeNode::render(const RBRenderInfo &info, RBViewport* viewport)
+{
+    if(element->type == LINE)
+    {
+        for(int i = 0; i < children.count(); i++)
+            children[i]->render(info, viewport);
+        viewport->newline();
+    }
+    else if(element->type == TAG)
+    {
+        QString filename;
+
+        /* Two switch statements to narrow down the tag name */
+        switch(element->tag->name[0])
+        {
+
+        case 'X':
+
+            switch(element->tag->name[1])
+            {
+            case '\0':
+                /* %X tag */
+                filename = QString(element->params[0].data.text);
+                info.screen()->setBackdrop(filename);
+                break;
+            }
+
+            break;
+
+        }
+    }
+}
diff --git a/utils/themeeditor/models/parsetreenode.h b/utils/themeeditor/models/parsetreenode.h
index bfbd596..127cd78 100644
--- a/utils/themeeditor/models/parsetreenode.h
+++ b/utils/themeeditor/models/parsetreenode.h
@@ -60,6 +60,7 @@
     }
 
     void render(const RBRenderInfo& info);
+    void render(const RBRenderInfo &info, RBViewport* viewport);
 
 private:
     ParseTreeNode* parent;
diff --git a/utils/themeeditor/themeeditor.pro b/utils/themeeditor/themeeditor.pro
index ba3efa9..d98e61f 100644
--- a/utils/themeeditor/themeeditor.pro
+++ b/utils/themeeditor/themeeditor.pro
@@ -37,7 +37,8 @@
     gui/skinviewer.h \
     graphics/rbscreen.h \
     graphics/rbviewport.h \
-    graphics/rbrenderinfo.h
+    graphics/rbrenderinfo.h \
+    graphics/rbimage.h
 SOURCES += main.cpp \
     models/parsetreemodel.cpp \
     models/parsetreenode.cpp \
@@ -51,7 +52,8 @@
     gui/skinviewer.cpp \
     graphics/rbscreen.cpp \
     graphics/rbviewport.cpp \
-    graphics/rbrenderinfo.cpp
+    graphics/rbrenderinfo.cpp \
+    graphics/rbimage.cpp
 OTHER_FILES += README \
     resources/windowicon.png \
     resources/appicon.xcf \