| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #pragma once
- #include "BsEditorPrerequisites.h"
- #include "GUI/BsGUIElementContainer.h"
- #include "Input/BsVirtualInput.h"
- #include "Utility/BsEvent.h"
- namespace bs
- {
- /** @addtogroup GUI-Editor-Internal
- * @{
- */
- /**
- * GUI element that displays some contents in a tree-view where elements are placed vertically above/beneath each other,
- * and different elements may be nested within other elements.
- *
- * Elements may be selected, renamed, dragged and re-parented.
- *
- * This class is abstract and meant to be extended by an implementation specific to some content type (for example scene
- * object hierarchy).
- */
- class BS_ED_EXPORT GUITreeView : public GUIElementContainer
- {
- protected:
- /** Types of possible states when the tree view is auto-scrolling. */
- enum class ScrollState
- {
- None,
- Up,
- Down,
- TransitioningUp,
- TransitioningDown
- };
- /**
- * Contains data about a single piece of content and all its children. This element may be visible and represented
- * by a GUI element, but might not (for example its parent is collapsed).
- */
- struct TreeElement
- {
- TreeElement();
- virtual ~TreeElement();
- TreeElement* mParent;
- Vector<TreeElement*> mChildren;
- GUIToggle* mFoldoutBtn;
- GUILabel* mElement;
- String mName;
- UINT32 mSortedIdx;
- bool mIsExpanded;
- bool mIsSelected;
- bool mIsHighlighted;
- bool mIsVisible;
- bool mIsCut;
- bool mIsDisabled;
- Color mTint;
- bool isParentRec(TreeElement* element) const;
- };
- /**
- * Contains data about all visible elements in the tree view. This might be a TreeElement entry, or a separator
- * (empty space) between two TreeElement%s.
- */
- struct InteractableElement
- {
- InteractableElement(TreeElement* parent, UINT32 index, const Rect2I& bounds)
- :parent(parent), index(index), bounds(bounds)
- { }
- bool isTreeElement() const { return index % 2 == 1; }
- TreeElement* getTreeElement() const;
- TreeElement* parent;
- UINT32 index;
- Rect2I bounds;
- };
- /** Contains data about one of the currently selected tree elements. */
- struct SelectedElement
- {
- SelectedElement()
- :element(nullptr), background(nullptr)
- { }
- SelectedElement(TreeElement* elem, GUITexture* back)
- :element(elem), background(back)
- { }
- TreeElement* element;
- GUITexture* background;
- };
- public:
- /** Returns type name of the GUI element used for finding GUI element styles. */
- static const String& getGUITypeName();
- /** Deletes all currently selected elements. */
- void deleteSelection();
- /** Duplicates the currently selected entries. */
- virtual void duplicateSelection() { }
- /** Marks the current selection for copying. */
- virtual void copySelection() { }
-
- /** Marks the current selection for cutting. */
- virtual void cutSelection() { }
- /** Pastes a set of entries previously marked for cut or copy. */
- virtual void paste() { }
- /** Starts rename operation on the currently selected element. */
- void renameSelected();
- /** @name Internal
- * @{
- */
- /** Updates tree view if dirty, among other operations. Must be called every frame. */
- void _update();
- /** @} */
- protected:
- GUITreeView(const String& backgroundStyle, const String& elementBtnStyle,
- const String& foldoutBtnStyle, const String& highlightBackgroundStyle, const String& selectionBackgroundStyle, const String& editBoxStyle,
- const String& dragHighlightStyle, const String& dragSepHighlightStyle, const GUIDimensions& dimensions);
- virtual ~GUITreeView();
- /** @copydoc GUIElement::_getOptimalSize */
- Vector2I _getOptimalSize() const override;
- /** @copydoc GUIElement::updateClippedBounds */
- void updateClippedBounds() override;
- /** @copydoc GUIElement::_updateLayoutInternal */
- void _updateLayoutInternal(const GUILayoutData& data) override;
- /** @copydoc GUIElement::_mouseEvent */
- bool _mouseEvent(const GUIMouseEvent& ev) override;
- /** @copydoc GUIElement::_commandEvent */
- bool _commandEvent(const GUICommandEvent& ev) override;
- /**
- * Attempts to find an interactable element under the specified coordinates. Returns null if one cannot be found.
- *
- * @param[in] coord Coordinates relative to parent GUI widget.
- */
- const InteractableElement* findElementUnderCoord(const Vector2I& coord) const;
- /** Returns the top-most selected tree element if selection is active, null otherwise. */
- TreeElement* getTopMostSelectedElement() const;
- /** Returns the bottom-most selected tree element if selection is active, null otherwise. */
- TreeElement* getBottomMostSelectedElement() const;
- /** Starts rename operation on the specified tree element, spawning an input box. */
- void enableEdit(TreeElement* element);
- /**
- * Ends rename operation if one is currently active.
- *
- * @param[in] acceptChanges Should the new name be accepted or discarded.
- */
- void disableEdit(bool acceptChanges);
- /**
- * Triggered when the Foldout button for a tree element was been toggled (something was expanded or collapsed).
- */
- void elementToggled(TreeElement* element, bool toggled);
- /** Returns the top level TreeElement. */
- virtual TreeElement& getRootElement() = 0;
- /** Returns the top level TreeElement that cannot be modified. */
- virtual const TreeElement& getRootElementConst() const = 0;
- /** Checks if the hierarchy needs any updates and performs those updates if needed. */
- virtual void updateTreeElementHierarchy() = 0;
- /** Changes the name of the content associated with the provided tree element. */
- virtual void renameTreeElement(TreeElement* element, const String& name) = 0;
- /** Deletes the content associated with the provided tree element. */
- virtual void deleteTreeElement(TreeElement* element) = 0;
- /** Checks whether the tree view can accept the currently active drag and drop operation. */
- virtual bool acceptDragAndDrop() const = 0;
- /** Triggered when the user drags a tree element and starts a drag and drop operation. */
- virtual void dragAndDropStart(const Vector<TreeElement*>& elements) = 0;
- /**
- * Triggered when the user ends a drag and drop operation over the tree view.
- *
- * @param[in] overTreeElement TreeElement the drag operation ended over, if any.
- */
- virtual void dragAndDropEnded(TreeElement* overTreeElement) = 0;
- /** Triggered whenever a TreeElement gets selected or deselected. */
- virtual void selectionChanged() { }
- /** Are any tree elements currently selected. */
- bool isSelectionActive() const;
- /** Expands the selection to the provided TreeElement. Doesn't clear previous selection. */
- void selectElement(TreeElement* element, bool triggerEvents = true);
- /** Unselects the provided TreeElement. */
- void unselectElement(TreeElement* element, bool triggerEvents = true);
- /**
- * Unselects all selected TreeElement%s.
- *
- * @param[in] sendEvent Determines should the external world be notified of this change.
- */
- void unselectAll(bool sendEvent = true);
- /** Expands all parents of the provided TreeElement making it interactable. */
- void expandToElement(TreeElement* element);
- /**
- * Expands the provided TreeElement making its children interactable. Set @p toggleButton to true to change
- * the toggle state on the toggle button itself. Set this to false if called from the toggle button callback.
- */
- void expandElement(TreeElement* element, bool toggleButton = true);
- /**
- * Collapses the provided TreeElement making its children hidden and not interactable. Set @p toggleButton to true
- * to change the toggle state on the toggle button itself. Set this to false if called from the toggle button
- * callback.
- */
- void collapseElement(TreeElement* element, bool toggleButton = true);
- /** Rebuilds the needed GUI elements for the provided TreeElement. */
- void updateElementGUI(TreeElement* element);
- /** Close any elements that were temporarily expanded due to a drag operation hovering over them. */
- void closeTemporarilyExpandedElements();
- /**
- * Temporarily expand the provided element. Temporarily expanded elements can be closed by calling
- * closeTemporarilyExpandedElements().
- */
- void temporarilyExpandElement(const GUITreeView::InteractableElement* mouseOverElement);
- /**
- * Scrolls the parent GUIScrollArea (if any) so that the specified TreeElement is visible.
- *
- * @param[in] element Element to scroll to.
- * @param[in] center If true the element will be centered in the scroll view, otherwise it will be at the top.
- */
- void scrollToElement(TreeElement* element, bool center);
- /** Attempts to find the parent GUIScrollArea that the tree view is a child of. */
- GUIScrollArea* findParentScrollArea() const;
- /** Scrolls the tree view to the specified element and highlights it. */
- void ping(TreeElement* element);
- /** Clears the ping highlight on the currently highlighted element. */
- void clearPing();
- /** Triggered when the user accepts the changes during a rename operation. */
- void onEditAccepted();
- /** Triggered when the user rejects the changes during a rename operation. */
- void onEditCanceled();
- /** Triggered when the user clicks outside of the edit box during a rename operation. */
- void onEditFocusLost();
- String mBackgroundStyle;
- String mElementBtnStyle;
- String mFoldoutBtnStyle;
- String mSelectionBackgroundStyle;
- String mHighlightBackgroundStyle;
- String mEditBoxStyle;
- String mDragHighlightStyle;
- String mDragSepHighlightStyle;
- GUITexture* mBackgroundImage;
- Vector<InteractableElement> mVisibleElements;
- bool mIsElementSelected;
- Vector<SelectedElement> mSelectedElements;
- bool mIsElementHighlighted;
- SelectedElement mHighlightedElement;
- TreeElement* mEditElement;
- GUITreeViewEditBox* mNameEditBox;
- Vector2I mDragStartPosition;
- Vector2I mDragPosition;
- bool mDragInProgress;
- GUITexture* mDragHighlight;
- GUITexture* mDragSepHighlight;
- Rect2I mTopScrollBounds;
- Rect2I mBottomScrollBounds;
- ScrollState mScrollState;
- float mLastScrollTime;
- Stack<TreeElement*> mAutoExpandedElements;
- TreeElement* mMouseOverDragElement;
- float mMouseOverDragElementTime;
- static const UINT32 ELEMENT_EXTRA_SPACING;
- static const UINT32 INDENT_SIZE;
- static const UINT32 INITIAL_INDENT_OFFSET;
- static const UINT32 DRAG_MIN_DISTANCE;
- static const float AUTO_EXPAND_DELAY_SEC;
- static const float SCROLL_AREA_HEIGHT_PCT;
- static const UINT32 SCROLL_SPEED_PX_PER_SEC;
- static const Color CUT_COLOR;
- static const Color DISABLED_COLOR;
- };
- /** @} */
- }
|