Theme Editor: Implemented conditional rendering, most conditionals should work correctly now

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27169 a1c6a512-1295-4272-9138-f99709370657
diff --git a/utils/themeeditor/graphics/rbimage.cpp b/utils/themeeditor/graphics/rbimage.cpp
index f15d1ed..ce92d2f 100644
--- a/utils/themeeditor/graphics/rbimage.cpp
+++ b/utils/themeeditor/graphics/rbimage.cpp
@@ -49,7 +49,21 @@
 
     }
     else
+    {
+        size = QRectF(0, 0, 0, 0);
         image = 0;
+    }
+}
+
+RBImage::RBImage(const RBImage &other, QGraphicsItem* parent)
+    : QGraphicsItem(parent), tiles(other.tiles), currentTile(other.currentTile)
+{
+    if(other.image)
+        image = new QPixmap(*(other.image));
+    else
+        image = 0;
+    size = other.size;
+    setPos(other.x(), other.y());
 }
 
 RBImage::~RBImage()
diff --git a/utils/themeeditor/graphics/rbimage.h b/utils/themeeditor/graphics/rbimage.h
index cc949d1..abfe8eb 100644
--- a/utils/themeeditor/graphics/rbimage.h
+++ b/utils/themeeditor/graphics/rbimage.h
@@ -29,6 +29,7 @@
 {
 public:
     RBImage(QString file, int tiles, int x, int y, QGraphicsItem* parent = 0);
+    RBImage(const RBImage& other, QGraphicsItem* parent);
     virtual ~RBImage();
 
     QRectF boundingRect() const;
diff --git a/utils/themeeditor/models/parsetreenode.cpp b/utils/themeeditor/models/parsetreenode.cpp
index bdc0c30..1cf7509 100644
--- a/utils/themeeditor/models/parsetreenode.cpp
+++ b/utils/themeeditor/models/parsetreenode.cpp
@@ -530,7 +530,7 @@
     else if(element->type == CONDITIONAL)
     {
         int child = evalTag(info, true, element->children_count).toInt();
-        //children[0]->render(info, viewport);
+        children[child]->render(info, viewport);
     }
 }
 
@@ -568,12 +568,13 @@
                     tile = c - 'a';
             }
 
-            image = info.screen()->getImage(id);
-            if(image)
+            if(info.screen()->getImage(id))
             {
+                image = new RBImage(*(info.screen()->getImage(id)), viewport);
                 image->setTile(tile);
                 image->show();
             }
+
             return true;
 
         case 'l':
@@ -684,5 +685,74 @@
 QVariant ParseTreeNode::evalTag(const RBRenderInfo& info, bool conditional,
                                 int branches)
 {
-    return info.device()->data(QString(element->tag->name));
+    if(!conditional)
+    {
+        return info.device()->data(QString(element->tag->name));
+    }
+    else
+    {
+        /* If we're evaluating for a conditional, we return the child branch
+         * index that should be selected.  For true/false values, this is
+         * 0 for true, 1 for false, and we also have to make sure not to
+         * ever exceed the number of available children
+         */
+
+        int child;
+        QVariant val = info.device()->data("?" + QString(element->tag->name));
+        if(val.isNull())
+            val = info.device()->data(QString(element->tag->name));
+
+        if(val.isNull())
+        {
+            child = 1;
+        }
+        else if(QString(element->tag->name) == "bl")
+        {
+            /* bl has to be scaled to the number of available children, but it
+             * also has an initial -1 value for an unknown state */
+            child = val.toInt();
+            if(child == -1)
+            {
+                child = 0;
+            }
+            else
+            {
+                child = ((branches - 1) * child / 100) + 1;
+            }
+        }
+        else if(QString(element->tag->name) == "px")
+        {
+            child = val.toInt();
+            child = branches * child / 100;
+        }
+        else if(val.type() == QVariant::Bool)
+        {
+            /* Boolean values have to be reversed, because conditionals are
+             * always of the form %?tag<true|false>
+             */
+            if(val.toBool())
+                child = 0;
+            else
+                child = 1;
+        }
+        else if(val.type() == QVariant::String)
+        {
+            if(val.toString().length() > 0)
+                child = 0;
+            else
+                child = 1;
+        }
+        else
+        {
+            child = val.toInt();
+        }
+
+        if(child < 0)
+            child = 0;
+
+        if(child < branches)
+            return child;
+        else
+            return branches - 1;
+    }
 }