diff --git a/binaries/data/tools/atlas/scripts/main.js b/binaries/data/tools/atlas/scripts/main.js index d93369d0d2..346d1fd0fa 100644 --- a/binaries/data/tools/atlas/scripts/main.js +++ b/binaries/data/tools/atlas/scripts/main.js @@ -11,17 +11,21 @@ function getScriptFilename(name) * Loads and executes a script from disk. The script runs in a separate scope, * so variables and functions declared in it will not be visible outside that file. */ -function loadScript(name, window) +function loadScript(name /*, ...*/) { var filename = getScriptFilename(name); var file = new wxFFile(filename.fullPath); var script = file.readAll(); // TODO: handle errors file.close(); - var script = Atlas.LoadScript(name+'.js', script); - scriptReloader.add(name, window, filename); + var args = []; + for (var i = 1; i < arguments.length; ++i) + args.push(arguments[i]) - script.init(window); // TODO: use a variable list of arguments + var script = Atlas.LoadScript(name+'.js', script); + scriptReloader.add(name, args, filename); + + script.init.apply(null, args); return script; } @@ -67,19 +71,22 @@ var scriptReloader = { } else { - script.window.destroyChildren(); - loadScript(script.name, script.window); - script.window.layout(); + // TODO: know which arguments are really windows that should be regenerated + for each (var window in script.args) + window.destroyChildren(); + loadScript.apply(null, [script.name].concat(script.args)); + for each (var window in script.args) + window.layout(); } } } }, - add: function (name, window, filename) + add: function (name, args, filename) { for each (var script in this.scripts) if (script.name == name) return; // stop if this is already loaded - this.scripts.push({ name:name, window:window, filename:filename, mtime:filename.modificationTime }); + this.scripts.push({ name:name, args:args, filename:filename, mtime:filename.modificationTime }); } }; scriptReloader.timer.onNotify = scriptReloader.notify; diff --git a/binaries/data/tools/atlas/scripts/section/terrain.js b/binaries/data/tools/atlas/scripts/section/terrain.js index b50afa321a..63edf11725 100644 --- a/binaries/data/tools/atlas/scripts/section/terrain.js +++ b/binaries/data/tools/atlas/scripts/section/terrain.js @@ -55,7 +55,53 @@ var brush = { } }; -function init(window) +function TerrainPreviewPage(panel, name) +{ + this.panel = panel; + this.name = name; +} +TerrainPreviewPage.prototype = { + display: function() { + if (this.loaded) + return; + + this.panel.sizer = new wxBoxSizer(wxOrientation.VERTICAL); + var list = new wxListCtrl(this.panel, -1, wxDefaultPosition, wxDefaultSize, wxListCtrl.ICON | wxListCtrl.SINGLE_SEL); + this.panel.sizer.add(list, 1, wxStretch.EXPAND); + + var w = 80, h = 40; + + var imglist = new wxImageList(w, h, false, 0); + + var previews = Atlas.Message.GetTerrainGroupPreviews(this.name, w, h).previews; + var i = 0; + var names = []; + for each (var p in previews) + { + imglist.add(p.imagedata); + list.insertItem(i, '', i); + names.push(p.name); + ++i; + } + list.onMotion = function(evt) { + var hit = list.hitTest(evt.position); + var tip = undefined; + if (hit.item != -1 && (hit.flags & wxListHitTest.ONITEMICON)) + tip = names[hit.item] + if (list.toolTip !== tip) + list.toolTip = tip; + }; + list.onItemSelected = function(evt) { + Atlas.SetSelectedTexture(names[evt.index]); + }; + + list.setImageList(imglist, wxListCtrl.NORMAL); + + this.loaded = true; + } +}; + +function init(window, bottomWindow) { window.sizer = new wxBoxSizer(wxOrientation.VERTICAL); @@ -91,8 +137,10 @@ function init(window) } else { + // Disable the old tool if (selectedTool) selectedTool[2].backgroundColour = wxSystemSettings.getColour(wxSystemSettings.COLOUR_BTNFACE); + // Enable the new one selectedTool = tool; this.backgroundColour = new wxColour(0xEE, 0xCC, 0x55); Atlas.SetCurrentTool(tool[1]); @@ -139,4 +187,22 @@ function init(window) brush.strength = evt.position / 10; brush.send(); }; + + + + var terrainGroups = Atlas.Message.GetTerrainGroups(); + var nb = new wxNotebook(bottomWindow, -1); + bottomWindow.sizer = new wxBoxSizer(wxOrientation.VERTICAL); + bottomWindow.sizer.add(nb, 1, wxStretch.EXPAND); + var pages = []; + nb.onPageChanged = function (evt) { + pages[evt.selection].display() + } + for each (var groupname in terrainGroups.groupnames) + { + var panel = new wxPanel(nb, -1); + var page = new TerrainPreviewPage(panel, groupname); + pages.push(page); + nb.addPage(panel, groupname); // TODO: use Titlecase letters + } } diff --git a/source/tools/atlas/AtlasScript/ScriptInterface.cpp b/source/tools/atlas/AtlasScript/ScriptInterface.cpp index 978963a3f6..c2a0b585b0 100644 --- a/source/tools/atlas/AtlasScript/ScriptInterface.cpp +++ b/source/tools/atlas/AtlasScript/ScriptInterface.cpp @@ -15,14 +15,11 @@ #include "wxJS/io/init.h" #include "wxJS/gui/init.h" #include "wxJS/gui/control/panel.h" +#include "wxJS/gui/misc/bitmap.h" #include "GameInterface/Shareable.h" #include "GameInterface/Messages.h" -// We want to include Messages.h again below, with some different definitions, -// so cheat and undefine its include-guard -#undef INCLUDED_MESSAGES - #include #include @@ -88,7 +85,9 @@ namespace { static bool Convert(JSContext* cx, jsval v, std::wstring& out) { - JSString* ret = JS_ValueToString(cx, v); // never returns NULL + JSString* ret = JS_ValueToString(cx, v); + if (! ret) + FAIL("Argument must be convertible to a string"); jschar* ch = JS_GetStringChars(ret); out = std::wstring(ch, ch+JS_GetStringLength(ret)); return true; @@ -99,7 +98,9 @@ namespace { static bool Convert(JSContext* cx, jsval v, std::string& out) { - JSString* ret = JS_ValueToString(cx, v); // never returns NULL + JSString* ret = JS_ValueToString(cx, v); + if (! ret) + FAIL("Argument must be convertible to a string"); char* ch = JS_GetStringBytes(ret); out = std::string(ch); return true; @@ -110,7 +111,9 @@ namespace { static bool Convert(JSContext* cx, jsval v, wxString& out) { - JSString* ret = JS_ValueToString(cx, v); // never returns NULL + JSString* ret = JS_ValueToString(cx, v); + if (! ret) + FAIL("Argument must be convertible to a string"); jschar* ch = JS_GetStringChars(ret); out = wxString((const char*)ch, wxMBConvUTF16(), JS_GetStringLength(ret)*2); return true; @@ -127,6 +130,7 @@ namespace jsuint length; if (! JS_GetArrayLength(cx, obj, &length)) FAIL("Failed to get array length"); + out.reserve(length); for (jsint i = 0; i < length; ++i) { jsval el; @@ -140,6 +144,114 @@ namespace return true; } }; + + //////////////////////////////////////////////////////////////// + + template struct ToJSVal + { + static jsval Convert(JSContext* cx, const T& val) + { + JS_ReportError(cx, "Unrecognised query return type"); + return JSVAL_VOID; + } + }; + + /*template<> struct ToJSVal + { + static jsval Convert(JSContext* cx, const float& val) + { + jsval rval = JSVAL_VOID; + JS_NewDoubleValue(cx, val, &rval); // ignore return value + return rval; + } + };*/ + + template<> struct ToJSVal + { + static jsval Convert(JSContext* WXUNUSED(cx), const int& val) + { + return INT_TO_JSVAL(val); + } + }; + + template<> struct ToJSVal + { + static jsval Convert(JSContext* cx, const wxString& val) + { + wxMBConvUTF16 conv; + size_t length; + wxCharBuffer utf16 = conv.cWC2MB(val.c_str(), val.length()+1, &length); + JSString* str = JS_NewUCStringCopyN(cx, reinterpret_cast(utf16.data()), length/2); + if (str) + return STRING_TO_JSVAL(str); + else + return JSVAL_VOID; + } + }; + + template<> struct ToJSVal + { + static jsval Convert(JSContext* cx, const std::wstring& val) + { + wxMBConvUTF16 conv; + size_t length; + wxCharBuffer utf16 = conv.cWC2MB(val.c_str(), val.length()+1, &length); + JSString* str = JS_NewUCStringCopyN(cx, reinterpret_cast(utf16.data()), length/2); + if (str) + return STRING_TO_JSVAL(str); + else + return JSVAL_VOID; + } + }; + + template struct ToJSVal > + { + static jsval Convert(JSContext* cx, const std::vector& val) + { + JSObject* obj = JS_NewArrayObject(cx, 0, NULL); + if (! obj) return JSVAL_VOID; + JS_AddRoot(cx, &obj); + for (size_t i = 0; i < val.size(); ++i) + { + jsval el = ToJSVal::Convert(cx, val[i]); + JS_SetElement(cx, obj, i, &el); + } + JS_RemoveRoot(cx, &obj); + return OBJECT_TO_JSVAL(obj); + } + }; + + template struct ToJSVal > + { + static jsval Convert(JSContext* cx, const AtlasMessage::Shareable& val) + { + return ToJSVal::Convert(cx, val._Unwrap()); + } + }; + + //////////////////////////////////////////////////////////////// + + template<> struct ToJSVal + { + static jsval Convert(JSContext* cx, const AtlasMessage::sTerrainGroupPreview& val) + { + JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL); + if (! obj) return JSVAL_VOID; + JS_AddRoot(cx, &obj); + + JS_DefineProperty(cx, obj, "name", ToJSVal::Convert(cx, *val.name), NULL, NULL, JSPROP_ENUMERATE); + + unsigned char* buf = (unsigned char*)(malloc(val.imagedata.GetSize())); + memcpy(buf, val.imagedata.GetBuffer(), val.imagedata.GetSize()); + jsval bmp = wxjs::gui::Bitmap::CreateObject(cx, new wxBitmap (wxImage(val.imagewidth, val.imageheight, buf))); + JS_DefineProperty(cx, obj, "imagedata", bmp, NULL, NULL, JSPROP_ENUMERATE); + + JS_RemoveRoot(cx, &obj); + + return OBJECT_TO_JSVAL(obj); + } + }; + } template bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, T& out) @@ -147,35 +259,16 @@ template bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, T& return ::FromJSVal::Convert(cx, v, out); } +template jsval ScriptInterface::ToJSVal(JSContext* cx, const T& v) +{ + return ::ToJSVal::Convert(cx, v); +} + // Explicit instantiation of functions that would otherwise be unused in this file // but are required for linking with other files template bool ScriptInterface::FromJSVal(JSContext*, jsval, wxString&); -template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const float& val) -{ - jsval rval = JSVAL_VOID; - JS_NewDoubleValue(cx, val, &rval); // ignore return value - return rval; -} - -template<> jsval ScriptInterface::ToJSVal(JSContext* WXUNUSED(cx), const int& val) -{ - return INT_TO_JSVAL(val); -} - -template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const wxString& val) -{ - wxMBConvUTF16 conv; - size_t length; - wxCharBuffer utf16 = conv.cWC2MB(val.c_str(), val.length()+1, &length); - JSString* str = JS_NewUCStringCopyN(cx, reinterpret_cast(utf16.data()), length/2); - if (str) - return STRING_TO_JSVAL(str); - else - return JSVAL_VOID; -} - //////////////////////////////////////////////////////////////// struct ScriptInterface_impl @@ -358,32 +451,91 @@ wxPanel* ScriptInterface::LoadScriptAsPanel(const wxString& name, wxWindow* pare return panel; } +// TODO: this is an ugly function to provide +std::pair ScriptInterface::LoadScriptAsSidebar(const wxString& name, wxWindow* side, wxWindow* bottom) +{ + wxPanel* sidePanel = new wxPanel(side, -1); + JSObject* jsSideWindow = JSVAL_TO_OBJECT(wxjs::gui::Panel::CreateObject(m->m_cx, sidePanel)); + sidePanel->SetClientObject(new wxjs::JavaScriptClientData(m->m_cx, jsSideWindow, true, false)); + + wxPanel* bottomPanel = new wxPanel(bottom, -1); + JSObject* jsBottomWindow = JSVAL_TO_OBJECT(wxjs::gui::Panel::CreateObject(m->m_cx, bottomPanel)); + bottomPanel->SetClientObject(new wxjs::JavaScriptClientData(m->m_cx, jsBottomWindow, true, false)); + + jsval jsName = ToJSVal(m->m_cx, name); + + const uintN argc = 3; + jsval argv[argc] = { jsName, OBJECT_TO_JSVAL(jsSideWindow), OBJECT_TO_JSVAL(jsBottomWindow) }; + + jsval rval; + JS_CallFunctionName(m->m_cx, m->m_glob, "loadScript", argc, argv, &rval); // TODO: error checking + + // TODO: This really need a better way to handle these two windows (of which one is optional)... + if (bottomPanel->GetChildren().size() != 0) + return std::make_pair(sidePanel, bottomPanel); + else + { + bottomPanel->Destroy(); + return std::make_pair(sidePanel, static_cast(NULL)); + } +} + //////////////////////////////////////////////////////////////// -struct MessageWrapper +#define TYPE(elem) BOOST_PP_TUPLE_ELEM(2, 0, elem) +#define NAME(elem) BOOST_PP_TUPLE_ELEM(2, 1, elem) +#define MAKE_STR_(s) #s +#define MAKE_STR(s) MAKE_STR_(s) + +#define CONVERT_ARGS(r, data, i, elem) \ + TYPE(elem) a##i; \ + if (! ScriptInterface::FromJSVal< TYPE(elem) >(cx, argv[i], a##i)) \ + return JS_FALSE; + +#define CONVERT_OUTPUTS(r, data, i, elem) \ + JS_DefineProperty(cx, ret, MAKE_STR(NAME(elem)), ScriptInterface::ToJSVal(cx, q.NAME(elem)), \ + NULL, NULL, JSPROP_ENUMERATE); + +#define ARG_LIST(r, data, i, elem) BOOST_PP_COMMA_IF(i) a##i + +#define MESSAGE(name, vals) \ + JSBool call_##name(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* WXUNUSED(rval)) \ + { \ + BOOST_PP_SEQ_FOR_EACH_I(CONVERT_ARGS, ~, vals) \ + g_MessagePasser->Add(SHAREABLE_NEW(m##name, ( BOOST_PP_SEQ_FOR_EACH_I(ARG_LIST, ~, vals) ))); \ + return JS_TRUE; \ + } + +#define QUERY(name, in_vals, out_vals) \ + JSBool call_##name(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) \ + { \ + BOOST_PP_SEQ_FOR_EACH_I(CONVERT_ARGS, ~, in_vals) \ + q##name q = q##name( BOOST_PP_SEQ_FOR_EACH_I(ARG_LIST, ~, in_vals) ); \ + q.Post(); \ + JSObject* ret = JS_NewObject(cx, NULL, NULL, NULL); \ + if (! ret) return JS_FALSE; \ + *rval = OBJECT_TO_JSVAL(ret); \ + BOOST_PP_SEQ_FOR_EACH_I(CONVERT_OUTPUTS, ~, out_vals) \ + return JS_TRUE; \ + } + +#define COMMAND(name, merge, vals) + +#define MESSAGES_SKIP_SETUP +#define MESSAGES_SKIP_STRUCTS + +// We want to include Messages.h again, with some different definitions, +// so cheat and undefine its include-guard +#undef INCLUDED_MESSAGES + +namespace { - #define NUMBERED_LIST(z, i, data) , data##i - #define NUMBERED_LIST2(z, i, data) BOOST_PP_COMMA_IF(i) data##i - #define CONVERT_ARGS(z, i, data) T##i a##i; if (! ScriptInterface::FromJSVal(cx, argv[i], a##i)) return JS_FALSE; - #define OVERLOADS(z, i, data) \ - template \ - static JSNative call(Message* (*WXUNUSED(fptr)) ( BOOST_PP_REPEAT_##z(i, NUMBERED_LIST2, T) )) { \ - return &_call; \ - } \ - template \ - static uintN nargs(Message* (*WXUNUSED(fptr)) ( BOOST_PP_REPEAT_##z(i, NUMBERED_LIST2, T) )) { \ - return i; \ - } \ - template \ - static JSBool _call(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* WXUNUSED(rval)) \ - { \ - (void)cx; (void)obj; (void)argc; (void)argv; /* avoid 'unused parameter' warnings */ \ - BOOST_PP_REPEAT_##z (i, CONVERT_ARGS, ~) \ - AtlasMessage::g_MessagePasser->Add(SHAREABLE_NEW(Message, ( BOOST_PP_REPEAT_##z(i, NUMBERED_LIST2, a) ))); \ - return JS_TRUE; \ - } - BOOST_PP_REPEAT(7, OVERLOADS, ~) -}; + using namespace AtlasMessage; + #include "GameInterface/Messages.h" +} + +#undef MESSAGE +#undef QUERY void ScriptInterface_impl::RegisterMessages(JSObject* parent) { @@ -392,20 +544,17 @@ void ScriptInterface_impl::RegisterMessages(JSObject* parent) JSFunction* ret; JSObject* obj = JS_DefineObject(m_cx, parent, "Message", NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT); -#define MESSAGE(name, vals) \ - ret = JS_DefineFunction(m_cx, obj, #name, MessageWrapper::call(&m##name::CtorType), MessageWrapper::nargs(&m##name::CtorType), JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT); + #define MESSAGE(name, vals) \ + ret = JS_DefineFunction(m_cx, obj, #name, call_##name, BOOST_PP_SEQ_SIZE((~)vals)-1, \ + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT); -#define QUERY(name, in_vals, out_vals) /* TODO \ - extern void f##name##_wrapper(AtlasMessage::IMessage*); \ - AtlasMessage::GetMsgHandlers().insert(std::pair(#name, &f##name##_wrapper));*/ + #define QUERY(name, in_vals, out_vals) \ + ret = JS_DefineFunction(m_cx, obj, #name, call_##name, BOOST_PP_SEQ_SIZE((~)in_vals)-1, \ + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT); + + // TODO: #define COMMAND(name, merge, vals) ... -#define COMMAND(name, merge, vals) /* TODO \ - extern cmdHandler c##name##_create(); \ - GetCmdHandlers().insert(std::pair("c"#name, c##name##_create()));*/ - -#undef SHAREABLE_STRUCT -#define SHAREABLE_STRUCT(name) - - #define MESSAGES_SKIP_SETUP + #undef INCLUDED_MESSAGES + #include "GameInterface/Messages.h" } diff --git a/source/tools/atlas/AtlasScript/ScriptInterface.h b/source/tools/atlas/AtlasScript/ScriptInterface.h index 817a9d2017..8214233969 100644 --- a/source/tools/atlas/AtlasScript/ScriptInterface.h +++ b/source/tools/atlas/AtlasScript/ScriptInterface.h @@ -35,6 +35,7 @@ public: void LoadScript(const wxString& filename, const wxString& code); wxPanel* LoadScriptAsPanel(const wxString& name, wxWindow* parent); + std::pair LoadScriptAsSidebar(const wxString& name, wxWindow* side, wxWindow* bottom); template static bool FromJSVal(JSContext* cx, jsval val, T& ret); template static jsval ToJSVal(JSContext* cx, const T& val); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index 28618b9841..789c33d6a8 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp @@ -24,6 +24,7 @@ #include "Tools/Common/Tools.h" #include "Tools/Common/Brushes.h" +#include "Tools/Common/MiscState.h" static HighResTimer g_Timer; @@ -276,6 +277,10 @@ namespace { g_Brush_Elevation.SetStrength(strength); } + void SetSelectedTexture(wxString name) + { + g_SelectedTexture = name; + } } ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterface) @@ -299,6 +304,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac GetScriptInterface().RegisterFunction("GetDataDirectory"); GetScriptInterface().RegisterFunction("SetCurrentTool"); GetScriptInterface().RegisterFunction("SetBrushStrength"); + GetScriptInterface().RegisterFunction("SetSelectedTexture"); { const wxString relativePath (_T("tools/atlas/scripts/main.js")); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp index 0da4673045..95a8997fc9 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp @@ -232,11 +232,19 @@ class ScriptedSidebar : public Sidebar { public: ScriptedSidebar(const wxString& name, ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer) - : Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer) + : Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer), m_BottomBarContainer(bottomBarContainer), m_Name(name) { - wxPanel* panel = m_ScenarioEditor.GetScriptInterface().LoadScriptAsPanel(_T("section/") + name, this); - m_MainSizer->Add(panel, wxSizerFlags(1).Expand()); } + + virtual void OnFirstDisplay() + { + std::pair panels = m_ScenarioEditor.GetScriptInterface().LoadScriptAsSidebar(_T("section/") + m_Name, this, m_BottomBarContainer); + m_MainSizer->Add(panels.first, wxSizerFlags(1).Expand()); + m_BottomBar = panels.second; + } +private: + wxString m_Name; + wxWindow* m_BottomBarContainer; }; @@ -288,7 +296,7 @@ void SectionLayout::Build(ScenarioEditor& scenarioEditor) ADD_SIDEBAR_SCRIPT(_T("map"), _T("map.png"), _("Map")); ADD_SIDEBAR_SCRIPT(_T("terrain"), _T("terrain.png"), _("Terrain")); - ADD_SIDEBAR(TerrainSidebar, _T("terrain.png"), _("Terrain")); + //ADD_SIDEBAR(TerrainSidebar, _T("terrain.png"), _("Terrain")); ADD_SIDEBAR(ObjectSidebar, _T("object.png"), _("Object")); ADD_SIDEBAR(EnvironmentSidebar, _T("environment.png"), _("Environment")); diff --git a/source/tools/atlas/GameInterface/Brushes.cpp b/source/tools/atlas/GameInterface/Brushes.cpp index 6ee94c517d..ae5ef52048 100644 --- a/source/tools/atlas/GameInterface/Brushes.cpp +++ b/source/tools/atlas/GameInterface/Brushes.cpp @@ -66,7 +66,7 @@ void Brush::SetData(int w, int h, const std::vector& data) m_Data = data; - debug_assert(data.size() == w*h); + debug_assert(data.size() == (size_t)(w*h)); } void Brush::GetCentre(int& x, int& y) const diff --git a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp index ab7ab952c6..da702a34cd 100644 --- a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp @@ -88,6 +88,8 @@ QUERYHANDLER(GetTerrainGroupPreviews) delete[] texdata; } + previews.back().imagewidth = msg->imagewidth; + previews.back().imageheight = msg->imageheight; previews.back().imagedata = buf; } diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index 47af1d0a7d..6803fca4f8 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -99,11 +99,13 @@ MESSAGE(Screenshot, ((int, tiles)) // the final image will be (640*tiles)x(480*tiles) ); +#ifndef MESSAGES_SKIP_STRUCTS struct sCinemaRecordCB { unsigned char* buffer; }; SHAREABLE_STRUCT(sCinemaRecordCB); +#endif QUERY(CinemaRecord, ((std::wstring, path)) @@ -136,12 +138,16 @@ QUERY(GetTerrainGroups, ((std::vector, groupnames)) ); +#ifndef MESSAGES_SKIP_STRUCTS struct sTerrainGroupPreview { Shareable name; - Shareable > imagedata; // RGB*size*size + Shareable imagewidth; + Shareable imageheight; + Shareable > imagedata; // RGB*width*height }; SHAREABLE_STRUCT(sTerrainGroupPreview); +#endif QUERY(GetTerrainGroupPreviews, ((std::wstring, groupname)) @@ -154,6 +160,7 @@ QUERY(GetTerrainGroupPreviews, ////////////////////////////////////////////////////////////////////////// +#ifndef MESSAGES_SKIP_STRUCTS struct sObjectsListItem { Shareable id; @@ -161,12 +168,14 @@ struct sObjectsListItem Shareable type; // 0 = entity, 1 = actor }; SHAREABLE_STRUCT(sObjectsListItem); +#endif QUERY(GetObjectsList, , // no inputs ((std::vector, objects)) // sorted by .name ); +#ifndef MESSAGES_SKIP_STRUCTS struct sObjectSettings { Shareable player; @@ -178,6 +187,7 @@ struct sObjectSettings Shareable > > variantgroups; }; SHAREABLE_STRUCT(sObjectSettings); +#endif // Preview object in the game world - creates a temporary unit at the given // position, and removes it when the preview is next changed @@ -249,6 +259,7 @@ MESSAGE(LookAt, ////////////////////////////////////////////////////////////////////////// +#ifndef MESSAGES_SKIP_STRUCTS struct sEnvironmentSettings { Shareable waterheight; // range 0..1 corresponds to min..max terrain height; out-of-bounds values allowed @@ -276,6 +287,7 @@ struct sEnvironmentSettings Shareable unitcolour; }; SHAREABLE_STRUCT(sEnvironmentSettings); +#endif QUERY(GetEnvironmentSettings, // no inputs diff --git a/source/tools/atlas/GameInterface/MessagesSetup.h b/source/tools/atlas/GameInterface/MessagesSetup.h index f2d02c1214..35cf2e60e5 100644 --- a/source/tools/atlas/GameInterface/MessagesSetup.h +++ b/source/tools/atlas/GameInterface/MessagesSetup.h @@ -151,6 +151,7 @@ const bool NOMERGE = false; #define QUERY_WITHOUT_INPUTS(name, in_vals, out_vals) \ QUERYSTRUCT(name) \ q##name() {} \ + static q##name* CtorType() { return NULL; } \ BOOST_PP_SEQ_FOR_EACH_I(B_MEMBERS, ~, out_vals) /* other members */ \ } @@ -158,6 +159,7 @@ const bool NOMERGE = false; QUERYSTRUCT(name) \ q##name( BOOST_PP_SEQ_FOR_EACH_I(B_CONSTRUCTORARGS, ~, in_vals) ) \ : BOOST_PP_SEQ_FOR_EACH_I(B_CONSTRUCTORINIT, ~, in_vals) {} \ + static q##name* CtorType( BOOST_PP_SEQ_FOR_EACH_I(B_CONSTRUCTORTYPES, ~, in_vals) ) { return NULL; } \ BOOST_PP_SEQ_FOR_EACH_I(B_CONSTMEMBERS, ~, in_vals) \ BOOST_PP_SEQ_FOR_EACH_I(B_MEMBERS, ~, out_vals) \ } diff --git a/source/tools/atlas/GameInterface/Shareable.h b/source/tools/atlas/GameInterface/Shareable.h index 507c1b4c8d..23912a041d 100644 --- a/source/tools/atlas/GameInterface/Shareable.h +++ b/source/tools/atlas/GameInterface/Shareable.h @@ -273,6 +273,7 @@ public: // (TODO - this is probably not really safely shareable, due to unspecified calling conventions) template struct Callback { + Callback() : cb(NULL), cbdata(NULL) {} Callback(void (*cb) (const T*, void*), void* cbdata) : cb(cb), cbdata(cbdata) {} void (*cb) (const T*, void*); void* cbdata; diff --git a/source/tools/atlas/wxJS/gui/control/bookctrl.cpp b/source/tools/atlas/wxJS/gui/control/bookctrl.cpp new file mode 100644 index 0000000000..5368687d56 --- /dev/null +++ b/source/tools/atlas/wxJS/gui/control/bookctrl.cpp @@ -0,0 +1,119 @@ +#include "precompiled.h" + +#ifndef WX_PRECOMP + #include +#endif + +#include "../../common/main.h" + +#include "bookctrl.h" +#include "window.h" + +using namespace wxjs; +using namespace wxjs::gui; + +WXJS_INIT_CLASS(BookCtrlBase, "wxBookCtrlBase", 0) + +WXJS_BEGIN_CONSTANT_MAP(BookCtrlBase) + WXJS_CONSTANT(wxBK_, HITTEST_NOWHERE) + WXJS_CONSTANT(wxBK_, HITTEST_ONICON) + WXJS_CONSTANT(wxBK_, HITTEST_ONLABEL) + WXJS_CONSTANT(wxBK_, HITTEST_ONITEM) + WXJS_CONSTANT(wxBK_, HITTEST_ONPAGE) + WXJS_CONSTANT(wxBK_, DEFAULT) + WXJS_CONSTANT(wxBK_, TOP) + WXJS_CONSTANT(wxBK_, BOTTOM) + WXJS_CONSTANT(wxBK_, LEFT) + WXJS_CONSTANT(wxBK_, RIGHT) +WXJS_END_CONSTANT_MAP() + +WXJS_BEGIN_PROPERTY_MAP(BookCtrlBase) + WXJS_READONLY_PROPERTY(P_PAGE_COUNT, "pageCount") +WXJS_END_PROPERTY_MAP() + +bool BookCtrlBase::GetProperty(wxBookCtrlBase *p, JSContext *cx, JSObject *obj, int id, jsval *vp) +{ + switch (id) + { + case P_PAGE_COUNT: + *vp = ToJS(cx, p->GetPageCount()); + break; + } + return true; +} + +bool BookCtrlBase::SetProperty(wxBookCtrlBase *p, JSContext *cx, JSObject *obj, int id, jsval *vp) +{ + return true; +} + +WXJS_BEGIN_METHOD_MAP(BookCtrlBase) + WXJS_METHOD("addPage", addPage, 2) + WXJS_METHOD("deleteAllPages", deleteAllPages, 0) + WXJS_METHOD("getPage", getPage, 1) +WXJS_END_METHOD_MAP() + +JSBool BookCtrlBase::addPage(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + wxBookCtrlBase *p = GetPrivate(cx, obj); + if ( p == NULL ) + return JS_FALSE; + + wxWindow *win; + wxString text; + bool select = false; + int imageId = -1; + + if ( argc >= 4 ) + { + if ( ! FromJS(cx, argv[3], imageId) ) + return JS_FALSE; + } + if ( argc >= 3 ) + { + if ( ! FromJS(cx, argv[2], select) ) + return JS_FALSE; + } + + FromJS(cx, argv[1], text); + win = Window::GetPrivate(cx, argv[0]); + if ( win == NULL ) + return JS_FALSE; + + p->AddPage(win, text, select, imageId); + + return JS_TRUE; +} + +JSBool BookCtrlBase::deleteAllPages(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + wxBookCtrlBase *p = GetPrivate(cx, obj); + if ( p == NULL ) + return JS_FALSE; + + p->DeleteAllPages(); + + return JS_TRUE; +} + +JSBool BookCtrlBase::getPage(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + wxBookCtrlBase *p = GetPrivate(cx, obj); + if ( p == NULL ) + return JS_FALSE; + + size_t page; + if ( ! FromJS(cx, argv[0], page) ) + return JS_FALSE; + + wxWindow *win = p->GetPage(page); + + JavaScriptClientData *data + = dynamic_cast(win->GetClientObject()); + if ( data == NULL ) + return JS_FALSE; + + *rval = OBJECT_TO_JSVAL(data->GetObject()); + + return JS_TRUE; +} diff --git a/source/tools/atlas/wxJS/gui/control/bookctrl.h b/source/tools/atlas/wxJS/gui/control/bookctrl.h new file mode 100644 index 0000000000..011120cfac --- /dev/null +++ b/source/tools/atlas/wxJS/gui/control/bookctrl.h @@ -0,0 +1,42 @@ +#ifndef _WXJSBOOKCTRL_H +#define _WXJSBOOKCTRL_H + +#include "../../common/evtconn.h" + +#include + +namespace wxjs +{ + namespace gui + { + class BookCtrlBase : public ApiWrapper + { + public: + static bool GetProperty(wxBookCtrlBase *p, + JSContext *cx, + JSObject *obj, + int id, + jsval *vp); + static bool SetProperty(wxBookCtrlBase *p, + JSContext *cx, + JSObject *obj, + int id, + jsval *vp); + + WXJS_DECLARE_METHOD_MAP() + WXJS_DECLARE_METHOD(addPage) + WXJS_DECLARE_METHOD(deleteAllPages) + WXJS_DECLARE_METHOD(getPage) + + WXJS_DECLARE_CONSTANT_MAP() + + WXJS_DECLARE_PROPERTY_MAP() + enum + { + P_PAGE_COUNT + }; + }; + }; // namespace gui +}; // namespace wxjs + +#endif //_WXJSBOOKCTRL_H diff --git a/source/tools/atlas/wxJS/gui/control/notebook.cpp b/source/tools/atlas/wxJS/gui/control/notebook.cpp new file mode 100644 index 0000000000..fdfe03a155 --- /dev/null +++ b/source/tools/atlas/wxJS/gui/control/notebook.cpp @@ -0,0 +1,257 @@ +#include "precompiled.h" + +#ifndef WX_PRECOMP + #include +#endif + +#include "../../common/main.h" + +#include "../event/jsevent.h" +#include "../event/notebookevt.h" + +#include "notebook.h" +#include "bookctrl.h" +#include "window.h" + +#include "../misc/point.h" +#include "../misc/size.h" +#include "../errors.h" + +using namespace wxjs; +using namespace wxjs::gui; + +WXJS_INIT_CLASS(Notebook, "wxNotebook", 2) + +void Notebook::InitClass(JSContext* WXUNUSED(cx), + JSObject* WXUNUSED(obj), + JSObject* WXUNUSED(proto)) +{ + NotebookEventHandler::InitConnectEventMap(); +} + +WXJS_BEGIN_CONSTANT_MAP(Notebook) + WXJS_CONSTANT(wxNB_, HITTEST_NOWHERE) + WXJS_CONSTANT(wxNB_, HITTEST_ONICON) + WXJS_CONSTANT(wxNB_, HITTEST_ONLABEL) + WXJS_CONSTANT(wxNB_, HITTEST_ONITEM) + WXJS_CONSTANT(wxNB_, HITTEST_ONPAGE) + WXJS_CONSTANT(wxNB_, DEFAULT) + WXJS_CONSTANT(wxNB_, TOP) + WXJS_CONSTANT(wxNB_, BOTTOM) + WXJS_CONSTANT(wxNB_, LEFT) + WXJS_CONSTANT(wxNB_, RIGHT) + WXJS_CONSTANT(wxNB_, FIXEDWIDTH) + WXJS_CONSTANT(wxNB_, MULTILINE) + WXJS_CONSTANT(wxNB_, NOPAGETHEME) + WXJS_CONSTANT(wxNB_, FLAT) +WXJS_END_CONSTANT_MAP() + +WXJS_BEGIN_PROPERTY_MAP(Notebook) + WXJS_READONLY_PROPERTY(P_ROW_COUNT, "rowCount") +WXJS_END_PROPERTY_MAP() + +bool Notebook::GetProperty(wxNotebook *p, JSContext *cx, JSObject *obj, int id, jsval *vp) +{ + switch (id) + { + case P_ROW_COUNT: + *vp = ToJS(cx, p->GetRowCount()); + break; + } + return true; +} + +bool Notebook::SetProperty(wxNotebook *p, JSContext *cx, JSObject *obj, int id, jsval *vp) +{ + switch (id) + { + } + return true; +} + +bool Notebook::AddProperty(wxNotebook *p, + JSContext* WXUNUSED(cx), + JSObject* WXUNUSED(obj), + const wxString &prop, + jsval* WXUNUSED(vp)) +{ + if ( WindowEventHandler::ConnectEvent(p, prop, true) ) + return true; + + NotebookEventHandler::ConnectEvent(p, prop, true); + + return true; +} + +bool Notebook::DeleteProperty(wxNotebook *p, + JSContext* WXUNUSED(cx), + JSObject* WXUNUSED(obj), + const wxString &prop) +{ + if ( WindowEventHandler::ConnectEvent(p, prop, false) ) + return true; + + NotebookEventHandler::ConnectEvent(p, prop, false); + return true; +} + +// HACK: so I don't get PAGE_CHANGED events when ~wxNotebook is calling DeleteAllPages +struct Wrapper_wxNotebook : public wxNotebook +{ + ~Wrapper_wxNotebook() + { + wxList* d = GetDynamicEventTable(); + for (wxList::iterator it = d->begin(), end = d->end(); it != end; ++it) + { + wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)*it; + delete entry->m_callbackUserData; + delete entry; + } + d->Clear(); + } +}; + +wxNotebook* Notebook::Construct(JSContext *cx, + JSObject *obj, + uintN argc, + jsval *argv, + bool WXUNUSED(constructing)) +{ + wxNotebook *p = new Wrapper_wxNotebook(); + SetPrivate(cx, obj, p); + + if ( argc > 0 ) + { + jsval rval; + if ( ! create(cx, obj, argc, argv, &rval) ) + return NULL; + } + return p; +} + +WXJS_BEGIN_METHOD_MAP(Notebook) + WXJS_METHOD("create", create, 2) +WXJS_END_METHOD_MAP() + +JSBool Notebook::create(JSContext *cx, + JSObject *obj, + uintN argc, + jsval *argv, + jsval *rval) +{ + wxNotebook *p = GetPrivate(cx, obj); + *rval = JSVAL_FALSE; + + if ( argc > 5 ) + argc = 5; + + wxWindowID id = -1; + const wxPoint *pt = &wxDefaultPosition; + const wxSize *size = &wxDefaultSize; + int style = 0; + + switch(argc) + { + case 5: + if ( ! FromJS(cx, argv[4], style) ) + { + JS_ReportError(cx, WXJS_INVALID_ARG_TYPE, 4, "Integer"); + return JS_FALSE; + } + // Fall through + case 4: + size = Size::GetPrivate(cx, argv[3]); + if ( size == NULL ) + { + JS_ReportError(cx, WXJS_INVALID_ARG_TYPE, 3, "wxSize"); + return JS_FALSE; + } + // Fall through + case 3: + pt = Point::GetPrivate(cx, argv[2]); + if ( pt == NULL ) + { + JS_ReportError(cx, WXJS_INVALID_ARG_TYPE, 3, "wxPoint"); + return JS_FALSE; + } + // Fall through + default: + + if ( ! FromJS(cx, argv[1], id) ) + { + JS_ReportError(cx, WXJS_INVALID_ARG_TYPE, 2, "Integer"); + return JS_FALSE; + } + + wxWindow *parent = Window::GetPrivate(cx, argv[0]); + if ( parent == NULL ) + { + JS_ReportError(cx, WXJS_NO_PARENT_ERROR, GetClass()->name); + return JS_FALSE; + } + JavaScriptClientData *clntParent = + dynamic_cast(parent->GetClientObject()); + if ( clntParent == NULL ) + { + JS_ReportError(cx, WXJS_NO_PARENT_ERROR, GetClass()->name); + return JS_FALSE; + } + JS_SetParent(cx, obj, clntParent->GetObject()); + + if ( p->Create(parent, id, *pt, *size, style) ) + { + *rval = JSVAL_TRUE; + p->SetClientObject(new JavaScriptClientData(cx, obj, true, false)); + } + } + + return JS_TRUE; +} + +WXJS_INIT_EVENT_MAP(wxNotebook) +const wxString WXJS_PAGE_CHANGED_EVENT = wxT("onPageChanged"); +const wxString WXJS_PAGE_CHANGING_EVENT = wxT("onPageChanging"); + +void NotebookEventHandler::OnPageChanged(wxNotebookEvent &event) +{ + PrivNotebookEvent::Fire(event, WXJS_PAGE_CHANGED_EVENT); +} + +void NotebookEventHandler::OnPageChanging(wxNotebookEvent &event) +{ + PrivNotebookEvent::Fire(event, WXJS_PAGE_CHANGING_EVENT); +} + +void NotebookEventHandler::ConnectPageChanged(wxNotebook *p, bool connect) +{ + if ( connect ) + { + p->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, + wxNotebookEventHandler(OnPageChanged)); + } + else + { + p->Disconnect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, + wxNotebookEventHandler(OnPageChanged)); + } +} + +void NotebookEventHandler::ConnectPageChanging(wxNotebook *p, bool connect) +{ + if ( connect ) + { + p->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, + wxNotebookEventHandler(OnPageChanging)); + } + else + { + p->Disconnect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, + wxNotebookEventHandler(OnPageChanging)); + } +} + +void NotebookEventHandler::InitConnectEventMap() +{ + AddConnector(WXJS_PAGE_CHANGED_EVENT, ConnectPageChanged); + AddConnector(WXJS_PAGE_CHANGING_EVENT, ConnectPageChanging); +} diff --git a/source/tools/atlas/wxJS/gui/control/notebook.h b/source/tools/atlas/wxJS/gui/control/notebook.h new file mode 100644 index 0000000000..b6c38af7df --- /dev/null +++ b/source/tools/atlas/wxJS/gui/control/notebook.h @@ -0,0 +1,69 @@ +#ifndef _WXJSNOTEBOOK_H +#define _WXJSNOTEBOOK_H + +#include "../../common/evtconn.h" + +#include + +namespace wxjs +{ + namespace gui + { + class Notebook : public ApiWrapper + { + public: + static void InitClass(JSContext *cx, + JSObject *obj, + JSObject *proto); + static bool AddProperty(wxNotebook *p, + JSContext *cx, + JSObject *obj, + const wxString &prop, + jsval *vp); + static bool DeleteProperty(wxNotebook *p, + JSContext *cx, + JSObject *obj, + const wxString &prop); + static bool GetProperty(wxNotebook *p, + JSContext *cx, + JSObject *obj, + int id, + jsval *vp); + static bool SetProperty(wxNotebook *p, + JSContext *cx, + JSObject *obj, + int id, + jsval *vp); + + static wxNotebook* Construct(JSContext *cx, + JSObject *obj, + uintN argc, + jsval *argv, + bool constructing); + + WXJS_DECLARE_METHOD_MAP() + WXJS_DECLARE_METHOD(create) + + WXJS_DECLARE_CONSTANT_MAP() + + WXJS_DECLARE_PROPERTY_MAP() + enum + { + P_ROW_COUNT + }; + }; + class NotebookEventHandler : public EventConnector + , public wxEvtHandler + { + public: + void OnPageChanged(wxNotebookEvent &event); + void OnPageChanging(wxNotebookEvent &event); + static void InitConnectEventMap(); + private: + static void ConnectPageChanged(wxNotebook *p, bool connect); + static void ConnectPageChanging(wxNotebook *p, bool connect); + }; + }; // namespace gui +}; // namespace wxjs + +#endif //_WXJSNOTEBOOK_H diff --git a/source/tools/atlas/wxJS/gui/control/window.cpp b/source/tools/atlas/wxJS/gui/control/window.cpp index 41ac0d4f75..12cf98b598 100644 --- a/source/tools/atlas/wxJS/gui/control/window.cpp +++ b/source/tools/atlas/wxJS/gui/control/window.cpp @@ -32,6 +32,8 @@ #include "../../common/main.h" +#include + #include "window.h" #include "../misc/point.h" #include "../misc/size.h" @@ -198,6 +200,7 @@ WXJS_BEGIN_PROPERTY_MAP(Window) WXJS_PROPERTY(P_BACKGROUND_COLOUR, "backgroundColour") WXJS_PROPERTY(P_FOREGROUND_COLOUR, "foregroundColour") WXJS_PROPERTY(P_FONT, "font") + WXJS_PROPERTY(P_TOOL_TIP, "toolTip") WXJS_END_PROPERTY_MAP() bool Window::GetProperty(wxWindow *p, JSContext *cx, JSObject *obj, int id, jsval *vp) @@ -347,6 +350,15 @@ bool Window::GetProperty(wxWindow *p, JSContext *cx, JSObject *obj, int id, jsva case P_FONT: *vp = Font::CreateObject(cx, new wxFont(p->GetFont()), obj); break; + case P_TOOL_TIP: + if ( p->GetToolTip() == NULL ) + *vp = JSVAL_VOID; + else + { + wxString tip = p->GetToolTip()->GetTip(); + *vp = ToJS(cx, tip); + } + break; } return true; } @@ -528,6 +540,17 @@ bool Window::SetProperty(wxWindow *p, JSContext *cx, JSObject *obj, int id, jsva p->SetFont(*font); break; } + case P_TOOL_TIP: + if ( JSVAL_IS_VOID(*vp) ) + { + p->SetToolTip(NULL); + } + else + { + wxString tip; + FromJS(cx, *vp, tip); + p->SetToolTip(tip); + } } return true; } diff --git a/source/tools/atlas/wxJS/gui/control/window.h b/source/tools/atlas/wxJS/gui/control/window.h index 86e96eeb48..624cc07997 100644 --- a/source/tools/atlas/wxJS/gui/control/window.h +++ b/source/tools/atlas/wxJS/gui/control/window.h @@ -129,6 +129,7 @@ namespace wxjs , P_BACKGROUND_COLOUR , P_FOREGROUND_COLOUR , P_FONT + , P_TOOL_TIP }; }; diff --git a/source/tools/atlas/wxJS/gui/event/jsevent.cpp b/source/tools/atlas/wxJS/gui/event/jsevent.cpp index 2286ac70fa..771817e610 100644 --- a/source/tools/atlas/wxJS/gui/event/jsevent.cpp +++ b/source/tools/atlas/wxJS/gui/event/jsevent.cpp @@ -48,6 +48,7 @@ #include "htmllink.h" #include "split.h" #include "spinevt.h" +#include "notebookevt.h" #include "notify.h" #include "listevt.h" @@ -178,5 +179,10 @@ bool wxjs::gui::InitEventClasses(JSContext *cx, JSObject *global) if (! obj ) return false; - return true; + obj = NotebookEvent::JSInit(cx, global, NotifyEvent::GetClassPrototype()); + wxASSERT_MSG(obj != NULL, wxT("wxNotebookEvent prototype creation failed")); + if (! obj ) + return false; + + return true; } diff --git a/source/tools/atlas/wxJS/gui/event/notebookevt.cpp b/source/tools/atlas/wxJS/gui/event/notebookevt.cpp new file mode 100644 index 0000000000..5512087bca --- /dev/null +++ b/source/tools/atlas/wxJS/gui/event/notebookevt.cpp @@ -0,0 +1,72 @@ +#include "precompiled.h" + +#ifndef WX_PRECOMP + #include +#endif + +#include "../../common/main.h" +#include "../../common/apiwrap.h" + +#include + +#include "jsevent.h" +#include "../misc/size.h" +#include "notebookevt.h" + +using namespace wxjs; +using namespace wxjs::gui; + +WXJS_INIT_CLASS(NotebookEvent, "wxNotebookEvent", 0) + +WXJS_BEGIN_PROPERTY_MAP(NotebookEvent) + WXJS_PROPERTY(P_OLD_SELECTION, "oldSelection") + WXJS_PROPERTY(P_SELECTION, "selection") +WXJS_END_PROPERTY_MAP() + +bool NotebookEvent::GetProperty(PrivNotebookEvent *p, + JSContext *cx, + JSObject* WXUNUSED(obj), + int id, + jsval *vp) +{ + wxNotebookEvent *event = (wxNotebookEvent*) p->GetEvent(); + + switch ( id ) + { + case P_OLD_SELECTION: + *vp = ToJS(cx, event->GetOldSelection()); + break; + case P_SELECTION: + *vp = ToJS(cx, event->GetSelection()); + break; + } + return true; +} + +bool NotebookEvent::SetProperty(PrivNotebookEvent *p, + JSContext *cx, + JSObject* WXUNUSED(obj), + int id, + jsval *vp) +{ + wxNotebookEvent *event = (wxNotebookEvent*) p->GetEvent(); + + switch ( id ) + { + case P_OLD_SELECTION: + { + int sel; + if ( FromJS(cx, *vp, sel) ) + event->SetOldSelection(sel); + break; + } + case P_SELECTION: + { + int sel; + if ( FromJS(cx, *vp, sel) ) + event->SetSelection(sel); + break; + } + } + return true; +} diff --git a/source/tools/atlas/wxJS/gui/event/notebookevt.h b/source/tools/atlas/wxJS/gui/event/notebookevt.h new file mode 100644 index 0000000000..83c71f5a34 --- /dev/null +++ b/source/tools/atlas/wxJS/gui/event/notebookevt.h @@ -0,0 +1,28 @@ +#ifndef _WXJSNotebookEvent_H +#define _WXJSNotebookEvent_H + +class wxNotebookEvent; + +namespace wxjs +{ + namespace gui + { + typedef JSEvent PrivNotebookEvent; + class NotebookEvent : public ApiWrapper + { + public: + static bool GetProperty(PrivNotebookEvent *p, JSContext *cx, JSObject *obj, int id, jsval *vp); + static bool SetProperty(PrivNotebookEvent *p, JSContext *cx, JSObject *obj, int id, jsval *vp); + + enum + { + P_OLD_SELECTION + , P_SELECTION + }; + + WXJS_DECLARE_PROPERTY_MAP() + }; + }; // namespace gui +}; // namespace wxjs + +#endif //_WXJSNotebookEvent_H diff --git a/source/tools/atlas/wxJS/gui/gui_init.cpp b/source/tools/atlas/wxJS/gui/gui_init.cpp index 602337e74a..77bec0002b 100644 --- a/source/tools/atlas/wxJS/gui/gui_init.cpp +++ b/source/tools/atlas/wxJS/gui/gui_init.cpp @@ -90,6 +90,8 @@ #include "control/htmlwin.h" #include "control/spinctrl.h" #include "control/spinbtn.h" +#include "control/bookctrl.h" +#include "control/notebook.h" // Validators #include "misc/validate.h" @@ -638,6 +640,16 @@ bool wxjs::gui::InitClass(JSContext *cx, JSObject *global) if (! obj ) return false; + obj = BookCtrlBase::JSInit(cx, global, Control::GetClassPrototype()); + wxASSERT_MSG(obj != NULL, wxT("wxBookCtrlBase prototype creation failed")); + if (! obj ) + return false; + + obj = Notebook::JSInit(cx, global, BookCtrlBase::GetClassPrototype()); + wxASSERT_MSG(obj != NULL, wxT("wxNotebook prototype creation failed")); + if (! obj ) + return false; + // Define the global functions InitFunctions(cx, global);