|
|
@@ -2,9 +2,12 @@
|
|
|
|
|
|
#include <Atomic/UI/UIEvents.h>
|
|
|
#include <Atomic/UI/UIWidget.h>
|
|
|
+#include <Atomic/UI/UI.h>
|
|
|
#include "JSVM.h"
|
|
|
#include "JSUI.h"
|
|
|
|
|
|
+using namespace tb;
|
|
|
+
|
|
|
namespace Atomic
|
|
|
{
|
|
|
|
|
|
@@ -12,6 +15,7 @@ JSUI::JSUI(Context* context) : Object(context)
|
|
|
{
|
|
|
ctx_ = JSVM::GetJSVM(nullptr)->GetJSContext();
|
|
|
SubscribeToEvent(E_WIDGETEVENT, HANDLER(JSUI, HandleWidgetEvent));
|
|
|
+ SubscribeToEvent(E_WIDGETLOADED, HANDLER(JSUI, HandleWidgetLoaded));
|
|
|
}
|
|
|
|
|
|
JSUI::~JSUI()
|
|
|
@@ -19,6 +23,67 @@ JSUI::~JSUI()
|
|
|
|
|
|
}
|
|
|
|
|
|
+void JSUI::GatherWidgets(tb::TBWidget* widget, PODVector<tb::TBWidget*>& widgets)
|
|
|
+{
|
|
|
+ if (widget->GetID() != TBID())
|
|
|
+ widgets.Push(widget);
|
|
|
+
|
|
|
+ for (TBWidget *n = widget->GetFirstChild(); n; n = n->GetNext())
|
|
|
+ {
|
|
|
+ GatherWidgets(n, widgets);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void JSUI::HandleWidgetLoaded(StringHash eventType, VariantMap& eventData)
|
|
|
+{
|
|
|
+ using namespace WidgetLoaded;
|
|
|
+
|
|
|
+ UIWidget* widget = static_cast<UIWidget*>(eventData[P_WIDGET].GetPtr());
|
|
|
+ if (!widget)
|
|
|
+ return;
|
|
|
+
|
|
|
+ void* heapptr = widget->JSGetHeapPtr();
|
|
|
+
|
|
|
+ if (!heapptr)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // a loaded widget recursively gathers children which have id's and
|
|
|
+ // stashes them in an internal array, so that they don't go out of scope
|
|
|
+ // for instance var button = window.getWidgetByID("reveal");
|
|
|
+ // if we didn't stash, any callback on button wouldn't work if button went out
|
|
|
+ // of scope, which isn't expected behavior (in JS you would think the button is
|
|
|
+ // in some way attached to the window object)
|
|
|
+
|
|
|
+ TBWidget* tbwidget = widget->GetInternalWidget();
|
|
|
+ assert(tbwidget);
|
|
|
+
|
|
|
+ PODVector<TBWidget*> widgets;
|
|
|
+ GatherWidgets(tbwidget, widgets);
|
|
|
+
|
|
|
+ UI* ui = GetSubsystem<UI>();
|
|
|
+
|
|
|
+ duk_push_heapptr(ctx_, heapptr);
|
|
|
+ duk_push_array(ctx_);
|
|
|
+
|
|
|
+ unsigned arrayCount = 0;
|
|
|
+ for (unsigned i = 0; i < widgets.Size(); i++)
|
|
|
+ {
|
|
|
+ UIWidget* o = ui->WrapWidget(widgets.At(i));
|
|
|
+
|
|
|
+ if (!o)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ js_push_class_object_instance(ctx_, o);
|
|
|
+
|
|
|
+ duk_put_prop_index(ctx_, -2, arrayCount++);
|
|
|
+ }
|
|
|
+
|
|
|
+ duk_put_prop_string(ctx_, -2, "__child_widgets");
|
|
|
+ duk_pop(ctx_);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
void JSUI::HandleWidgetEvent(StringHash eventType, VariantMap& eventData)
|
|
|
{
|
|
|
using namespace WidgetEvent;
|