JS GUI interface
This was SVN commit r666.
This commit is contained in:
parent
a8f48ff7e0
commit
af9c336b43
@ -71,22 +71,48 @@ void CButton::HandleMessage(const SGUIMessage &Message)
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_OVER:
|
||||
ScriptEvent("MouseOver");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_ENTER:
|
||||
ScriptEvent("MouseEnter");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_LEAVE:
|
||||
ScriptEvent("MouseLeave");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_PRESS_LEFT:
|
||||
ScriptEvent("MouseLeftPress");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_RELEASE_LEFT:
|
||||
ScriptEvent("MouseLeftRelease");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_DOWN_LEFT:
|
||||
ScriptEvent("MouseLeftDown");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_PRESS_RIGHT:
|
||||
ScriptEvent("MouseRightPress");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_RELEASE_RIGHT:
|
||||
ScriptEvent("MouseRightRelease");
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_DOWN_RIGHT:
|
||||
ScriptEvent("MouseRightDown");
|
||||
break;
|
||||
|
||||
case GUIM_PRESSED:
|
||||
GetGUI()->TEMPmessage = "Button " + string((const TCHAR*)m_Name) + " was pressed!";
|
||||
ScriptEvent("Press");
|
||||
break;
|
||||
|
||||
case GUIM_LOAD:
|
||||
ScriptEvent("Load");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -93,6 +93,8 @@ void CCheckBox::HandleMessage(const SGUIMessage &Message)
|
||||
GUI<bool>::SetSetting(this, "checked", checked);
|
||||
|
||||
//GetGUI()->TEMPmessage = "Check box " + string((const TCHAR*)m_Name) + " was " + (m_Settings.m_Checked?"checked":"unchecked");
|
||||
|
||||
ScriptEvent("Press");
|
||||
} break;
|
||||
|
||||
default:
|
||||
|
@ -5,7 +5,6 @@ gee@pyro.nu
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#undef new // if it was redefined for leak detection, since xerces doesn't like it
|
||||
|
||||
#include "GUI.h"
|
||||
|
||||
@ -15,28 +14,35 @@ gee@pyro.nu
|
||||
#include "CCheckBox.h"
|
||||
#include "CRadioButton.h"
|
||||
|
||||
#include "XML.h"
|
||||
//#include <xercesc/dom/DOM.hpp>
|
||||
//#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
//#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
//#include <xercesc/util/XMLString.hpp>
|
||||
//#include <xercesc/util/PlatformUtils.hpp>
|
||||
#include "ps/Xeromyces.h"
|
||||
|
||||
#include "XercesErrorHandler.h"
|
||||
#include "Prometheus.h"
|
||||
#include "input.h"
|
||||
#include "OverlayText.h"
|
||||
// TODO Gee: Whatever include CRect/CPos/CSize
|
||||
#include "Overlay.h"
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// namespaces used
|
||||
XERCES_CPP_NAMESPACE_USE
|
||||
//XERCES_CPP_NAMESPACE_USE
|
||||
using namespace std;
|
||||
|
||||
#include "sysdep/ia32.h"
|
||||
#include "ps/CLogger.h"
|
||||
#define XERO_TIME
|
||||
|
||||
// Class for global JavaScript object
|
||||
JSClass GUIClass = {
|
||||
"GUIClass", 0,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
};
|
||||
|
||||
|
||||
extern int g_xres, g_yres;
|
||||
|
||||
@ -74,10 +80,12 @@ int CGUI::HandleEvent(const SDL_Event* ev)
|
||||
// sprintf(buf, "type = %d", ev->type);
|
||||
//TEMPmessage = buf;
|
||||
|
||||
// Update m_MouseButtons. (BUTTONUP is handled later.)
|
||||
if (ev->type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
// sprintf(buf, "button = %d", ev->button.button);
|
||||
//TEMPmessage = buf;
|
||||
// (0,1,2) = (LMB,RMB,MMB)
|
||||
if (ev->button.button < 3)
|
||||
m_MouseButtons |= (1 << ev->button.button);
|
||||
}
|
||||
|
||||
// JW: (pre|post)process omitted; what're they for? why would we need any special button_released handling?
|
||||
@ -191,17 +199,32 @@ int CGUI::HandleEvent(const SDL_Event* ev)
|
||||
}
|
||||
*/
|
||||
|
||||
// BUTTONUP's effect on m_MouseButtons is handled after
|
||||
// everything else, so that e.g. 'press' handlers (activated
|
||||
// on button up) see which mouse button had been pressed.
|
||||
if (ev->type == SDL_MOUSEBUTTONUP)
|
||||
{
|
||||
// (0,1,2) = (LMB,RMB,MMB)
|
||||
if (ev->button.button < 3)
|
||||
m_MouseButtons &= ~(1 << ev->button.button);
|
||||
}
|
||||
|
||||
return EV_PASS;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Constructor / Destructor
|
||||
//-------------------------------------------------------------------
|
||||
CGUI::CGUI() : m_InternalNameNumber(0)
|
||||
CGUI::CGUI() : m_InternalNameNumber(0), m_MouseButtons(0)
|
||||
{
|
||||
m_BaseObject = new CGUIDummyObject;
|
||||
m_BaseObject->SetGUI(this);
|
||||
|
||||
// Construct the parent object for all GUI JavaScript things
|
||||
m_ScriptObject = (void*)JS_NewObject(g_ScriptingHost.getContext(), &GUIClass, NULL, NULL);
|
||||
assert(m_ScriptObject != NULL); // How should it handle errors?
|
||||
JS_AddRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
|
||||
|
||||
// This will make this invisible, not add
|
||||
//m_BaseObject->SetName(BASE_OBJECT_NAME);
|
||||
}
|
||||
@ -210,6 +233,11 @@ CGUI::~CGUI()
|
||||
{
|
||||
if (m_BaseObject)
|
||||
delete m_BaseObject;
|
||||
|
||||
if (m_ScriptObject)
|
||||
// Let it be garbage-collected
|
||||
JS_RemoveRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@ -307,6 +335,10 @@ void CGUI::Process()
|
||||
|
||||
void CGUI::Draw()
|
||||
{
|
||||
// Clear the depth buffer, so the GUI is
|
||||
// drawn on top of everything else
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
@ -462,6 +494,16 @@ bool CGUI::ObjectExists(const CStr& Name) const
|
||||
return m_pAllObjects.count(Name) != 0;
|
||||
}
|
||||
|
||||
IGUIObject* CGUI::FindObjectByName(const CStr& Name) const
|
||||
{
|
||||
map_pObjects::const_iterator it = m_pAllObjects.find(Name);
|
||||
if (it == m_pAllObjects.end())
|
||||
return NULL;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
// private struct used only in GenerateText(...)
|
||||
struct SGenerateTextImage
|
||||
{
|
||||
@ -804,199 +846,158 @@ void CGUI::LoadXMLFile(const string &Filename)
|
||||
// we can later check if this has increased
|
||||
m_Errors = 0;
|
||||
|
||||
// Initialize XML library
|
||||
XMLPlatformUtils::Initialize();
|
||||
CXeromyces XeroFile;
|
||||
XeroFile.Load(Filename.c_str());
|
||||
|
||||
bool ParseFailed = false;
|
||||
|
||||
XMBElement node = XeroFile.getRoot();
|
||||
|
||||
// Check root element's (node) name so we know what kind of
|
||||
// data we'll be expecting
|
||||
std::wstring root_name = XeroFile.getElementString(node.getNodeName());
|
||||
|
||||
if (root_name == L"objects")
|
||||
{
|
||||
// Create parser instance
|
||||
XercesDOMParser *parser = new XercesDOMParser();
|
||||
Xeromyces_ReadRootObjects(node, &XeroFile);
|
||||
|
||||
bool ParseFailed = false;
|
||||
|
||||
if (parser)
|
||||
{
|
||||
// Setup parser
|
||||
parser->setValidationScheme(XercesDOMParser::Val_Auto);
|
||||
parser->setDoNamespaces(false);
|
||||
parser->setDoSchema(false);
|
||||
parser->setCreateEntityReferenceNodes(false);
|
||||
|
||||
// Set cosutomized error handler
|
||||
CXercesErrorHandler *errorHandler = new CXercesErrorHandler();
|
||||
parser->setErrorHandler(errorHandler);
|
||||
|
||||
/// g_nemLog("*** Xerces XML Parsing Errors");
|
||||
|
||||
// Get main node
|
||||
XMLCh *fname=XMLString::transcode(Filename.c_str());
|
||||
LocalFileInputSource source(fname);
|
||||
XMLString::release(&fname);
|
||||
|
||||
// parse
|
||||
parser->parse(source);
|
||||
|
||||
// Check how many errors
|
||||
ParseFailed = parser->getErrorCount() != 0;
|
||||
|
||||
// Parse Failed?
|
||||
if (!ParseFailed)
|
||||
{
|
||||
DOMDocument *doc = parser->getDocument();
|
||||
DOMElement *node = doc->getDocumentElement();
|
||||
|
||||
// Check root element's (node) name so we know what kind of
|
||||
// data we'll be expecting
|
||||
CStr root_name = XMLTranscode( node->getNodeName() );
|
||||
|
||||
if (root_name == CStr("objects"))
|
||||
{
|
||||
Xerces_ReadRootObjects(node);
|
||||
|
||||
// Re-cache all values so these gets cached too.
|
||||
//UpdateResolution();
|
||||
}
|
||||
else
|
||||
if (root_name == CStr("sprites"))
|
||||
{
|
||||
Xerces_ReadRootSprites(node);
|
||||
}
|
||||
else
|
||||
if (root_name == CStr("styles"))
|
||||
{
|
||||
Xerces_ReadRootStyles(node);
|
||||
}
|
||||
else
|
||||
if (root_name == CStr("setup"))
|
||||
{
|
||||
Xerces_ReadRootSetup(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO Gee: Output in log
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Now report if any other errors occured
|
||||
if (m_Errors > 0)
|
||||
{
|
||||
/// g_console.submit("echo GUI Tree Creation Reports %d errors", m_Errors);
|
||||
}
|
||||
|
||||
delete parser->getErrorHandler();
|
||||
delete parser;
|
||||
// Re-cache all values so these gets cached too.
|
||||
//UpdateResolution();
|
||||
}
|
||||
XMLPlatformUtils::Terminate();
|
||||
else
|
||||
if (root_name == L"sprites")
|
||||
{
|
||||
Xeromyces_ReadRootSprites(node, &XeroFile);
|
||||
}
|
||||
else
|
||||
if (root_name == L"styles")
|
||||
{
|
||||
Xeromyces_ReadRootStyles(node, &XeroFile);
|
||||
}
|
||||
else
|
||||
if (root_name == L"setup")
|
||||
{
|
||||
Xeromyces_ReadRootSetup(node, &XeroFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO Gee: Output in log
|
||||
}
|
||||
|
||||
// Now report if any other errors occured
|
||||
if (m_Errors > 0)
|
||||
{
|
||||
/// g_console.submit("echo GUI Tree Creation Reports %d errors", m_Errors);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// XML Reading Xerces Specific Sub-Routines
|
||||
// XML Reading Xeromyces Specific Sub-Routines
|
||||
//===================================================================
|
||||
|
||||
void CGUI::Xerces_ReadRootObjects(DOMElement *pElement)
|
||||
void CGUI::Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <object> elements
|
||||
DOMNodeList *children = pElement->getChildNodes();
|
||||
for (u16 i=0; i<children->getLength(); ++i)
|
||||
XMBElementList children = Element.getChildNodes();
|
||||
for (int i=0; i<children.Count; ++i)
|
||||
{
|
||||
DOMNode *child = children->item(i);
|
||||
//debug_out("Object %d\n", i);
|
||||
XMBElement child = children.item(i);
|
||||
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
{
|
||||
// Read in this whole object into the GUI
|
||||
DOMElement *element = (DOMElement*)child;
|
||||
Xerces_ReadObject(element, m_BaseObject);
|
||||
}
|
||||
// Read in this whole object into the GUI
|
||||
Xeromyces_ReadObject(child, pFile, m_BaseObject);
|
||||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadRootSprites(DOMElement *pElement)
|
||||
void CGUI::Xeromyces_ReadRootSprites(XMBElement Element, CXeromyces* pFile)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <sprite> elements
|
||||
DOMNodeList *children = pElement->getChildNodes();
|
||||
for (u16 i=0; i<children->getLength(); ++i)
|
||||
XMBElementList children = Element.getChildNodes();
|
||||
for (int i=0; i<children.Count; ++i)
|
||||
{
|
||||
DOMNode *child = children->item(i);
|
||||
XMBElement child = children.item(i);
|
||||
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
{
|
||||
// Read in this whole object into the GUI
|
||||
DOMElement *element = (DOMElement*)child;
|
||||
Xerces_ReadSprite(element);
|
||||
}
|
||||
// Read in this whole object into the GUI
|
||||
Xeromyces_ReadSprite(child, pFile);
|
||||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadRootStyles(DOMElement *pElement)
|
||||
void CGUI::Xeromyces_ReadRootStyles(XMBElement Element, CXeromyces* pFile)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <styles> elements
|
||||
DOMNodeList *children = pElement->getChildNodes();
|
||||
for (u16 i=0; i<children->getLength(); ++i)
|
||||
XMBElementList children = Element.getChildNodes();
|
||||
for (int i=0; i<children.Count; ++i)
|
||||
{
|
||||
DOMNode *child = children->item(i);
|
||||
XMBElement child = children.item(i);
|
||||
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
{
|
||||
// Read in this whole object into the GUI
|
||||
DOMElement *element = (DOMElement*)child;
|
||||
Xerces_ReadStyle(element);
|
||||
}
|
||||
// Read in this whole object into the GUI
|
||||
Xeromyces_ReadStyle(child, pFile);
|
||||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadRootSetup(DOMElement *pElement)
|
||||
void CGUI::Xeromyces_ReadRootSetup(XMBElement Element, CXeromyces* pFile)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <icon>, <scrollbar> or <tooltip>.
|
||||
DOMNodeList *children = pElement->getChildNodes();
|
||||
for (u16 i=0; i<children->getLength(); ++i)
|
||||
XMBElementList children = Element.getChildNodes();
|
||||
for (int i=0; i<children.Count; ++i)
|
||||
{
|
||||
DOMNode *child = children->item(i);
|
||||
XMBElement child = children.item(i);
|
||||
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
// Read in this whole object into the GUI
|
||||
|
||||
std::wstring name = pFile->getElementString(child.getNodeName());
|
||||
|
||||
if (name == L"scrollbar")
|
||||
{
|
||||
// Read in this whole object into the GUI
|
||||
DOMElement *element = (DOMElement*)child;
|
||||
|
||||
CStr name = XMLTranscode( element->getNodeName() );
|
||||
|
||||
if (name == CStr("scrollbar"))
|
||||
{
|
||||
Xerces_ReadScrollBarStyle(element);
|
||||
}
|
||||
// No need for else, we're using DTD.
|
||||
Xeromyces_ReadScrollBarStyle(child, pFile);
|
||||
}
|
||||
// No need for else, we're using DTD.
|
||||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
||||
void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent)
|
||||
{
|
||||
assert(pParent && pElement);
|
||||
u16 i;
|
||||
assert(pParent);
|
||||
int i;
|
||||
|
||||
// Our object we are going to create
|
||||
IGUIObject *object = NULL;
|
||||
|
||||
XMBAttributeList attributes = Element.getAttributes();
|
||||
|
||||
// Well first of all we need to determine the type
|
||||
CStr type = XMLTranscode( pElement->getAttribute( (XMLCh*)L"type" ) );
|
||||
std::wstring type = attributes.getNamedItem( pFile->getAttributeID(L"type") );
|
||||
|
||||
// Construct object from specified type
|
||||
// henceforth, we need to do a rollback before aborting.
|
||||
// i.e. releasing this object
|
||||
object = ConstructObject(type);
|
||||
object = ConstructObject(tocstr(type));
|
||||
|
||||
if (!object)
|
||||
{
|
||||
// Report error that object was unsuccessfully loaded
|
||||
ReportParseError(CStr("Unrecognized type: ") + type);
|
||||
ReportParseError(CStr("Unrecognized type: ") + tocstr(type));
|
||||
|
||||
delete object;
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache some IDs for element attribute names, to avoid string comparisons
|
||||
#define ELMT(x) int elmt_##x = pFile->getElementID(L#x)
|
||||
#define ATTR(x) int attr_##x = pFile->getAttributeID(L#x)
|
||||
ELMT(object);
|
||||
ELMT(action);
|
||||
ATTR(style);
|
||||
ATTR(type);
|
||||
ATTR(name);
|
||||
ATTR(z);
|
||||
ATTR(on);
|
||||
|
||||
//
|
||||
// Read Style and set defaults
|
||||
//
|
||||
@ -1004,7 +1005,7 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
||||
//
|
||||
// Always load default (if it's available) first!
|
||||
//
|
||||
CStr argStyle = XMLTranscode( pElement->getAttribute( (XMLCh*)L"style" ) );
|
||||
CStr argStyle = tocstr(attributes.getNamedItem(attr_style));
|
||||
|
||||
if (m_Styles.count(CStr("default")) == 1)
|
||||
object->LoadStyle(*this, CStr("default"));
|
||||
@ -1028,41 +1029,38 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
||||
bool ManuallySetZ = false; // if z has been manually set, this turn true
|
||||
|
||||
// Now we can iterate all attributes and store
|
||||
DOMNamedNodeMap *attributes = pElement->getAttributes();
|
||||
for (i=0; i<attributes->getLength(); ++i)
|
||||
for (i=0; i<attributes.Count; ++i)
|
||||
{
|
||||
DOMAttr *attr = (DOMAttr*)attributes->item(i);
|
||||
CStr attr_name = XMLTranscode( attr->getName() );
|
||||
CStr attr_value = XMLTranscode( attr->getValue() );
|
||||
XMBAttribute attr = attributes.item(i);
|
||||
|
||||
// If value is "null", then it is equivalent as never being entered
|
||||
if (attr_value == CStr("null"))
|
||||
if (attr.Value == L"null")
|
||||
continue;
|
||||
|
||||
// Ignore "type" and "style", we've already checked it
|
||||
if (attr_name == CStr("type") || attr_name == CStr("style") )
|
||||
if (attr.Name == attr_type || attr.Name == attr_style )
|
||||
continue;
|
||||
|
||||
// Also the name needs some special attention
|
||||
if (attr_name == CStr("name"))
|
||||
if (attr.Name == attr_name)
|
||||
{
|
||||
object->SetName(attr_value);
|
||||
object->SetName(tocstr(attr.Value));
|
||||
NameSet = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attr_name == CStr("z"))
|
||||
if (attr.Name == attr_z)
|
||||
ManuallySetZ = true;
|
||||
|
||||
// Try setting the value
|
||||
try
|
||||
{
|
||||
object->SetSetting(attr_name, attr_value);
|
||||
object->SetSetting(tocstr(pFile->getAttributeString(attr.Name)), tocstr(attr.Value));
|
||||
}
|
||||
catch (PS_RESULT e)
|
||||
{
|
||||
UNUSED(e);
|
||||
ReportParseError(CStr("Can't set \"") + attr_name + CStr("\" to \"") + attr_value + CStr("\""));
|
||||
ReportParseError(CStr("Can't set \"") + tocstr(pFile->getAttributeString(attr.Name)) + CStr("\" to \"") + tocstr(attr.Value) + CStr("\""));
|
||||
|
||||
// This is not a fatal error
|
||||
}
|
||||
@ -1075,63 +1073,50 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
||||
++m_InternalNameNumber;
|
||||
}
|
||||
|
||||
|
||||
CStr caption = tocstr(Element.getText());
|
||||
caption.Trim(PS_TRIM_BOTH);
|
||||
if (caption.Length())
|
||||
{
|
||||
try
|
||||
{
|
||||
// Set the setting caption to this
|
||||
object->SetSetting("caption", caption);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// There is no harm if the object didn't have a "caption"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Read Children
|
||||
//
|
||||
|
||||
// Iterate children
|
||||
DOMNodeList *children = pElement->getChildNodes();
|
||||
XMBElementList children = Element.getChildNodes();
|
||||
|
||||
for (i=0; i<children->getLength(); ++i)
|
||||
for (i=0; i<children.Count; ++i)
|
||||
{
|
||||
// Get node
|
||||
DOMNode *child = children->item(i);
|
||||
XMBElement child = children.item(i);
|
||||
|
||||
// Check type (it's probably text or element)
|
||||
|
||||
// A child element
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
// Check what name the elements got
|
||||
int element_name = child.getNodeName();
|
||||
|
||||
if (element_name == elmt_object)
|
||||
{
|
||||
// Check what name the elements got
|
||||
CStr element_name = XMLTranscode( child->getNodeName() );
|
||||
// TODO Gee: REPORT ERROR
|
||||
|
||||
if (element_name == CStr("object"))
|
||||
{
|
||||
// First get element and not node
|
||||
DOMElement *element = (DOMElement*)child;
|
||||
|
||||
// TODO Gee: REPORT ERROR
|
||||
|
||||
// Call this function on the child
|
||||
Xerces_ReadObject(element, object);
|
||||
}
|
||||
// Call this function on the child
|
||||
Xeromyces_ReadObject(child, pFile, object);
|
||||
}
|
||||
else
|
||||
if (child->getNodeType() == DOMNode::TEXT_NODE)
|
||||
else if (element_name == elmt_action)
|
||||
{
|
||||
CStr caption = XMLTranscode( child->getNodeValue() );
|
||||
|
||||
caption = caption.Trim(PS_TRIM_BOTH);
|
||||
|
||||
if (caption.Length())
|
||||
{
|
||||
// Text is only okay if it's the first element i.e. <object>caption ... </object>
|
||||
if (i==0)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
// Set the setting caption to this
|
||||
object->SetSetting("caption", caption);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// There is no harm if the object didn't have a "caption"
|
||||
}
|
||||
}
|
||||
else
|
||||
debug_warn("Text is only okay if it's the first element i.e. <object>caption ... </object>");
|
||||
}
|
||||
CStr action = tocstr(child.getAttributes().getNamedItem(attr_on));
|
||||
CStr code = tocstr(child.getText());
|
||||
object->RegisterScriptHandler(action, code, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1182,10 +1167,8 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
||||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadSprite(DOMElement *pElement)
|
||||
void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
// Sprite object we're adding
|
||||
CGUISprite sprite;
|
||||
|
||||
@ -1197,33 +1180,24 @@ void CGUI::Xerces_ReadSprite(DOMElement *pElement)
|
||||
//
|
||||
|
||||
// Get name, we know it exists because of DTD requirements
|
||||
name = XMLTranscode( pElement->getAttribute( (XMLCh*)L"name" ) );
|
||||
name = tocstr( Element.getAttributes().getNamedItem( pFile->getAttributeID(L"name") ) );
|
||||
|
||||
//
|
||||
// Read Children (the images)
|
||||
//
|
||||
|
||||
// Iterate children
|
||||
DOMNodeList *children = pElement->getChildNodes();
|
||||
XMBElementList children = Element.getChildNodes();
|
||||
|
||||
for (u16 i=0; i<children->getLength(); ++i)
|
||||
for (int i=0; i<children.Count; ++i)
|
||||
{
|
||||
// Get node
|
||||
DOMNode *child = children->item(i);
|
||||
XMBElement child = children.item(i);
|
||||
|
||||
// Check type (it's probably text or element)
|
||||
|
||||
// A child element
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
{
|
||||
// All Elements will be of type "image" by DTD law
|
||||
// All Elements will be of type "image" by DTD law
|
||||
|
||||
// First get element and not node
|
||||
DOMElement *element = (DOMElement*)child;
|
||||
|
||||
// Call this function on the child
|
||||
Xerces_ReadImage(element, sprite);
|
||||
}
|
||||
// Call this function on the child
|
||||
Xeromyces_ReadImage(child, pFile, sprite);
|
||||
}
|
||||
|
||||
//
|
||||
@ -1233,9 +1207,8 @@ void CGUI::Xerces_ReadSprite(DOMElement *pElement)
|
||||
m_Sprites[name] = sprite;
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadImage(DOMElement *pElement, CGUISprite &parent)
|
||||
void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
// Image object we're adding
|
||||
SGUIImage image;
|
||||
@ -1247,20 +1220,20 @@ void CGUI::Xerces_ReadImage(DOMElement *pElement, CGUISprite &parent)
|
||||
//
|
||||
|
||||
// Now we can iterate all attributes and store
|
||||
DOMNamedNodeMap *attributes = pElement->getAttributes();
|
||||
for (u16 i=0; i<attributes->getLength(); ++i)
|
||||
XMBAttributeList attributes = Element.getAttributes();
|
||||
for (int i=0; i<attributes.Count; ++i)
|
||||
{
|
||||
DOMAttr *attr = (DOMAttr*)attributes->item(i);
|
||||
CStr attr_name = XMLTranscode( attr->getName() );
|
||||
CStr attr_value(XMLTranscode( attr->getValue() ));
|
||||
XMBAttribute attr = attributes.item(i);
|
||||
std::wstring attr_name = pFile->getAttributeString(attr.Name);
|
||||
CStr attr_value = tocstr( attr.Value );
|
||||
|
||||
// This is the only attribute we want
|
||||
if (attr_name == CStr("texture"))
|
||||
if (attr_name == L"texture")
|
||||
{
|
||||
image.m_Texture = attr_value;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("size"))
|
||||
if (attr_name == L"size")
|
||||
{
|
||||
CClientArea ca;
|
||||
if (!GUI<CClientArea>::ParseString(attr_value, ca))
|
||||
@ -1270,7 +1243,7 @@ void CGUI::Xerces_ReadImage(DOMElement *pElement, CGUISprite &parent)
|
||||
else image.m_Size = ca;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("z-level"))
|
||||
if (attr_name == L"z-level")
|
||||
{
|
||||
int z_level;
|
||||
if (!GUI<int>::ParseString(attr_value, z_level))
|
||||
@ -1280,7 +1253,7 @@ void CGUI::Xerces_ReadImage(DOMElement *pElement, CGUISprite &parent)
|
||||
else image.m_DeltaZ = (float)z_level/100.f;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("backcolor"))
|
||||
if (attr_name == L"backcolor")
|
||||
{
|
||||
CColor color;
|
||||
if (!GUI<CColor>::ParseString(attr_value, color))
|
||||
@ -1304,10 +1277,8 @@ void CGUI::Xerces_ReadImage(DOMElement *pElement, CGUISprite &parent)
|
||||
parent.AddImage(image);
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadStyle(DOMElement *pElement)
|
||||
void CGUI::Xeromyces_ReadStyle(XMBElement Element, CXeromyces* pFile)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
// style object we're adding
|
||||
SGUIStyle style;
|
||||
CStr name;
|
||||
@ -1317,19 +1288,19 @@ void CGUI::Xerces_ReadStyle(DOMElement *pElement)
|
||||
//
|
||||
|
||||
// Now we can iterate all attributes and store
|
||||
DOMNamedNodeMap *attributes = pElement->getAttributes();
|
||||
for (u16 i=0; i<attributes->getLength(); ++i)
|
||||
XMBAttributeList attributes = Element.getAttributes();
|
||||
for (int i=0; i<attributes.Count; ++i)
|
||||
{
|
||||
DOMAttr *attr = (DOMAttr*)attributes->item(i);
|
||||
CStr attr_name = XMLTranscode( attr->getName() );
|
||||
CStr attr_value = XMLTranscode( attr->getValue() );
|
||||
XMBAttribute attr = attributes.item(i);
|
||||
std::wstring attr_name = pFile->getAttributeString(attr.Name);
|
||||
CStr attr_value = tocstr( attr.Value );
|
||||
|
||||
// The "name" setting is actually the name of the style
|
||||
// and not a new default
|
||||
if (attr_name == CStr("name"))
|
||||
if (attr_name == L"name")
|
||||
name = attr_value;
|
||||
else
|
||||
style.m_SettingsDefaults[attr_name] = attr_value;
|
||||
style.m_SettingsDefaults[tocstr(attr_name)] = attr_value;
|
||||
}
|
||||
|
||||
//
|
||||
@ -1339,10 +1310,8 @@ void CGUI::Xerces_ReadStyle(DOMElement *pElement)
|
||||
m_Styles[name] = style;
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadScrollBarStyle(DOMElement *pElement)
|
||||
void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
// style object we're adding
|
||||
SGUIScrollBarStyle scrollbar;
|
||||
CStr name;
|
||||
@ -1352,20 +1321,20 @@ void CGUI::Xerces_ReadScrollBarStyle(DOMElement *pElement)
|
||||
//
|
||||
|
||||
// Now we can iterate all attributes and store
|
||||
DOMNamedNodeMap *attributes = pElement->getAttributes();
|
||||
for (u16 i=0; i<attributes->getLength(); ++i)
|
||||
XMBAttributeList attributes = Element.getAttributes();
|
||||
for (int i=0; i<attributes.Count; ++i)
|
||||
{
|
||||
DOMAttr *attr = (DOMAttr*)attributes->item(i);
|
||||
CStr attr_name = XMLTranscode( attr->getName() );
|
||||
CStr attr_value = XMLTranscode( attr->getValue() );
|
||||
XMBAttribute attr = attributes.item(i);
|
||||
std::wstring attr_name = pFile->getAttributeString(attr.Name);
|
||||
CStr attr_value = tocstr( attr.Value );
|
||||
|
||||
if (attr_value == CStr("null"))
|
||||
continue;
|
||||
|
||||
if (attr_name == CStr("name"))
|
||||
if (attr_name == L"name")
|
||||
name = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("width"))
|
||||
if (attr_name == L"width")
|
||||
{
|
||||
int i;
|
||||
if (!GUI<int>::ParseString(attr_value, i))
|
||||
@ -1375,7 +1344,7 @@ void CGUI::Xerces_ReadScrollBarStyle(DOMElement *pElement)
|
||||
scrollbar.m_Width = i;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("minimum-bar-size"))
|
||||
if (attr_name == L"minimum-bar-size")
|
||||
{
|
||||
int i;
|
||||
if (!GUI<int>::ParseString(attr_value, i))
|
||||
@ -1385,40 +1354,40 @@ void CGUI::Xerces_ReadScrollBarStyle(DOMElement *pElement)
|
||||
scrollbar.m_MinimumBarSize = i;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top"))
|
||||
if (attr_name == L"sprite-button-top")
|
||||
scrollbar.m_SpriteButtonTop = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top-pressed"))
|
||||
if (attr_name == L"sprite-button-top-pressed")
|
||||
scrollbar.m_SpriteButtonTopPressed = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top-disabled"))
|
||||
if (attr_name == L"sprite-button-top-disabled")
|
||||
scrollbar.m_SpriteButtonTopDisabled = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top-over"))
|
||||
if (attr_name == L"sprite-button-top-over")
|
||||
scrollbar.m_SpriteButtonTopOver = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom"))
|
||||
if (attr_name == L"sprite-button-bottom")
|
||||
scrollbar.m_SpriteButtonBottom = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom-pressed"))
|
||||
if (attr_name == L"sprite-button-bottom-pressed")
|
||||
scrollbar.m_SpriteButtonBottomPressed = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom-disabled"))
|
||||
if (attr_name == L"sprite-button-bottom-disabled")
|
||||
scrollbar.m_SpriteButtonBottomDisabled = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom-over"))
|
||||
if (attr_name == L"sprite-button-bottom-over")
|
||||
scrollbar.m_SpriteButtonBottomOver = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-back-vertical"))
|
||||
if (attr_name == L"sprite-back-vertical")
|
||||
scrollbar.m_SpriteBackVertical = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-bar-vertical"))
|
||||
if (attr_name == L"sprite-bar-vertical")
|
||||
scrollbar.m_SpriteBarVertical = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-bar-vertical-over"))
|
||||
if (attr_name == L"sprite-bar-vertical-over")
|
||||
scrollbar.m_SpriteBarVerticalOver = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-bar-vertical-pressed"))
|
||||
if (attr_name == L"sprite-bar-vertical-pressed")
|
||||
scrollbar.m_SpriteBarVerticalPressed = attr_value;
|
||||
|
||||
/*
|
||||
|
@ -21,15 +21,11 @@ gee@pyro.nu
|
||||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
#include "GUI.h"
|
||||
#include "XML.h"
|
||||
//#include <xercesc/dom/DOM.hpp>
|
||||
//#include <xercesc/util/XMLString.hpp>
|
||||
//#include <xercesc/util/PlatformUtils.hpp>
|
||||
|
||||
#include "Singleton.h"
|
||||
#include "input.h" // JW: grr, classes suck in this case :P
|
||||
|
||||
class XERCES_CPP_NAMESPACE::DOMElement;
|
||||
#include "Xeromyces.h"
|
||||
|
||||
extern int gui_handler(const SDL_Event* ev);
|
||||
|
||||
@ -153,6 +149,16 @@ public:
|
||||
*/
|
||||
bool ObjectExists(const CStr& Name) const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the GUI object with the desired name, or NULL
|
||||
* if no match is found,
|
||||
*
|
||||
* @param Name String name of object
|
||||
* @return Matching object, or NULL
|
||||
*/
|
||||
IGUIObject* FindObjectByName(const CStr& Name) const;
|
||||
|
||||
/**
|
||||
* The GUI needs to have all object types inputted and
|
||||
* their constructors. Also it needs to associate a type
|
||||
@ -241,7 +247,7 @@ private:
|
||||
IGUIObject *ConstructObject(const CStr& str);
|
||||
|
||||
//--------------------------------------------------------
|
||||
/** @name XML Reading Xerces C++ specific subroutines
|
||||
/** @name XML Reading Xeromyces specific subroutines
|
||||
*
|
||||
* These does not throw!
|
||||
* Because when reading in XML files, it won't be fatal
|
||||
@ -252,7 +258,7 @@ private:
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
Xerces_* functions tree
|
||||
Xeromyces_* functions tree
|
||||
<code>
|
||||
\<objects\> (ReadRootObjects)
|
||||
|
|
||||
@ -294,42 +300,46 @@ private:
|
||||
/**
|
||||
* Reads in the root element \<objects\> (the DOMElement).
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the objects-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadRootObjects(XERCES_CPP_NAMESPACE::DOMElement *pElement);
|
||||
void Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile);
|
||||
|
||||
/**
|
||||
* Reads in the root element \<sprites\> (the DOMElement).
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the sprites-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadRootSprites(XERCES_CPP_NAMESPACE::DOMElement *pElement);
|
||||
void Xeromyces_ReadRootSprites(XMBElement Element, CXeromyces* pFile);
|
||||
|
||||
/**
|
||||
* Reads in the root element \<styles\> (the DOMElement).
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* the sprites-tag.
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the styles-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadRootStyles(XERCES_CPP_NAMESPACE::DOMElement *pElement);
|
||||
void Xeromyces_ReadRootStyles(XMBElement Element, CXeromyces* pFile);
|
||||
|
||||
/**
|
||||
* Reads in the root element \<setup\> (the DOMElement).
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the setup-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadRootSetup(XERCES_CPP_NAMESPACE::DOMElement *pElement);
|
||||
void Xeromyces_ReadRootSetup(XMBElement Element, CXeromyces* pFile);
|
||||
|
||||
// Read Subs
|
||||
|
||||
@ -346,61 +356,67 @@ private:
|
||||
*
|
||||
* Reads in the root element \<sprites\> (the DOMElement).
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the object-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
* @param pParent Parent to add this object as child in.
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadObject(XERCES_CPP_NAMESPACE::DOMElement *, IGUIObject *pParent);
|
||||
void Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent);
|
||||
|
||||
/**
|
||||
* Reads in the element \<sprite\> (the DOMElement) and stores the
|
||||
* result in a new CGUISprite.
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the sprite-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadSprite(XERCES_CPP_NAMESPACE::DOMElement *pElement);
|
||||
void Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile);
|
||||
|
||||
/**
|
||||
* Reads in the element \<image\> (the DOMElement) and stores the
|
||||
* result within the CGUISprite.
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the image-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
* @param parent Parent sprite.
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadImage(XERCES_CPP_NAMESPACE::DOMElement *pElement, CGUISprite &parent);
|
||||
void Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent);
|
||||
|
||||
/**
|
||||
* Reads in the element \<style\> (the DOMElement) and stores the
|
||||
* result in m_Styles.
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* the sprite-tag.
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the style-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement);
|
||||
void Xeromyces_ReadStyle(XMBElement Element, CXeromyces* pFile);
|
||||
|
||||
/**
|
||||
* Reads in the element \<scrollbar\> (the DOMElement) and stores the
|
||||
* result in m_ScrollBarStyles.
|
||||
*
|
||||
* @param pElement The Xerces C++ Parser object that represents
|
||||
* @param Element The Xeromyces object that represents
|
||||
* the scrollbar-tag.
|
||||
* @param pFile The Xeromyces object for the file being read
|
||||
*
|
||||
* @see LoadXMLFile()
|
||||
*/
|
||||
void Xerces_ReadScrollBarStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement);
|
||||
void Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile);
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Variables
|
||||
@ -410,6 +426,14 @@ private:
|
||||
//--------------------------------------------------------
|
||||
//@{
|
||||
|
||||
/**
|
||||
* An JSObject* under which all GUI JavaScript things will
|
||||
* be created, so that they can be garbage-collected
|
||||
* when the GUI shuts down. (Stored as void* to avoid
|
||||
* to avoid pulling in all the JS headers)
|
||||
*/
|
||||
void* m_ScriptObject;
|
||||
|
||||
/**
|
||||
* don't want to pass this around with the
|
||||
* ChooseMouseOverAndClosest broadcast -
|
||||
@ -417,6 +441,12 @@ private:
|
||||
*/
|
||||
CPos m_MousePos;
|
||||
|
||||
/**
|
||||
* Indicates which buttons are pressed (bit 0 = LMB,
|
||||
* bit 1 = RMB, bit 2 = MMB)
|
||||
*/
|
||||
unsigned int m_MouseButtons;
|
||||
|
||||
/// Used when reading in XML files
|
||||
// TODO Gee: Used?
|
||||
int16_t m_Errors;
|
||||
|
@ -30,6 +30,8 @@ void CRadioButton::HandleMessage(const SGUIMessage &Message)
|
||||
GUI<bool>::SetSetting(this, "checked", true);
|
||||
|
||||
//GetGUI()->TEMPmessage = "Check box " + string((const TCHAR*)m_Name) + " was " + (m_Settings.m_Checked?"checked":"unchecked");
|
||||
|
||||
ScriptEvent("Press");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,9 @@ gee@pyro.nu
|
||||
#include <assert.h>
|
||||
/////
|
||||
|
||||
#include "gui/scripting/JSInterface_IGUIObject.h"
|
||||
#include "gui/scripting/JSInterface_GUITypes.h"
|
||||
|
||||
extern int g_xres, g_yres;
|
||||
|
||||
using namespace std;
|
||||
@ -245,6 +248,20 @@ void IGUIObject::SetSetting(const CStr& Setting, const CStr& Value)
|
||||
}
|
||||
}
|
||||
|
||||
PS_RESULT IGUIObject::GetSettingType(const CStr& Setting, EGUISettingType &Type) const
|
||||
{
|
||||
if (!SettingExists(Setting))
|
||||
return PS_SETTING_FAIL;
|
||||
|
||||
if (m_Settings.find(Setting) == m_Settings.end())
|
||||
return PS_FAIL;
|
||||
|
||||
Type = m_Settings.find(Setting)->second.m_Type;
|
||||
|
||||
return PS_OK;
|
||||
}
|
||||
|
||||
|
||||
void IGUIObject::ChooseMouseOverAndClosest(IGUIObject* &pObject)
|
||||
{
|
||||
if (MouseOver())
|
||||
@ -375,3 +392,56 @@ void IGUIObject::CheckSettingsValidity()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void IGUIObject::RegisterScriptHandler(const CStr& Action, const CStr& Code, CGUI* pGUI)
|
||||
{
|
||||
const int paramCount = 1;
|
||||
const char* paramNames[paramCount] = { "mouse" };
|
||||
|
||||
JSFunction* func = JS_CompileFunction(g_ScriptingHost.getContext(), (JSObject*)pGUI->m_ScriptObject, "", paramCount, paramNames, (const char*)Code, Code.Length(), "GUI script", 0);
|
||||
m_ScriptHandlers[Action] = func;
|
||||
}
|
||||
|
||||
void IGUIObject::ScriptEvent(const CStr& Action)
|
||||
{
|
||||
map<CStr, void*>::iterator it = m_ScriptHandlers.find(Action);
|
||||
if (it == m_ScriptHandlers.end())
|
||||
return;
|
||||
|
||||
// PRIVATE_TO_JSVAL assumes two-byte alignment,
|
||||
// so make sure that's always true
|
||||
assert(! ((jsval)this & JSVAL_INT));
|
||||
|
||||
// The IGUIObject needs to be stored inside the script's object
|
||||
jsval guiObject = PRIVATE_TO_JSVAL(this);
|
||||
|
||||
// Make a 'this', allowing access to the IGUIObject
|
||||
JSObject* jsGuiObject = JS_ConstructObjectWithArguments(g_ScriptingHost.getContext(), &JSI_IGUIObject::JSI_class, NULL, (JSObject*)m_pGUI->m_ScriptObject, 1, &guiObject);
|
||||
|
||||
// Prevent it from being garbage-collected before
|
||||
// it's passed into the function
|
||||
JS_AddRoot(g_ScriptingHost.getContext(), &jsGuiObject);
|
||||
|
||||
|
||||
// Set up the 'mouse' parameter
|
||||
jsval mouseParams[3];
|
||||
mouseParams[0] = INT_TO_JSVAL(m_pGUI->m_MousePos.x);
|
||||
mouseParams[1] = INT_TO_JSVAL(m_pGUI->m_MousePos.y);
|
||||
mouseParams[2] = INT_TO_JSVAL(m_pGUI->m_MouseButtons);
|
||||
JSObject* mouseObj = JS_ConstructObjectWithArguments(g_ScriptingHost.getContext(), &JSI_GUIMouse::JSI_class, NULL, (JSObject*)m_pGUI->m_ScriptObject, 3, mouseParams);
|
||||
assert(mouseObj); // need better error handling
|
||||
|
||||
// Don't garbage collect the mouse
|
||||
JS_AddRoot(g_ScriptingHost.getContext(), &mouseObj);
|
||||
|
||||
const int paramCount = 1;
|
||||
jsval paramData[paramCount];
|
||||
paramData[0] = OBJECT_TO_JSVAL(mouseObj);
|
||||
|
||||
jsval result;
|
||||
JSBool ok = JS_CallFunction(g_ScriptingHost.getContext(), jsGuiObject, (JSFunction*)((*it).second), 1, paramData, &result);
|
||||
|
||||
// Allow the temporary parameters to be collected
|
||||
JS_RemoveRoot(g_ScriptingHost.getContext(), &mouseObj);
|
||||
JS_RemoveRoot(g_ScriptingHost.getContext(), &jsGuiObject);
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ gee@pyro.nu
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gui/scripting/JSInterface_IGUIObject.h"
|
||||
|
||||
struct SGUISetting;
|
||||
struct SGUIStyle;
|
||||
class CGUI;
|
||||
@ -132,10 +134,13 @@ class IGUIObject
|
||||
friend class CInternalCGUIAccessorBase;
|
||||
friend class IGUIScrollBar;
|
||||
|
||||
// Allow getProperty to access things like GetParent()
|
||||
friend JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
|
||||
|
||||
public:
|
||||
IGUIObject();
|
||||
virtual ~IGUIObject();
|
||||
|
||||
|
||||
/**
|
||||
* Checks if mouse is hovering this object.
|
||||
* The mouse position is cached in CGUI.
|
||||
@ -255,6 +260,24 @@ public:
|
||||
*/
|
||||
void SetSetting(const CStr& Setting, const CStr& Value);
|
||||
|
||||
/**
|
||||
* Retrieves the type of a named setting.
|
||||
*
|
||||
* @param Setting Setting by name
|
||||
* @param Type Stores an EGUISettingType
|
||||
* @return PS_RESULT (PS_OK if successful)
|
||||
*/
|
||||
PS_RESULT GetSettingType(const CStr& Setting, EGUISettingType &Type) const;
|
||||
|
||||
/**
|
||||
* Set the script handler for a particular object-specific action
|
||||
*
|
||||
* @param Action Name of action
|
||||
* @param Code Javascript code to execute when the action occurs
|
||||
* @param pGUI GUI instance to associate the script with
|
||||
*/
|
||||
void RegisterScriptHandler(const CStr& Action, const CStr& Code, CGUI* pGUI);
|
||||
|
||||
//@}
|
||||
protected:
|
||||
//--------------------------------------------------------
|
||||
@ -374,6 +397,19 @@ protected:
|
||||
*/
|
||||
CRect m_CachedActualSize;
|
||||
|
||||
/**
|
||||
* Execute the script for a particular action.
|
||||
* Does nothing if no script has been registered for that action.
|
||||
*
|
||||
* @param Action Name of action
|
||||
*/
|
||||
void ScriptEvent(const CStr& Action);
|
||||
|
||||
/**
|
||||
* Internal storage for registered script handlers.
|
||||
*/
|
||||
std::map<CStr, void*> m_ScriptHandlers;
|
||||
|
||||
//@}
|
||||
private:
|
||||
//--------------------------------------------------------
|
||||
|
194
source/gui/scripting/JSInterface_GUITypes.cpp
Executable file
194
source/gui/scripting/JSInterface_GUITypes.cpp
Executable file
@ -0,0 +1,194 @@
|
||||
// $Id: JSInterface_GUITypes.cpp,v 1.1 2004/07/08 15:19:45 philip Exp $
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "JSInterface_GUITypes.h"
|
||||
|
||||
/**** GUISize ****/
|
||||
|
||||
JSClass JSI_GUISize::JSI_class = {
|
||||
"GUISize", 0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, JS_FinalizeStub,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JSPropertySpec JSI_GUISize::JSI_props[] =
|
||||
{
|
||||
{ "left", 0, JSPROP_ENUMERATE},
|
||||
{ "top", 1, JSPROP_ENUMERATE},
|
||||
{ "right", 2, JSPROP_ENUMERATE},
|
||||
{ "bottom", 3, JSPROP_ENUMERATE},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSFunctionSpec JSI_GUISize::JSI_methods[] =
|
||||
{
|
||||
{ "toString", JSI_GUISize::toString, 0, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSBool JSI_GUISize::construct(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
if (argc == 4)
|
||||
{
|
||||
JS_SetProperty(cx, obj, "left", &argv[0]);
|
||||
JS_SetProperty(cx, obj, "top", &argv[1]);
|
||||
JS_SetProperty(cx, obj, "right", &argv[2]);
|
||||
JS_SetProperty(cx, obj, "bottom", &argv[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
jsval zero = JSVAL_ZERO;
|
||||
JS_SetProperty(cx, obj, "left", &zero);
|
||||
JS_SetProperty(cx, obj, "top", &zero);
|
||||
JS_SetProperty(cx, obj, "right", &zero);
|
||||
JS_SetProperty(cx, obj, "bottom", &zero);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool JSI_GUISize::toString(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
char buffer[256];
|
||||
snprintf(buffer, 256, "%i %i %i %i",
|
||||
JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "left" )),
|
||||
JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "top" )),
|
||||
JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "right" )),
|
||||
JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "bottom")) );
|
||||
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**** GUIColour ****/
|
||||
|
||||
|
||||
JSClass JSI_GUIColour::JSI_class = {
|
||||
"GUIColour", 0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, JS_FinalizeStub,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JSPropertySpec JSI_GUIColour::JSI_props[] =
|
||||
{
|
||||
{ "r", 0, JSPROP_ENUMERATE},
|
||||
{ "g", 1, JSPROP_ENUMERATE},
|
||||
{ "b", 2, JSPROP_ENUMERATE},
|
||||
{ "a", 3, JSPROP_ENUMERATE},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSFunctionSpec JSI_GUIColour::JSI_methods[] =
|
||||
{
|
||||
{ "toString", JSI_GUIColour::toString, 0, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSBool JSI_GUIColour::construct(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
if (argc == 4)
|
||||
{
|
||||
JS_SetProperty(cx, obj, "r", &argv[0]);
|
||||
JS_SetProperty(cx, obj, "g", &argv[1]);
|
||||
JS_SetProperty(cx, obj, "b", &argv[2]);
|
||||
JS_SetProperty(cx, obj, "a", &argv[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nice magenta:
|
||||
jsval r = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0));
|
||||
jsval g = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 0.0));
|
||||
jsval b = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0));
|
||||
jsval a = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0));
|
||||
JS_SetProperty(cx, obj, "r", &r);
|
||||
JS_SetProperty(cx, obj, "g", &g);
|
||||
JS_SetProperty(cx, obj, "b", &b);
|
||||
JS_SetProperty(cx, obj, "a", &a);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool JSI_GUIColour::toString(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
char buffer[256];
|
||||
// Convert to integers, to be compatible with the GUI's string SetSetting
|
||||
snprintf(buffer, 256, "%i %i %i %i",
|
||||
(int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "r")) ),
|
||||
(int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "g")) ),
|
||||
(int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "b")) ),
|
||||
(int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "a")) ));
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/**** GUIMouse ****/
|
||||
|
||||
|
||||
JSClass JSI_GUIMouse::JSI_class = {
|
||||
"GUIMouse", 0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, JS_FinalizeStub,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JSPropertySpec JSI_GUIMouse::JSI_props[] =
|
||||
{
|
||||
{ "x", 0, JSPROP_ENUMERATE},
|
||||
{ "y", 1, JSPROP_ENUMERATE},
|
||||
{ "buttons", 2, JSPROP_ENUMERATE},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSFunctionSpec JSI_GUIMouse::JSI_methods[] =
|
||||
{
|
||||
{ "toString", JSI_GUIMouse::toString, 0, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSBool JSI_GUIMouse::construct(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
if (argc == 3)
|
||||
{
|
||||
JS_SetProperty(cx, obj, "x", &argv[0]);
|
||||
JS_SetProperty(cx, obj, "y", &argv[1]);
|
||||
JS_SetProperty(cx, obj, "buttons", &argv[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
jsval zero = JSVAL_ZERO;
|
||||
JS_SetProperty(cx, obj, "x", &zero);
|
||||
JS_SetProperty(cx, obj, "y", &zero);
|
||||
JS_SetProperty(cx, obj, "buttons", &zero);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool JSI_GUIMouse::toString(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
char buffer[256];
|
||||
snprintf(buffer, 256, "%i %i %i",
|
||||
JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "x")),
|
||||
JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "y")),
|
||||
JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "buttons")) );
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Initialise all the types at once:
|
||||
void JSI_GUITypes::init()
|
||||
{
|
||||
g_ScriptingHost.DefineCustomObjectType(&JSI_GUISize::JSI_class, JSI_GUISize::construct, 1, JSI_GUISize::JSI_props, JSI_GUISize::JSI_methods, NULL, NULL);
|
||||
g_ScriptingHost.DefineCustomObjectType(&JSI_GUIColour::JSI_class, JSI_GUIColour::construct, 1, JSI_GUIColour::JSI_props, JSI_GUIColour::JSI_methods, NULL, NULL);
|
||||
g_ScriptingHost.DefineCustomObjectType(&JSI_GUIMouse::JSI_class, JSI_GUIMouse::construct, 1, JSI_GUIMouse::JSI_props, JSI_GUIMouse::JSI_methods, NULL, NULL);
|
||||
}
|
30
source/gui/scripting/JSInterface_GUITypes.h
Executable file
30
source/gui/scripting/JSInterface_GUITypes.h
Executable file
@ -0,0 +1,30 @@
|
||||
// $Id: JSInterface_GUITypes.h,v 1.1 2004/07/08 15:19:45 philip Exp $
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
|
||||
#ifndef JSI_GUITYPES_INCLUDED
|
||||
#define JSI_GUITYPES_INCLUDED
|
||||
|
||||
#define GUISTDTYPE(x) \
|
||||
namespace JSI_GUI##x \
|
||||
{ \
|
||||
extern JSClass JSI_class; \
|
||||
extern JSPropertySpec JSI_props[]; \
|
||||
extern JSFunctionSpec JSI_methods[]; \
|
||||
JSBool construct( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ); \
|
||||
JSBool getByName( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ); \
|
||||
JSBool toString( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ); \
|
||||
}
|
||||
|
||||
GUISTDTYPE(Size)
|
||||
GUISTDTYPE(Colour)
|
||||
GUISTDTYPE(Mouse)
|
||||
|
||||
#undef GUISTDTYPE // avoid unnecessary pollution
|
||||
|
||||
namespace JSI_GUITypes
|
||||
{
|
||||
void init();
|
||||
}
|
||||
|
||||
#endif
|
355
source/gui/scripting/JSInterface_IGUIObject.cpp
Executable file
355
source/gui/scripting/JSInterface_IGUIObject.cpp
Executable file
@ -0,0 +1,355 @@
|
||||
// $Id: JSInterface_IGUIObject.cpp,v 1.1 2004/07/08 15:19:45 philip Exp $
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "JSInterface_IGUIObject.h"
|
||||
#include "JSInterface_GUITypes.h"
|
||||
|
||||
JSClass JSI_IGUIObject::JSI_class = {
|
||||
"GUIObject", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JSI_IGUIObject::getProperty, JSI_IGUIObject::setProperty,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, JS_FinalizeStub,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JSPropertySpec JSI_IGUIObject::JSI_props[] =
|
||||
{
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSFunctionSpec JSI_IGUIObject::JSI_methods[] =
|
||||
{
|
||||
{ "toString", JSI_IGUIObject::toString, 0, 0, 0 },
|
||||
{ "getByName", JSI_IGUIObject::getByName, 1, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)
|
||||
{
|
||||
CStr propName = JS_GetStringBytes(JS_ValueToString(cx, id));
|
||||
|
||||
// Skip some things which are known to be functions rather than properties.
|
||||
// ("constructor" *must* be here, else it'll try to GetSettingType before
|
||||
// the private IGUIObject* has been set (and thus crash). The others are
|
||||
// just for efficiency.)
|
||||
if (propName == (CStr)"constructor" ||
|
||||
propName == (CStr)"toString" ||
|
||||
propName == (CStr)"getByName"
|
||||
)
|
||||
return JS_TRUE;
|
||||
|
||||
IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj);
|
||||
|
||||
// Handle the "parent" property specially
|
||||
if (propName == (CStr)"parent")
|
||||
{
|
||||
IGUIObject* parent = e->GetParent();
|
||||
if (parent)
|
||||
{
|
||||
// If the object isn't parentless, return a new object
|
||||
JSObject* entity = JS_NewObject(cx, &JSI_IGUIObject::JSI_class, NULL, NULL);
|
||||
JS_SetPrivate(cx, entity, parent);
|
||||
*vp = OBJECT_TO_JSVAL(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return null if there's no parent
|
||||
*vp = JSVAL_VOID;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
// Also handle "name" specially
|
||||
else if (propName == (CStr)"name")
|
||||
{
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, e->GetName()));
|
||||
return JS_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
EGUISettingType Type;
|
||||
if (e->GetSettingType(propName, Type) != PS_OK)
|
||||
{
|
||||
// Possibly a function, but they should have been individually
|
||||
// handled above, so complain about it
|
||||
JS_ReportError(cx, "Invalid setting '%s'", propName.c_str());
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// (All the cases are in {...} to avoid scoping problems)
|
||||
switch (Type)
|
||||
{
|
||||
case GUIST_bool:
|
||||
{
|
||||
bool value;
|
||||
GUI<bool>::GetSetting(e, propName, value);
|
||||
*vp = value ? JSVAL_TRUE : JSVAL_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_int:
|
||||
{
|
||||
int value;
|
||||
GUI<int>::GetSetting(e, propName, value);
|
||||
*vp = INT_TO_JSVAL(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_float:
|
||||
{
|
||||
float value;
|
||||
GUI<float>::GetSetting(e, propName, value);
|
||||
// Create a garbage-collectable double
|
||||
*vp = DOUBLE_TO_JSVAL(JS_NewDouble(cx, value) );
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_CColor:
|
||||
{
|
||||
CColor colour;
|
||||
GUI<CColor>::GetSetting(e, propName, colour);
|
||||
JSObject* obj = JS_NewObject(cx, &JSI_GUIColour::JSI_class, NULL, NULL);
|
||||
jsval r = DOUBLE_TO_JSVAL(JS_NewDouble(cx, colour.r));
|
||||
jsval g = DOUBLE_TO_JSVAL(JS_NewDouble(cx, colour.g));
|
||||
jsval b = DOUBLE_TO_JSVAL(JS_NewDouble(cx, colour.b));
|
||||
jsval a = DOUBLE_TO_JSVAL(JS_NewDouble(cx, colour.a));
|
||||
JS_SetProperty(cx, obj, "r", &r);
|
||||
JS_SetProperty(cx, obj, "g", &g);
|
||||
JS_SetProperty(cx, obj, "b", &b);
|
||||
JS_SetProperty(cx, obj, "a", &a);
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_CClientArea:
|
||||
{
|
||||
CClientArea area;
|
||||
GUI<CClientArea>::GetSetting(e, propName, area);
|
||||
CRect size = area.pixel;
|
||||
JSObject* obj = JS_NewObject(cx, &JSI_GUISize::JSI_class, NULL, NULL);
|
||||
jsval left = INT_TO_JSVAL(size.left);
|
||||
jsval top = INT_TO_JSVAL(size.top);
|
||||
jsval right = INT_TO_JSVAL(size.right);
|
||||
jsval bottom = INT_TO_JSVAL(size.bottom);
|
||||
JS_SetProperty(cx, obj, "left", &left);
|
||||
JS_SetProperty(cx, obj, "top", &top);
|
||||
JS_SetProperty(cx, obj, "right", &right);
|
||||
JS_SetProperty(cx, obj, "bottom", &bottom);
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_CGUIString:
|
||||
{
|
||||
CGUIString value;
|
||||
GUI<CGUIString>::GetSetting(e, propName, value);
|
||||
// Create a garbage-collectable copy of the string
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, value.GetRawString().c_str() ));
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_CStr:
|
||||
{
|
||||
CStr value;
|
||||
GUI<CStr>::GetSetting(e, propName, value);
|
||||
// Create a garbage-collectable copy of the string
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, value.c_str() ));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
JS_ReportError(cx, "Setting '%s' uses an unimplemented type", propName.c_str());
|
||||
*vp = JSVAL_NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Automatically falls through to methods
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)
|
||||
{
|
||||
IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj);
|
||||
CStr propName = g_ScriptingHost.ValueToString(id);
|
||||
if (propName == (CStr)"name")
|
||||
{
|
||||
CStr propValue = JS_GetStringBytes(JS_ValueToString(cx, *vp));
|
||||
e->SetName(propValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
EGUISettingType Type;
|
||||
if (e->GetSettingType(propName, Type) != PS_OK)
|
||||
{
|
||||
JS_ReportError(cx, "Invalid setting '%s'", propName.c_str());
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
|
||||
case GUIST_CStr:
|
||||
case GUIST_CGUIString:
|
||||
e->SetSetting(propName, JS_GetStringBytes(JS_ValueToString(cx, *vp)) );
|
||||
break;
|
||||
|
||||
case GUIST_int:
|
||||
{
|
||||
int32 value;
|
||||
if (JS_ValueToInt32(cx, *vp, &value) == JS_TRUE)
|
||||
GUI<int>::SetSetting(e, propName, value);
|
||||
else
|
||||
JS_ReportError(cx, "Cannot convert value to int");
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_float:
|
||||
{
|
||||
jsdouble value;
|
||||
if (JS_ValueToNumber(cx, *vp, &value) == JS_TRUE)
|
||||
GUI<float>::SetSetting(e, propName, (float)value);
|
||||
else
|
||||
JS_ReportError(cx, "Cannot convert value to float");
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_bool:
|
||||
{
|
||||
JSBool value;
|
||||
if (JS_ValueToBoolean(cx, *vp, &value) == JS_TRUE)
|
||||
GUI<bool>::SetSetting(e, propName, value||0); // ||0 to avoid int-to-bool compiler warnings
|
||||
else
|
||||
JS_ReportError(cx, "Cannot convert value to bool");
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_CClientArea:
|
||||
{
|
||||
if (JSVAL_IS_STRING(*vp))
|
||||
{
|
||||
e->SetSetting(propName, JS_GetStringBytes(JS_ValueToString(cx, *vp)) );
|
||||
}
|
||||
else if (JSVAL_IS_OBJECT(*vp) && JS_GetClass(JSVAL_TO_OBJECT(*vp)) == &JSI_GUISize::JSI_class)
|
||||
{
|
||||
CClientArea area;
|
||||
GUI<CClientArea>::GetSetting(e, propName, area);
|
||||
|
||||
JSObject* obj = JSVAL_TO_OBJECT(*vp);
|
||||
jsval t; int32 s;
|
||||
#define PROP(x) JS_GetProperty(cx, obj, #x, &t); \
|
||||
JS_ValueToInt32(cx, t, &s); \
|
||||
area.pixel.##x = s
|
||||
PROP(left); PROP(top); PROP(right); PROP(bottom);
|
||||
#undef PROP
|
||||
|
||||
GUI<CClientArea>::SetSetting(e, propName, area);
|
||||
}
|
||||
else
|
||||
{
|
||||
JS_ReportError(cx, "Size only accepts strings or GUISize objects");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIST_CColor:
|
||||
{
|
||||
if (JSVAL_IS_STRING(*vp))
|
||||
{
|
||||
e->SetSetting(propName, JS_GetStringBytes(JS_ValueToString(cx, *vp)) );
|
||||
}
|
||||
else if (JSVAL_IS_OBJECT(*vp) && JS_GetClass(JSVAL_TO_OBJECT(*vp)) == &JSI_GUIColour::JSI_class)
|
||||
{
|
||||
CColor colour;
|
||||
JSObject* obj = JSVAL_TO_OBJECT(*vp);
|
||||
jsval t; double s;
|
||||
#define PROP(x) JS_GetProperty(cx, obj, #x, &t); \
|
||||
JS_ValueToNumber(cx, t, &s); \
|
||||
colour.##x = (float)s
|
||||
PROP(r); PROP(g); PROP(b); PROP(a);
|
||||
#undef PROP
|
||||
|
||||
GUI<CColor>::SetSetting(e, propName, colour);
|
||||
}
|
||||
else
|
||||
{
|
||||
JS_ReportError(cx, "Color only accepts strings or GUIColour objects");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
JS_ReportError(cx, "Setting '%s' uses an unimplemented type", propName.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (PS_RESULT)
|
||||
{
|
||||
JS_ReportError(cx, "Invalid value for setting '%s'", propName.c_str());
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
JSBool JSI_IGUIObject::construct(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
if (argc == 0)
|
||||
{
|
||||
JS_ReportError(cx, "GUIObject has no default constructor");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
assert(argc == 1);
|
||||
|
||||
// Store the IGUIObject in the JS object's 'private' area
|
||||
IGUIObject* guiObject = (IGUIObject*)JSVAL_TO_PRIVATE(argv[0]);
|
||||
JS_SetPrivate(cx, obj, guiObject);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
JSBool JSI_IGUIObject::getByName(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
assert(argc == 1);
|
||||
|
||||
CStr objectName = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||
|
||||
IGUIObject* guiObject = g_GUI.FindObjectByName(objectName);
|
||||
|
||||
if (!guiObject)
|
||||
{
|
||||
// Not found - return null
|
||||
*rval = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSObject* entity = JS_NewObject(cx, &JSI_IGUIObject::JSI_class, NULL, NULL);
|
||||
JS_SetPrivate(cx, entity, guiObject);
|
||||
*rval = OBJECT_TO_JSVAL(entity);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void JSI_IGUIObject::init()
|
||||
{
|
||||
g_ScriptingHost.DefineCustomObjectType(&JSI_class, construct, 1, JSI_props, JSI_methods, NULL, NULL);
|
||||
}
|
||||
|
||||
JSBool JSI_IGUIObject::toString(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
IGUIObject* e = (IGUIObject*)JS_GetPrivate( cx, obj );
|
||||
|
||||
char buffer[256];
|
||||
snprintf(buffer, 256, "[GUIObject: %s]", (const TCHAR*)e->GetName());
|
||||
buffer[255] = 0;
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));
|
||||
return JS_TRUE;
|
||||
}
|
25
source/gui/scripting/JSInterface_IGUIObject.h
Executable file
25
source/gui/scripting/JSInterface_IGUIObject.h
Executable file
@ -0,0 +1,25 @@
|
||||
// $Id: JSInterface_IGUIObject.h,v 1.1 2004/07/08 15:19:45 philip Exp $
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
#include "gui/GUI.h"
|
||||
|
||||
#ifndef JSI_IGUIOBJECT_INCLUDED
|
||||
#define JSI_IGUIOBJECT_INCLUDED
|
||||
|
||||
namespace JSI_IGUIObject
|
||||
{
|
||||
extern JSClass JSI_class;
|
||||
extern JSPropertySpec JSI_props[];
|
||||
extern JSFunctionSpec JSI_methods[];
|
||||
JSBool addProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
|
||||
JSBool delProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
|
||||
JSBool getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
|
||||
JSBool setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp);
|
||||
JSBool construct(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval);
|
||||
JSBool getByName(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval);
|
||||
JSBool toString(JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval);
|
||||
void init();
|
||||
void x();
|
||||
}
|
||||
|
||||
#endif
|
@ -10,7 +10,7 @@
|
||||
#include "scripting/JSInterface_Entity.h"
|
||||
#include "scripting/JSInterface_BaseEntity.h"
|
||||
#include "scripting/JSInterface_Vector3D.h"
|
||||
//#include "gui/scripting/JSInterface_IGUIObject.h"
|
||||
#include "gui/scripting/JSInterface_IGUIObject.h"
|
||||
|
||||
extern CConsole* g_Console;
|
||||
|
||||
@ -28,7 +28,7 @@ JSFunctionSpec ScriptFunctionTable[] =
|
||||
{"writeConsole", writeConsole, 1, 0, 0 },
|
||||
{"getEntityByHandle", getEntityByHandle, 1, 0, 0 },
|
||||
{"getEntityTemplate", getEntityTemplate, 1, 0, 0 },
|
||||
// {"getGUIObjectByName", JSI_IGUIObject::getByName, 1, 0, 0 },
|
||||
{"getGUIObjectByName", JSI_IGUIObject::getByName, 1, 0, 0 },
|
||||
{"getGlobal", getGlobal, 0, 0, 0 },
|
||||
{0, 0, 0, 0, 0},
|
||||
};
|
||||
|
@ -44,6 +44,7 @@ package.files = {
|
||||
-- gui/
|
||||
{ sourcesfromdirs(
|
||||
"../../gui") },
|
||||
{ sourcesfromdirs( "../../gui/scripting" ) },
|
||||
-- terrain/
|
||||
{ sourcesfromdirs(
|
||||
"../../terrain") },
|
||||
|
Loading…
Reference in New Issue
Block a user