ソースを参照

UIInlineSelect (smart) undo/redo

Josh Engebretson 10 年 前
コミット
482eca9386

+ 17 - 3
Script/AtomicEditor/ui/frames/inspector/DataBinding.ts

@@ -27,6 +27,7 @@ class DataBinding {
         fd.size = 11;
 
         var editFields: Array<Atomic.UIEditField> = [];
+        var inlineSelects: Array<Atomic.UIInlineSelect> = [];
 
         var enumSource = null;
 
@@ -108,6 +109,7 @@ class DataBinding {
 
             for (var i: any = 0; i < 3; i++) {
                 var select = new Atomic.UIInlineSelect();
+                inlineSelects.push(select);
                 select.id = String(i + 1);
                 select.fontDescription = fd;
                 select.skinBg = "InspectorVectorAttrName";
@@ -130,6 +132,7 @@ class DataBinding {
             for (var i: any = 0; i < 4; i++) {
 
                 var select = new Atomic.UIInlineSelect();
+                inlineSelects.push(select);
                 select.id = String(i + 1);
                 select.fontDescription = fd;
                 select.setLimits(-10000000, 10000000);
@@ -147,6 +150,7 @@ class DataBinding {
 
             for (var i: any = 0; i < 2; i++) {
                 var select = new Atomic.UIInlineSelect();
+                inlineSelects.push(select);
                 select.id = String(i + 1);
                 select.fontDescription = fd;
                 select.skinBg = "InspectorVectorAttrName";
@@ -255,7 +259,10 @@ class DataBinding {
             binding.enumSource = enumSource;
 
             for (var i in editFields) {
-                binding.subscribeToFocusChange(field);
+                editFields[i].subscribeToEvent(editFields[i], "UIWidgetFocusChanged", (ev) => binding.handleUIWidgetFocusChangedEvent(ev));
+            }
+            for (var i in inlineSelects) {
+                inlineSelects[i].subscribeToEvent(inlineSelects[i], "UIWidgetEditComplete", (ev) => binding.handleUIWidgetEditCompleteEvent(ev));
             }
 
             return binding;
@@ -453,12 +460,19 @@ class DataBinding {
 
     }
 
-    subscribeToFocusChange(widget: Atomic.UIWidget) {
+    handleUIWidgetEditCompleteEvent(ev) {
+
+      // TODO: once new base class stuff is in, should be able to check for type
+      var scene = this.object["scene"];
+
+      if (!scene)
+          return;
 
-        widget.subscribeToEvent(widget, "UIWidgetFocusChanged", (ev) => this.handleUIWidgetFocusChangedEvent(ev));
+      scene.sendEvent("SceneEditSerializable", { serializable: this.object, operation: 1 });
 
     }
 
+    // event for text field edits
     handleUIWidgetFocusChangedEvent(ev: Atomic.UIWidgetFocusChangedEvent) {
 
         // TODO: once new base class stuff is in, should be able to check for type

+ 6 - 1
Source/Atomic/UI/UI.cpp

@@ -825,10 +825,15 @@ SystemUI::MessageBox* UI::ShowSystemMessageBox(const String& title, const String
 
 }
 
-
 UIWidget* UI::GetWidgetAt(int x, int y, bool include_children)
 {
     return WrapWidget(rootWidget_->GetWidgetAt(x, y, include_children));
 }
 
+bool UI::OnWidgetInvokeEvent(tb::TBWidget *widget, const tb::TBWidgetEvent &ev)
+{
+    return false;
+}
+
+
 }

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

@@ -121,6 +121,7 @@ private:
     void OnWidgetDelete(tb::TBWidget *widget);
     bool OnWidgetDying(tb::TBWidget *widget);    
     void OnWidgetFocusChanged(tb::TBWidget *widget, bool focused);
+    bool OnWidgetInvokeEvent(tb::TBWidget *widget, const tb::TBWidgetEvent &ev);
 
 
     tb::TBWidget* rootWidget_;

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

@@ -112,6 +112,10 @@ EVENT(E_UIWIDGETFOCUSESCAPED, UIWidgetFocusEscaped)
 {
 }
 
+EVENT(E_UIWIDGETEDITCOMPLETE, UIWidgetEditComplete)
+{
+}
+
 EVENT(E_UIUNHANDLEDSHORTCUT, UIUnhandledShortcut)
 {
     PARAM(P_REFID, RefID); // string tbid

+ 5 - 0
Source/Atomic/UI/UIInlineSelect.cpp

@@ -70,6 +70,11 @@ void UIInlineSelect::SetLimits(double minimum, double maximum)
 
 bool UIInlineSelect::OnEvent(const tb::TBWidgetEvent &ev)
 {
+    if (ev.type == EVENT_TYPE_CUSTOM && ev.ref_id == TBIDC("TBInlineSelectModified"))
+    {
+        SendEvent(E_UIWIDGETEDITCOMPLETE);
+        return true;
+    }
     return UIWidget::OnEvent(ev);
 }
 

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

@@ -39,7 +39,8 @@ namespace Atomic
 
 UIWidget::UIWidget(Context* context, bool createWidget) : Object(context),
     widget_(0),
-    preferredSize_(new UIPreferredSize())
+    preferredSize_(new UIPreferredSize()),
+    multiTouch_(false)
 {
     AddRef();
 
@@ -738,6 +739,24 @@ bool UIWidget::OnEvent(const tb::TBWidgetEvent &ev)
     return false;
 }
 
+bool UIWidget::GetCaptured()
+{
+    if (!widget_)
+        return false;
+
+    return widget_->IsCaptured();
+
+}
+
+void UIWidget::SetCapturing(bool capturing)
+{
+    if (!widget_)
+        return;
+
+    widget_->SetCapturing(capturing);
+}
+
+
 void UIWidget::InvalidateLayout()
 {
     if (!widget_)

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

@@ -247,8 +247,9 @@ class UIWidget : public Object, public tb::TBWidgetDelegate
 
     bool IsMultiTouch() { return multiTouch_; }
 
-    void SetCapturing(bool capturing) { widget_->SetCapturing(capturing); }
+    bool GetCaptured();
 
+    void SetCapturing(bool capturing);
     bool GetCapturing() { return widget_->GetCapturing(); }
 
     void InvokeShortcut(const String& shortcut);
@@ -269,7 +270,6 @@ protected:
 
     SharedPtr<UIDragObject> dragObject_;
 
-
     bool multiTouch_;
 
 };

+ 57 - 3
Source/ThirdParty/TurboBadger/tb_inline_select.cpp

@@ -18,7 +18,8 @@ namespace tb {
 TBInlineSelect::TBInlineSelect()
 	: m_value(0)
 	, m_min(0)
-	, m_max(100)
+    , m_max(100)
+    , m_modified(false)
 {
 	SetSkinBg(TBIDC("TBInlineSelect"));
 	AddChild(&m_layout);
@@ -41,10 +42,15 @@ TBInlineSelect::TBInlineSelect()
 	m_editfield.SetTextAlign(TB_TEXT_ALIGN_CENTER);
 	m_editfield.SetEditType(EDIT_TYPE_NUMBER);
 	m_editfield.SetText("0");
+
+    m_editfield.AddListener(this);
+
 }
 
 TBInlineSelect::~TBInlineSelect()
 {
+    m_editfield.RemoveListener(this);
+
 	m_layout.RemoveChild(&m_buttons[1]);
 	m_layout.RemoveChild(&m_editfield);
 	m_layout.RemoveChild(&m_buttons[0]);
@@ -87,8 +93,8 @@ void TBInlineSelect::SetValueInternal(double value, bool update_text)
 		m_editfield.SetText(strval);
 	}
 
-	TBWidgetEvent ev(EVENT_TYPE_CHANGED);
-	InvokeEvent(ev);
+    TBWidgetEvent ev(EVENT_TYPE_CHANGED);
+    InvokeEvent(ev);
 
 	// Warning: Do nothing here since the event might have deleted us.
 	//          If needed, check if we are alive using a safe pointer first.
@@ -126,7 +132,55 @@ bool TBInlineSelect::OnEvent(const TBWidgetEvent &ev)
 		m_editfield.GetText(text);
         SetValueInternal((double) atof(text), false);
 	}
+
+    // catch mouse up/mouse down on buttons for modifications
+    if (ev.target == &m_buttons[0] || ev.target == &m_buttons[1])
+    {
+        if (ev.type == EVENT_TYPE_POINTER_DOWN)
+        {
+            m_modified = true;
+        }
+        else if (ev.type == EVENT_TYPE_POINTER_UP)
+        {
+            if (m_modified)
+                InvokeModifiedEvent();
+        }
+    }
+
 	return false;
 }
 
+void TBInlineSelect::InvokeModifiedEvent()
+{
+    TBWidgetEvent ev(EVENT_TYPE_CUSTOM);
+    ev.ref_id = TBIDC("TBInlineSelectModified");
+    // forward to delegate
+    TBWidget::OnEvent(ev);
+    m_modified = false;
+    m_editfield.GetText(m_initial_edit_value);
+}
+
+bool TBInlineSelect::OnWidgetInvokeEvent(TBWidget *widget, const TBWidgetEvent &ev)
+{
+    return false;
+}
+
+void TBInlineSelect::OnWidgetFocusChanged(TBWidget *widget, bool focused)
+{
+    if (widget == &m_editfield)
+    {
+        if (focused)
+            m_editfield.GetText(m_initial_edit_value);
+        else
+        {
+            TBStr editvalue;
+            m_editfield.GetText(editvalue);
+            if (m_modified || !editvalue.Equals(m_initial_edit_value.CStr()))
+            {
+                InvokeModifiedEvent();
+            }
+        }
+    }
+}
+
 }; // namespace tb

+ 10 - 1
Source/ThirdParty/TurboBadger/tb_inline_select.h

@@ -19,7 +19,7 @@ namespace tb {
 	FIX: Should also be possible to set a list of strings that will be
 		shown instead of numbers.
 */
-class TBInlineSelect : public TBWidget
+class TBInlineSelect : public TBWidget, private TBWidgetListener
 {
 public:
 	// For safe typecasting
@@ -53,8 +53,17 @@ protected:
 	TBEditField m_editfield;
     double m_value;
     double m_min, m_max;
+    bool m_modified;
 
     void SetValueInternal(double value, bool update_text);
+
+private:
+
+    TBStr m_initial_edit_value;
+
+    void InvokeModifiedEvent();
+    void OnWidgetFocusChanged(TBWidget *widget, bool focused);
+    bool OnWidgetInvokeEvent(TBWidget *widget, const TBWidgetEvent &ev);
 };
 
 }; // namespace tb