Browse Source

Merge pull request #1570 from JimMarlowe/JM-TB-PERCENT

add UIPulldownMenu widget
JoshEngebretson 8 years ago
parent
commit
f592f88569

+ 4 - 2
Script/Packages/Atomic/UI.json

@@ -10,7 +10,7 @@
 								"UISkinImage", "UITabContainer", "UISceneView", "UIPreferredSize", "UIDragObject",
 								"UIContainer", "UISection", "UIInlineSelect", "UITextureWidget", "UIColorWidget", "UIColorWheel",
 								"UIScrollContainer", "UISeparator", "UIDimmer", "UISelectDropdown", "UISlider", "UIBargraph",
-								"UIPromptWindow", "UIFinderWindow"],
+								"UIPromptWindow", "UIFinderWindow", "UIPulldownMenu"],
 	"overloads" : {
 	},
 	"typescript_decl" : {
@@ -22,7 +22,9 @@
 		    "getWidgetAt<T extends UIWidget>(x: number, y: number, include_children: boolean): T;"
 		],
 		"UIWidget": [
-		    "getWidget<T extends UIWidget>(id: string): T;"
+		    "getWidget<T extends UIWidget>(id: string): T;",
+		    "onEvent: (eventData:UIWidgetEvent) => void;",
+		    "onChanged: () => void;"
 		]
 	}
 

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

@@ -90,6 +90,7 @@ using namespace tb;
 #include "UIBargraph.h"
 #include "UIPromptWindow.h"
 #include "UIFinderWindow.h"
+#include "UIPulldownMenu.h"
 
 #include "SystemUI/SystemUI.h"
 #include "SystemUI/SystemUIEvents.h"
@@ -737,6 +738,14 @@ UIWidget* UI::WrapWidget(tb::TBWidget* widget)
         return select;
     }
 
+    if (widget->IsOfType<TBPulldownMenu>())
+    {
+        UIPulldownMenu* select = new UIPulldownMenu(context_, false);
+        select->SetWidget(widget);
+        WrapWidget(select, widget);
+        return select;
+    }
+
     if (widget->IsOfType<TBButton>())
     {
         // don't wrap the close button of a TBWindow.close

+ 84 - 0
Source/Atomic/UI/UIPulldownMenu.cpp

@@ -0,0 +1,84 @@
+//
+// Copyright (c) 2017, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <TurboBadger/tb_widgets.h>
+#include <TurboBadger/tb_widgets_common.h>
+#include <TurboBadger/tb_atomic_widgets.h>
+
+#include <Atomic/IO/Log.h>
+
+#include "UI.h"
+#include "UIEvents.h"
+#include "UIPulldownMenu.h"
+
+using namespace tb;
+
+namespace Atomic
+{
+
+UIPulldownMenu::UIPulldownMenu(Context* context, bool createWidget) : UIButton(context, false)
+{
+    if (createWidget)
+    {
+        widget_ = new TBPulldownMenu();
+        widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
+    }
+}
+
+UIPulldownMenu::~UIPulldownMenu()
+{
+
+}
+
+void UIPulldownMenu::SetSource(UISelectItemSource* source)
+{
+    if (!widget_)
+        return;
+
+    ((TBSelectDropdown*)widget_)->SetSource(source ? source->GetTBItemSource() : NULL);
+
+}
+
+const String& UIPulldownMenu::GetSelectedId()
+{
+    if (!widget_)
+    {
+        if (sid_.Length())
+            sid_.Clear();
+        return sid_;
+    }
+
+    UI* ui = GetSubsystem<UI>();
+    ui->GetTBIDString(((TBPulldownMenu*)widget_)->GetValueID(), sid_);
+
+    return sid_;
+
+}
+bool UIPulldownMenu::OnEvent(const tb::TBWidgetEvent &ev)
+{
+
+   return UIButton::OnEvent(ev);
+
+}
+
+}

+ 51 - 0
Source/Atomic/UI/UIPulldownMenu.h

@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2017, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "UISelectItem.h"
+#include "UIButton.h"
+
+namespace Atomic
+{
+
+class ATOMIC_API UIPulldownMenu : public UIButton
+{
+    ATOMIC_OBJECT(UIPulldownMenu, UIButton)
+
+public:
+
+    UIPulldownMenu(Context* context, bool createWidget = true);
+    virtual ~UIPulldownMenu();
+
+    void SetSource(UISelectItemSource* source); /// for programming the pulled down menu
+
+    const String& GetSelectedId(); /// return id of entry selected in menu
+
+protected:
+
+    virtual bool OnEvent(const tb::TBWidgetEvent &ev);
+    String sid_;  /// cached selected item tbid
+
+};
+
+}

+ 122 - 1
Source/ThirdParty/TurboBadger/tb_atomic_widgets.cpp

@@ -3,7 +3,7 @@
 // ==                     See tb_core.h for more information.                    ==
 // ================================================================================
 //
-// Copyright (c) 2016, THUNDERBEAST GAMES LLC All rights reserved
+// Copyright (c) 2016-2017, THUNDERBEAST GAMES LLC All rights reserved
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
@@ -31,6 +31,8 @@
 #include "tb_atomic_widgets.h"
 #include "tb_editfield.h"
 #include "tb_menu_window.h"
+#include "tb_select.h"
+
 #include <math.h>
 
 namespace tb {
@@ -638,5 +640,124 @@ TBWidget *TBFinderWindow::FindParentList( TBWidget *widget) // utility for deali
     return NULL;
 }
 
+// == TBPulldownMenu ==========================================
+
+TBPulldownMenu::TBPulldownMenu()
+    : m_value(-1)
+{
+    SetSource(&m_default_source);
+    SetSkinBg(TBIDC("TBSelectDropdown"), WIDGET_INVOKE_INFO_NO_CALLBACKS);
+}
+
+TBPulldownMenu::~TBPulldownMenu()
+{
+    SetSource(nullptr);
+    CloseWindow();
+}
+
+void TBPulldownMenu::OnSourceChanged()
+{
+    m_value = -1;
+    m_valueid = TBID();
+    if (m_source && m_source->GetNumItems())
+        SetValue(0);
+}
+
+void TBPulldownMenu::SetValue(int value)
+{
+    if (!m_source)
+        return;
+    m_value = value;
+    m_valueid = GetSelectedItemID();
+    InvokeModifiedEvent( m_valueid );
+}
+
+TBID TBPulldownMenu::GetSelectedItemID()
+{
+    if (m_source && m_value >= 0 && m_value < m_source->GetNumItems())
+        return m_source->GetItemID(m_value);
+    return TBID();
+}
+
+void TBPulldownMenu::InvokeModifiedEvent( TBID entryid )
+{
+    TBWidgetEvent ev( EVENT_TYPE_CHANGED);
+    // TBIDC does not register the TBID with the UI system, so do it this way
+    ev.target = this;      // who am I
+    ev.ref_id = entryid;   // id of whom we clicked
+    TBWidget::OnEvent(ev); // forward to delegate
+}
+
+void TBPulldownMenu::OpenWindow()
+{
+    if (!m_source || !m_source->GetNumItems() || m_window_pointer.Get())
+        return;
+
+    if (TBMenuWindow *window = new TBMenuWindow(this, TBIDC("TBPulldownMenu.menu")))
+    {
+        m_window_pointer.Set(window);
+        window->SetSkinBg(TBIDC("TBSelectDropdown.window"));
+        window->Show(m_source, TBPopupAlignment());
+    }
+}
+
+void TBPulldownMenu::CloseWindow()
+{
+    if (TBMenuWindow *window = GetMenuIfOpen())
+        window->Close();
+}
+
+TBMenuWindow *TBPulldownMenu::GetMenuIfOpen() const
+{
+    return TBSafeCast<TBMenuWindow>(m_window_pointer.Get());
+}
+
+bool TBPulldownMenu::OnEvent(const TBWidgetEvent &ev)
+{
+    if ( ev.target->IsOfType<TBButton>() && ev.type == EVENT_TYPE_CLICK)
+    {
+        // Open the menu, or set the value and close it if already open (this will
+        // happen when clicking by keyboard since that will call click on this button)
+        if (TBMenuWindow *menu_window = GetMenuIfOpen())
+        {
+            TBWidgetSafePointer tmp(this);
+            int value = menu_window->GetList()->GetValue();
+            menu_window->Die();
+            if (tmp.Get())
+                SetValue(value);
+        }
+        else
+            OpenWindow();
+        return true;
+    }
+    else if (ev.target->GetID() == TBIDC("TBPulldownMenu.menu") && ev.type == EVENT_TYPE_CLICK )
+    {
+        if (TBMenuWindow *menu_window = GetMenuIfOpen())
+            SetValue(menu_window->GetList()->GetValue());
+        return true;
+    }
+    else if (ev.target == this && m_source && ev.IsKeyEvent())
+    {
+        if (TBMenuWindow *menu_window = GetMenuIfOpen())
+        {
+            // Redirect the key strokes to the list
+            TBWidgetEvent redirected_ev(ev);
+            return menu_window->GetList()->InvokeEvent(redirected_ev);
+        }
+    }
+    return false;
+}
+
+TB_WIDGET_FACTORY( TBPulldownMenu, TBValue::TYPE_INT, WIDGET_Z_TOP) {}
+
+extern void ReadItems(TBNode *node, TBGenericStringItemSource *target_source);  // blind function that lives in tb_widgets_reader.cpp
+
+void TBPulldownMenu::OnInflate(const INFLATE_INFO &info)
+{
+    // Read items (if there is any) into the default source
+    ReadItems(info.node, GetDefaultSource());
+    TBWidget::OnInflate(info);
+}
+
 
 }; // namespace tb

+ 61 - 1
Source/ThirdParty/TurboBadger/tb_atomic_widgets.h

@@ -3,7 +3,7 @@
 // ==                     See tb_core.h for more information.                    ==
 // ================================================================================
 //
-// Copyright (c) 2016, THUNDERBEAST GAMES LLC All rights reserved
+// Copyright (c) 2016-2017, THUNDERBEAST GAMES LLC All rights reserved
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
@@ -32,6 +32,9 @@
 #include "tb_widgets_listener.h"
 #include "tb_widgets_common.h"
 #include "tb_window.h"
+#include "tb_scroll_container.h"
+#include "tb_select_item.h"
+#include "tb_menu_window.h"
 
 #define UIPROMPTMESSAGEID 1
 #define UIPROMPTEDITID 2
@@ -202,6 +205,63 @@ private:
 };
 
 
+/** TBSelectDropdown shows a button that opens a popup with a TBSelectList with items
+    provided by a TBSelectItemSource. */
+
+class TBPulldownMenu : public TBButton, public TBSelectItemViewer
+{
+public:
+    // For safe typecasting
+    TBOBJECT_SUBCLASS(TBPulldownMenu, TBButton);
+
+    TBPulldownMenu();
+    ~TBPulldownMenu();
+
+    /** Get the default item source for this widget. This source can be used to add
+        items of type TBGenericStringItem to this widget. */
+    TBGenericStringItemSource *GetDefaultSource() { return &m_default_source; }
+
+    /** Save the selected item. Transfers value from menu to button parent */
+    virtual void SetValue(int value);
+    virtual int GetValue() { return m_value; }
+
+    /** Save the selected item TBID. Transfers value from menu to button parent */
+    void SetValueID(TBID value) { m_valueid = value; }
+    TBID GetValueID() { return m_valueid; }
+
+    /** Get the ID of the selected item, or 0 if there is no item selected. */
+    TBID GetSelectedItemID();
+
+    /** Open the window if the model has items. */
+    void OpenWindow();
+
+    /** Close the window if it is open. */
+    void CloseWindow();
+
+    /** Return the menu window if it's open, or nullptr. */
+    TBMenuWindow *GetMenuIfOpen() const;
+
+    virtual void OnInflate(const INFLATE_INFO &info);
+    virtual bool OnEvent(const TBWidgetEvent &ev);
+
+    // TBSelectItemViewer 
+    virtual void OnSourceChanged();
+    virtual void OnItemChanged(int index) {}
+    virtual void OnItemAdded(int index) {}
+    virtual void OnItemRemoved(int index) {}
+    virtual void OnAllItemsRemoved() {}
+    
+    virtual bool OnWidgetInvokeEvent(TBWidget *widget, const TBWidgetEvent &ev) { return false; } 
+
+protected:
+
+    void InvokeModifiedEvent(TBID entryid);
+
+    TBGenericStringItemSource m_default_source;
+    TBWidgetSafePointer m_window_pointer; ///< Points to the dropdown window if opened
+    int m_value; /// which list item has been selected
+    TBID m_valueid; /// the TBID of the list item that was selected
+};