Ver código fonte

Working on New UI

Josh Engebretson 10 anos atrás
pai
commit
b56c24194f

+ 8 - 0
Source/Atomic/UI/UI.cpp

@@ -425,6 +425,14 @@ void UI::PruneUnreachableWidgets()
     }
 }
 
+void UI::WrapWidget(UIWidget* widget, tb::TBWidget* tbwidget)
+{
+    assert (!widgetWrap_.Contains(tbwidget));
+
+    widgetWrap_[tbwidget] = widget;
+
+}
+
 UIWidget* UI::WrapWidget(tb::TBWidget* widget)
 {
     if (widgetWrap_.Contains(widget))

+ 8 - 0
Source/Atomic/UI/UI.h

@@ -46,9 +46,17 @@ public:
     void SetDefaultFont(const String& name, int size);
 
     bool IsWidgetWrapped(tb::TBWidget* widget);
+
+    // wrap an existing widget we new'd from script
+    void WrapWidget(UIWidget* widget, tb::TBWidget* tbwidget);
+
+    // given a TB widget, creating a UIWidget
     UIWidget* WrapWidget(tb::TBWidget* widget);
+
     bool UnwrapWidget(tb::TBWidget* widget);
 
+    unsigned DebugGetWrappedWidgetCount() { return widgetWrap_.Size(); }
+
     void PruneUnreachableWidgets();
 
     void GetTBIDString(unsigned id, String& value);

+ 1 - 0
Source/Atomic/UI/UIButton.cpp

@@ -19,6 +19,7 @@ UIButton::UIButton(Context* context, bool createWidget) : UIWidget(context, fals
     {
         widget_ = new TBButton();
         widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
     }
 }
 

+ 2 - 0
Source/Atomic/UI/UIEditField.cpp

@@ -3,6 +3,7 @@
 #include <TurboBadger/tb_widgets_common.h>
 #include <TurboBadger/tb_editfield.h>
 
+#include "UI.h"
 #include "UIEvents.h"
 #include "UIEditField.h"
 
@@ -17,6 +18,7 @@ UIEditField::UIEditField(Context* context, bool createWidget) : UIWidget(context
     {
         widget_ = new TBEditField();
         widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
     }
 }
 

+ 4 - 0
Source/Atomic/UI/UIEvents.h

@@ -42,6 +42,10 @@ EVENT(E_WIDGETEVENT, WidgetEvent)
     PARAM(P_MODIFIERKEYS, ModifierKeys); // enum MODIFIER_KEYS
     PARAM(P_REFID, RefID);                     // unsigned (TBID)
     PARAM(P_TOUCH, Touch);               // bool
+
+    // EventHandled can be set by event receivers to stop event bubble
+    PARAM(P_HANDLED, Handled);               // [OUT] -> bool
+
 }
 
 EVENT(E_WIDGETLOADED, WidgetLoaded)

+ 2 - 0
Source/Atomic/UI/UIImageWidget.cpp

@@ -5,6 +5,7 @@
 
 #include <Atomic/IO/Log.h>
 
+#include "UI.h"
 #include "UIEvents.h"
 #include "UIWidget.h"
 #include "UIImageWidget.h"
@@ -20,6 +21,7 @@ UIImageWidget::UIImageWidget(Context* context, bool createWidget) : UIWidget(con
     {
         widget_ = new TBImageWidget();
         widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
     }
 }
 

+ 2 - 0
Source/Atomic/UI/UILayout.cpp

@@ -3,6 +3,7 @@
 #include <TurboBadger/tb_widgets_common.h>
 #include <TurboBadger/image/tb_image_widget.h>
 
+#include "UI.h"
 #include "UIEvents.h"
 #include "UIWidget.h"
 #include "UILayout.h"
@@ -18,6 +19,7 @@ UILayout::UILayout(Context* context, bool createWidget) : UIWidget(context, fals
     {
         widget_ = new TBLayout();
         widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
     }
 }
 

+ 4 - 1
Source/Atomic/UI/UIMenuWindow.cpp

@@ -3,6 +3,7 @@
 #include <TurboBadger/tb_widgets_common.h>
 #include <TurboBadger/tb_menu_window.h>
 
+#include "UI.h"
 #include "UIEvents.h"
 #include "UIWidget.h"
 #include "UISelectItem.h"
@@ -16,8 +17,10 @@ namespace Atomic
 UIMenuWindow::UIMenuWindow(Context* context, UIWidget* target, const String& id) : UIWidget(context, false)
   , source_(0)
 {
-    widget_ = new TBMenuWindow(target->GetInternalWidget(), TBID(id.CString()));
+    widget_ = new TBMenuWindow(target->GetInternalWidget(), TBID(id.CString()));    
     widget_->SetDelegate(this);
+    GetSubsystem<UI>()->WrapWidget(this, widget_);
+
 }
 
 UIMenuWindow::~UIMenuWindow()

+ 2 - 0
Source/Atomic/UI/UITextField.cpp

@@ -2,6 +2,7 @@
 #include <TurboBadger/tb_widgets.h>
 #include <TurboBadger/tb_widgets_common.h>
 
+#include "UI.h"
 #include "UIEvents.h"
 #include "UITextField.h"
 
@@ -16,6 +17,7 @@ UITextField::UITextField(Context* context, bool createWidget) : UIWidget(context
     {
         widget_ = new TBTextField();
         widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
     }
 }
 

+ 1 - 0
Source/Atomic/UI/UIView.cpp

@@ -13,6 +13,7 @@ UIView::UIView(Context* context) : UIWidget(context, false)
 {
     widget_ = new TBWidget();
     widget_->SetDelegate(this);
+    GetSubsystem<UI>()->WrapWidget(this, widget_);
 
     UI* ui = GetSubsystem<UI>();
 

+ 23 - 1
Source/Atomic/UI/UIWidget.cpp

@@ -21,7 +21,11 @@ UIWidget::UIWidget(Context* context, bool createWidget) : Object(context),
     {
         widget_ = new TBWidget();
         widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
     }
+
+    UI* ui = GetSubsystem<UI>();
+
 }
 
 UIWidget::~UIWidget()
@@ -162,7 +166,18 @@ UIWidget* UIWidget::GetParent()
 
 }
 
-void UIWidget::RemoveChild(UIWidget* child)
+void UIWidget::Destroy()
+{
+    if (!widget_)
+        return;
+
+    if (widget_->GetParent())
+        widget_->GetParent()->RemoveChild(widget_);
+
+    delete widget_;
+}
+
+void UIWidget::RemoveChild(UIWidget* child, bool cleanup)
 {
     if (!widget_ || !child)
         return;
@@ -173,6 +188,9 @@ void UIWidget::RemoveChild(UIWidget* child)
         return;
 
     widget_->RemoveChild(childw);
+
+    if (cleanup)
+        delete childw;
 }
 
 
@@ -223,6 +241,10 @@ bool UIWidget::OnEvent(const tb::TBWidgetEvent &ev)
                 VariantMap eventData;
                 ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
                 SendEvent(E_WIDGETEVENT, eventData);
+
+                if (eventData[WidgetEvent::P_HANDLED].GetBool())
+                    return true;
+
             }
         }
 

+ 4 - 2
Source/Atomic/UI/UIWidget.h

@@ -13,7 +13,7 @@ class TBWidget;
 namespace Atomic
 {
 
-/// Wraps a TurboBadger widget
+/// Wraps a TurboBadger widget in our Object model
 class UIWidget : public Object, public tb::TBWidgetDelegate
 {
     friend class UI;
@@ -33,13 +33,15 @@ public:
 
     UIWidget* GetParent();
 
-    void RemoveChild(UIWidget* child);
+    void RemoveChild(UIWidget* child, bool cleanup = true);
 
     // String ID
     const String& GetId();
 
     void Center();
 
+    void Destroy();
+
     // get this or child widget with id
     UIWidget* GetWidget(const String& id);
 

+ 2 - 0
Source/Atomic/UI/UIWindow.cpp

@@ -5,6 +5,7 @@
 
 #include "../IO/Log.h"
 
+#include "UI.h"
 #include "UIEvents.h"
 #include "UIWindow.h"
 
@@ -19,6 +20,7 @@ UIWindow::UIWindow(Context* context, bool createWidget) : UIWidget(context, fals
     {
         widget_ = new TBWindow();
         widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
     }
 }
 

+ 8 - 3
Source/AtomicJS/Javascript/JSUI.cpp

@@ -107,8 +107,7 @@ void JSUI::HandleWidgetDeleted(StringHash eventType, VariantMap& eventData)
     // string property, pointer will be string representation of
     // address, so, unique key
     duk_push_pointer(ctx_, widget);
-    duk_push_null(ctx_);
-    duk_put_prop(ctx_, -3);
+    duk_del_prop(ctx_, -2);
     duk_pop_2(ctx_);
 
 }
@@ -304,13 +303,15 @@ void JSUI::HandleWidgetEvent(StringHash eventType, VariantMap& eventData)
             PushWidgetEventObject(eventData);
 
             duk_call(ctx_, 1);
+
+            if (duk_is_boolean(ctx_, -1) && duk_to_boolean(ctx_, -1))
+                eventData[P_HANDLED] = true;
         }
         duk_pop_n(ctx_, 2);
         assert(top == duk_get_top(ctx_));
     }
 
     // specific event handlers
-
     if (type == tb::EVENT_TYPE_CLICK)
     {
         int top = duk_get_top(ctx_);
@@ -318,6 +319,10 @@ void JSUI::HandleWidgetEvent(StringHash eventType, VariantMap& eventData)
         duk_get_prop_string(ctx_, -1, "onClick");
         if (duk_is_callable(ctx_, -1)) {
             duk_call(ctx_, 0);
+
+            if (duk_is_boolean(ctx_, -1) && duk_to_boolean(ctx_, -1))
+                eventData[P_HANDLED] = true;
+
         }
         duk_pop_n(ctx_, 2);
         assert(top == duk_get_top(ctx_));

+ 47 - 0
Source/AtomicJS/Javascript/JSUIAPI.cpp

@@ -7,6 +7,7 @@
 #include "JSUIAPI.h"
 #include "JSVM.h"
 
+#include <Atomic/UI/UI.h>
 #include <Atomic/UI/UISelectItem.h>
 #include <Atomic/UI/UIMenuWindow.h>
 #include <Atomic/UI/UIButton.h>
@@ -99,11 +100,57 @@ int UIWindow_GetResizeToFitContentRect(duk_context* ctx)
 
 }
 
+int UI_DebugGetUIKeepAliveCount(duk_context* ctx)
+{
+    duk_push_global_stash(ctx);
+    duk_get_prop_string(ctx, -1, "__jsui_widgetkeepalive");
+
+    duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);
+
+    double count = 0;
+
+    while (duk_next(ctx, -1 , 0)) {
+
+        duk_pop(ctx);  /* pop_key */
+        count++;
+    }
+
+    duk_pop_n(ctx, 3);  /* pop enum object, keep alive object, and stash */
+
+    duk_push_number(ctx, count);
+
+    return 1;
+}
+
+int UI_DebugGetWrappedWidgetCount(duk_context* ctx)
+{
+    JSVM* vm = JSVM::GetJSVM(ctx);
+    UI* ui = vm->GetSubsystem<UI>();
+
+    duk_push_number(ctx, (double) ui->DebugGetWrappedWidgetCount());
+    return 1;
+}
 
 void jsapi_init_ui(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
 
+    // UI object
+    duk_get_global_string(ctx, "Atomic");
+
+    duk_push_object(ctx);
+
+    duk_push_c_function(ctx, UI_DebugGetWrappedWidgetCount, 0);
+    duk_put_prop_string(ctx, -2, "debugGetWrappedWidgetCount");
+
+    duk_push_c_function(ctx, UI_DebugGetUIKeepAliveCount, 0);
+    duk_put_prop_string(ctx, -2, "debugGetUIKeepAliveCount");
+
+    duk_put_prop_string(ctx, -2, "UI");
+
+
+    duk_pop(ctx);
+
     js_class_get_prototype(ctx, "UIButton");
     duk_push_c_function(ctx, UIButton_Popup, 2);
     duk_put_prop_string(ctx, -2, "popup");