]> git.mxchange.org Git - flightgear.git/commitdiff
Support a log-list widget in PUI.
authorJames Turner <zakalawe@mac.com>
Fri, 8 Feb 2013 19:39:41 +0000 (19:39 +0000)
committerJames Turner <zakalawe@mac.com>
Fri, 8 Feb 2013 19:39:41 +0000 (19:39 +0000)
Add a puaListBox which can show the contents of a log-buffer. Currently only two buffer sources are supported more to follow (and the dialog XML updates).

src/GUI/FGPUIDialog.cxx
src/GUI/FGPUIDialog.hxx
src/GUI/new_gui.cxx
src/Scripting/NasalSys.cxx
src/Scripting/NasalSys.hxx

index 70ba763f4b155753afee914cb3ad58e889b484e9..33cbc52885b15b02b42c0c0ed273118797935ddf 100644 (file)
@@ -6,6 +6,8 @@
 
 #include <simgear/structure/SGBinding.hxx>
 #include <simgear/props/props_io.hxx>
+#include <simgear/debug/BufferedLogCallback.hxx>
+#include <simgear/scene/tsync/terrasync.hxx>
 
 #include <Scripting/NasalSys.hxx>
 #include <Main/fg_os.hxx>
@@ -162,6 +164,25 @@ private:
   bool _inHit;
 };
 
+class LogList : public puaList, public FGPUIDialog::ActiveWidget, public GUI_ID {
+public:
+    LogList(int x1, int y1, int x2, int y2, int sw) :
+        puaList(x1, y1, x2, y2, sw),
+        GUI_ID(FGCLASS_LOGLIST)
+    {
+        m_buffer = NULL;
+        m_stamp = 0;
+    }
+    
+    void setBuffer(simgear::BufferedLogCallback* buf);
+    
+    virtual void update();
+private:
+    std::vector<unsigned char*> m_items;
+    simgear::BufferedLogCallback* m_buffer;
+    unsigned int m_stamp;
+};
+
 class fgSelectBox : public fgValueList, public puaSelectBox {
 public:
   fgSelectBox(int x1, int y1, int x2, int y2, SGPropertyNode *p) :
@@ -749,6 +770,10 @@ FGPUIDialog::update ()
     _conditionalObjects[j]->update(this);
   }
   
+  for (unsigned int i = 0; i < _activeWidgets.size(); i++) {
+    _activeWidgets[i]->update();
+  }
+  
   if (_needsRelayout) {
     relayout();
   }
@@ -1024,6 +1049,21 @@ FGPUIDialog::makeObject (SGPropertyNode *props, int parentWidth, int parentHeigh
         ScrolledWaypointList* obj = new ScrolledWaypointList(x, y, width, height);
         setupObject(obj, props);
         return obj;
+        
+    } else if (type == "loglist") {
+        LogList* obj = new LogList(x, y, width, height, 20);
+        string logClass = props->getStringValue("logclass");
+        if (logClass == "terrasync") {
+          simgear::SGTerraSync* tsync = (simgear::SGTerraSync*) globals->get_subsystem("terrasync");
+          obj->setBuffer(tsync->log());
+        } else {
+          FGNasalSys* nasal = (FGNasalSys*) globals->get_subsystem("nasal");
+          obj->setBuffer(nasal->log());
+        }
+
+        setupObject(obj, props);
+        _activeWidgets.push_back(obj);
+        return obj;
     } else {
         return 0;
     }
@@ -1474,6 +1514,34 @@ fgList::update()
     setTopItem(top);
 }
 
+////////////////////////////////////////////////////////////////////////
+// Implementation of fgLogList
+////////////////////////////////////////////////////////////////////////
+
+void LogList::update()
+{
+    if (!m_buffer) return;
+    
+    if (m_stamp != m_buffer->stamp()) {
+        m_stamp = m_buffer->threadsafeCopy(m_items);
+        m_items.push_back(NULL); // terminator value
+        newList((char**) m_items.data());
+        setTopItem(m_items.size() - 1); // scroll to bottom of list
+    }
+}
+
+void LogList::setBuffer(simgear::BufferedLogCallback* buf)
+{
+    m_buffer = buf;
+    m_stamp = m_buffer->stamp() - 1; // force an update
+    update();
+}
+
+////////////////////////////////////////////////////////////////////////
+// Implementation of fgComboBox 
+////////////////////////////////////////////////////////////////////////
+
+
 void fgComboBox::update()
 {
   if (_inHit) {
index 52ea117b22d54b3651ef8f50f3a55dd75522059c..a21c4ec8c575b4d98d7edf29a2c34e3707ca2514 100644 (file)
@@ -100,6 +100,12 @@ public:
     void setNeedsLayout() {
       _needsRelayout = true;
     }
+    
+    class ActiveWidget
+    {
+    public:
+        virtual void update() = 0;
+    };
 private:
 
     enum {
@@ -191,6 +197,8 @@ private:
     
     typedef SGSharedPtr<ConditionalObject> ConditionalObjectRef;
     std::vector<ConditionalObjectRef> _conditionalObjects;
+    
+    std::vector<ActiveWidget*> _activeWidgets;
 };
 
 #endif // __DIALOG_HXX
index 864352b1a578ee6116b2a60ee68d268b1838ef92..eff8bbe2fb3379078c7d1531c4e33ce1dab0da30 100644 (file)
@@ -142,6 +142,7 @@ NewGUI::unbind ()
 void
 NewGUI::update (double delta_time_sec)
 {
+    SG_UNUSED(delta_time_sec);
     map<string,FGDialog *>::iterator iter = _active_dialogs.begin();
     for(/**/; iter != _active_dialogs.end(); iter++)
         iter->second->update();
index 6ae142a75ed123adecc74afaa6bce954b2eaf8a6..537adf1f5b825e752b67a87d2e88570e6f9ef96c 100644 (file)
@@ -27,6 +27,7 @@
 #include <simgear/structure/commands.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/structure/event_mgr.hxx>
+#include <simgear/debug/BufferedLogCallback.hxx>
 
 #include "NasalSys.hxx"
 #include "NasalPositioned.hxx"
@@ -109,6 +110,10 @@ FGNasalSys::FGNasalSys()
     _gcHash = naNil();
     _nextGCKey = 0; // Any value will do
     _callCount = 0;
+    
+    _log = new simgear::BufferedLogCallback(SG_NASAL, SG_INFO);
+    _log->truncateAt(255);
+    sglog().addCallback(_log);
 }
 
 // Utility.  Sets a named key in a hash by C string, rather than nasal
index 83efde6e427ab94204736701714eb95c5e5ab548..7fa3fb7ae220138fe9241d62bedf3ff836afb819 100644 (file)
@@ -16,6 +16,8 @@ class FGNasalScript;
 class FGNasalListener;
 class SGCondition;
 
+namespace simgear { class BufferedLogCallback; }
+
 /** Nasal model data container.
  * load and unload methods must be run in main thread (not thread-safe). */
 class FGNasalModelData : public SGReferenced
@@ -151,6 +153,11 @@ public:
     // when done.
     int gcSave(naRef r);
     void gcRelease(int key);
+    
+    /// retrive the associated log object, for displaying log
+    /// output somewhere (a UI, presumably)
+    simgear::BufferedLogCallback* log() const
+    { return _log; }
 private:
     friend class FGNasalScript;
     friend class FGNasalListener;
@@ -195,7 +202,9 @@ private:
     naRef _gcHash;
     int _callCount;
 
-    public: void handleTimer(NasalTimer* t);
+    simgear::BufferedLogCallback* _log;
+public:
+    void handleTimer(NasalTimer* t);
 };