some code in the exhibit ui, and first stab at laying out the
[laserbrain_demo] / src / exman.cc
index d6cac9c..e5cdd9f 100644 (file)
@@ -4,8 +4,11 @@
 #include "exhibit.h"
 #include "blob_exhibit.h"
 #include "treestore.h"
+#include "app.h"
+#include "geomdraw.h"
 
 static Exhibit *create_exhibit(const char *type);
+static void clean_desc_text(char *dest, const char *src);
 
 
 ExhibitSlot::ExhibitSlot(Exhibit *ex)
@@ -114,13 +117,10 @@ ExhibitManager::~ExhibitManager()
 
 void ExhibitManager::clear()
 {
-       int num = (int)items.size();
-       for(int i=0; i<num; i++) {
-               delete items[i];
-       }
+       // not deleting exhibit objects, as they will be deleted the own_scn destructor
        items.clear();
 
-       num = (int)exslots.size();
+       int num = (int)exslots.size();
        for(int i=0; i<num; i++) {
                delete exslots[i];
        }
@@ -134,6 +134,8 @@ void ExhibitManager::add(Exhibit *ex)
        std::vector<Exhibit*>::iterator it = std::find(items.begin(), items.end(), ex);
        if(it == items.end()) {
                items.push_back(ex);
+               own_scn->add_object(ex);
+               if(ex->node) own_scn->add_node(ex->node);
        }
 }
 
@@ -142,6 +144,8 @@ bool ExhibitManager::remove(Exhibit *ex)
        std::vector<Exhibit*>::iterator it = std::find(items.begin(), items.end(), ex);
        if(it != items.end()) {
                items.erase(it);
+               own_scn->remove_object(ex);
+               if(ex->node) own_scn->remove_node(ex->node);
                return true;
        }
        return false;
@@ -156,8 +160,10 @@ bool ExhibitManager::load(MetaScene *mscn, const char *fname)
                return false;
        }
 
-       // create our own scene to manage all exhibits not already in an existing scene
-       // and add it to the metascene
+       /* create our own scene to manage all exhibits not already in an existing scene
+        * and add it to the metascene.
+        * Also exhibit drawing happens due to the renderer drawing the metascene
+        */
        if(!own_scn) {
                own_scn = new Scene;
                own_scn->name = "ad-hoc exhibits";
@@ -192,13 +198,15 @@ bool ExhibitManager::load(MetaScene *mscn, const char *fname)
                                }
                        }
 
+                       // add everything to our data structures
+                       // equivalent to add_exhibit(ex), but without all the searching
+                       own_scn->add_object(ex);
                        if(!snode) {
                                snode = new SceneNode;
                                snode->set_name(ex->get_name());
                                own_scn->add_node(snode);
                        }
                        ex->set_node(snode);
-
                        items.push_back(ex);
 
                        float *apos = ts_get_attr_vec(node, "pos");
@@ -237,7 +245,10 @@ bool ExhibitManager::load(MetaScene *mscn, const char *fname)
                                ExData exd;
 
                                if(desc) {
-                                       exd.text = std::string(desc);
+                                       char *fixed_desc = new char[strlen(desc) + 1];
+                                       clean_desc_text(fixed_desc, desc);
+                                       exd.text = std::string(fixed_desc);
+                                       delete [] fixed_desc;
                                }
                                if(voice) {
                                        exd.voice = new OggVorbisStream;
@@ -336,9 +347,10 @@ void ExhibitManager::draw() const
 {
        int num = items.size();
        for(int i=0; i<num; i++) {
-               items[i]->pre_draw();
-               items[i]->draw();
-               items[i]->post_draw();
+               if(exsel_hover.ex == items[i]) {
+                       const AABox &bvol = items[i]->get_aabox();
+                       draw_geom_object(&bvol);
+               }
        }
 }
 
@@ -360,3 +372,27 @@ static Exhibit *create_exhibit(const char *type)
        error_log("unknown exhibit type: %s\n", type);
        return 0;
 }
+
+/* clean up description text to be more easily layed out later.
+ * more specifically:
+ *  - remove redundant spaces
+ *  - remove all newlines except as paragraph separators
+ *  - remove all other whitespace chars
+ * destination buffer must be as large as the source buffer
+ */
+static void clean_desc_text(char *dest, const char *src)
+{
+       while(*src) {
+               if(isspace(*src)) {
+                       if(*src == '\n' && *(src + 1) == '\n') {
+                               *dest++ = '\n';
+                       } else {
+                               *dest++ = ' ';
+                       }
+                       while(*src && isspace(*src)) ++src;
+               } else {
+                       *dest++ = *src++;
+               }
+       }
+       *dest = 0;
+}