Theme Editor: Implemented subline rendering, including conditional subline times

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27182 a1c6a512-1295-4272-9138-f99709370657
diff --git a/utils/themeeditor/graphics/rbrenderinfo.cpp b/utils/themeeditor/graphics/rbrenderinfo.cpp
index 289d730..3116034 100644
--- a/utils/themeeditor/graphics/rbrenderinfo.cpp
+++ b/utils/themeeditor/graphics/rbrenderinfo.cpp
@@ -29,6 +29,11 @@
 {
 }
 
+RBRenderInfo::RBRenderInfo()
+    : mProject(0), mSettings(0), mDevice(0), mScreen(0), mModel(0)
+{
+}
+
 RBRenderInfo::RBRenderInfo(const RBRenderInfo &other)
 {
     mProject = other.mProject;
diff --git a/utils/themeeditor/graphics/rbrenderinfo.h b/utils/themeeditor/graphics/rbrenderinfo.h
index c65c4de..0e21938 100644
--- a/utils/themeeditor/graphics/rbrenderinfo.h
+++ b/utils/themeeditor/graphics/rbrenderinfo.h
@@ -35,6 +35,7 @@
     RBRenderInfo(ParseTreeModel* model,  ProjectModel* project,
                  QMap<QString, QString>* settings, DeviceState* device,
                  RBScreen* screen);
+    RBRenderInfo();
     RBRenderInfo(const RBRenderInfo& other);
     virtual ~RBRenderInfo();
 
diff --git a/utils/themeeditor/models/parsetreenode.cpp b/utils/themeeditor/models/parsetreenode.cpp
index 1cf7509..a2781d2 100644
--- a/utils/themeeditor/models/parsetreenode.cpp
+++ b/utils/themeeditor/models/parsetreenode.cpp
@@ -532,6 +532,47 @@
         int child = evalTag(info, true, element->children_count).toInt();
         children[child]->render(info, viewport);
     }
+    else if(element->type == SUBLINES)
+    {
+        /* First we build a list of the times for each branch */
+        QList<double> times;
+        for(int i = 0; i < children.count() ; i++)
+            times.append(findBranchTime(children[i], info));
+
+        /* Now we figure out which branch to select */
+        double timeLeft = info.device()->data(QString("?pc")).toDouble();
+        int branch = 0;
+        while(timeLeft > 0)
+        {
+            timeLeft -= times[branch];
+            if(timeLeft >= 0)
+                branch++;
+            else
+                break;
+            if(branch >= times.count())
+                branch = 0;
+        }
+
+        /* In case we end up on a disabled branch, skip ahead.  If we find that
+         * all the branches are disabled, don't render anything
+         */
+        int originalBranch = branch;
+        while(times[branch] == 0)
+        {
+            branch++;
+            if(branch == originalBranch)
+            {
+                branch = -1;
+                break;
+            }
+            if(branch >= times.count())
+                branch = 0;
+        }
+
+        /* ...and finally render the selected branch */
+        if(branch >= 0)
+            children[branch]->render(info, viewport);
+    }
 }
 
 bool ParseTreeNode::execTag(const RBRenderInfo& info, RBViewport* viewport)
@@ -756,3 +797,34 @@
             return branches - 1;
     }
 }
+
+double ParseTreeNode::findBranchTime(ParseTreeNode *branch,
+                                     const RBRenderInfo& info)
+{
+    double retval = 2;
+    for(int i = 0; i < branch->children.count(); i++)
+    {
+        ParseTreeNode* current = branch->children[i];
+        if(current->element->type == TAG)
+        {
+            if(current->element->tag->name[0] == 't'
+               && current->element->tag->name[1] == '\0')
+            {
+                retval = atof(current->element->params[0].data.text);
+            }
+        }
+        else if(current->element->type == CONDITIONAL)
+        {
+            retval = findConditionalTime(current, info);
+        }
+    }
+    return retval;
+}
+
+double ParseTreeNode::findConditionalTime(ParseTreeNode *conditional,
+                                          const RBRenderInfo& info)
+{
+    int child = conditional->evalTag(info, true,
+                                     conditional->children.count()).toInt();
+    return findBranchTime(conditional->children[child], info);
+}
diff --git a/utils/themeeditor/models/parsetreenode.h b/utils/themeeditor/models/parsetreenode.h
index f85460d..7d7154a 100644
--- a/utils/themeeditor/models/parsetreenode.h
+++ b/utils/themeeditor/models/parsetreenode.h
@@ -62,6 +62,10 @@
     void render(const RBRenderInfo& info);
     void render(const RBRenderInfo &info, RBViewport* viewport);
 
+    double findBranchTime(ParseTreeNode* branch, const RBRenderInfo& info);
+    double findConditionalTime(ParseTreeNode* conditional,
+                               const RBRenderInfo& info);
+
 private:
 
     bool execTag(const RBRenderInfo& info, RBViewport* viewport);
diff --git a/utils/themeeditor/resources/deviceoptions b/utils/themeeditor/resources/deviceoptions
index b9081c6..5d3c5fc 100644
--- a/utils/themeeditor/resources/deviceoptions
+++ b/utils/themeeditor/resources/deviceoptions
@@ -96,6 +96,7 @@
 [Playlist/Song Info]
 px ; Percent Played ; spin(0,100) ; 50
 pc ; Current Time In Song ; text ; 1:00
+?pc ; Time In Song (Conditional) ; fspin(0,5000) ; 60
 pe ; Playlist Entries ; spin(0,1000) ; 20
 pn ; Playlist Name ; text ; Current Playlist
 pp ; Playlist Position ; spin(0,1000) ; 10