1
0
Fork 0

Support a log-list widget in PUI.

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).
This commit is contained in:
James Turner 2013-02-08 19:39:41 +00:00
parent e08eb7457e
commit ce9afecdbd
5 changed files with 92 additions and 1 deletions

View 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) {

View 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

View 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();

View 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

View 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);
};