Initial release
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
// This file is part of VSTGUI. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this
|
||||
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vstguifwd.h"
|
||||
#include "cview.h"
|
||||
#include "cdrawdefs.h"
|
||||
#if VSTGUI_TOUCH_EVENT_HANDLING
|
||||
#include "itouchevent.h"
|
||||
#endif
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace VSTGUI {
|
||||
|
||||
/** Message of a view loosing focus (only CTextEdit and COptionMenu send this) */
|
||||
extern IdStringPtr kMsgLooseFocus;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct GetViewOptions
|
||||
{
|
||||
enum {
|
||||
kNone = 0,
|
||||
kDeep = 1 << 0,
|
||||
kMouseEnabled = 1 << 1,
|
||||
kIncludeViewContainer = 1 << 2,
|
||||
kIncludeInvisible = 1 << 3
|
||||
};
|
||||
|
||||
explicit GetViewOptions (uint32_t options = kNone) : flags (options) {}
|
||||
|
||||
GetViewOptions& deep (bool state = true) { setBit (flags, kDeep, state); return *this; }
|
||||
GetViewOptions& mouseEnabled (bool state = true) { setBit (flags, kMouseEnabled, state); return *this; }
|
||||
GetViewOptions& includeViewContainer (bool state = true) { setBit (flags, kIncludeViewContainer, state); return *this; }
|
||||
GetViewOptions& includeInvisible (bool state = true) { setBit (flags, kIncludeInvisible, state); return *this; }
|
||||
|
||||
bool getDeep () const { return hasBit (flags, kDeep); }
|
||||
bool getMouseEnabled () const { return hasBit (flags, kMouseEnabled); }
|
||||
bool getIncludeViewContainer () const { return hasBit (flags, kIncludeViewContainer); }
|
||||
bool getIncludeInvisible () const { return hasBit (flags, kIncludeInvisible); }
|
||||
private:
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CViewContainer Declaration
|
||||
//! @brief Container Class of CView objects
|
||||
/// @ingroup containerviews
|
||||
//-----------------------------------------------------------------------------
|
||||
class CViewContainer : public CView
|
||||
{
|
||||
public:
|
||||
using ViewList = std::list<SharedPointer<CView>>;
|
||||
|
||||
explicit CViewContainer (const CRect& size);
|
||||
CViewContainer (const CViewContainer& viewContainer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// @name Sub View Methods
|
||||
//-----------------------------------------------------------------------------
|
||||
//@{
|
||||
/** add a child view */
|
||||
bool addView (CView* pView, const CRect& mouseableArea, bool mouseEnabled = true);
|
||||
/** add a child view before another view */
|
||||
virtual bool addView (CView* pView, CView* pBefore = nullptr);
|
||||
/** remove a child view */
|
||||
virtual bool removeView (CView* pView, bool withForget = true);
|
||||
/** remove all child views */
|
||||
virtual bool removeAll (bool withForget = true);
|
||||
/** check if pView is a child view of this container */
|
||||
bool isChild (CView* pView) const;
|
||||
/** check if pView is a child view of this container */
|
||||
virtual bool isChild (CView* pView, bool deep) const;
|
||||
/** check if container has child views */
|
||||
virtual bool hasChildren () const;
|
||||
/** get the number of child views */
|
||||
virtual uint32_t getNbViews () const;
|
||||
/** get the child view at index */
|
||||
virtual CView* getView (uint32_t index) const;
|
||||
/** get the view at point where */
|
||||
virtual CView* getViewAt (const CPoint& where, const GetViewOptions& options = GetViewOptions ()) const;
|
||||
/** get the container at point where */
|
||||
virtual CViewContainer* getContainerAt (const CPoint& where, const GetViewOptions& options = GetViewOptions ().deep ()) const;
|
||||
/** get all views at point where, top->down */
|
||||
virtual bool getViewsAt (const CPoint& where, ViewList& views, const GetViewOptions& options = GetViewOptions ().deep ()) const;
|
||||
/** change view z order position */
|
||||
virtual bool changeViewZOrder (CView* view, uint32_t newIndex);
|
||||
|
||||
virtual bool hitTestSubViews (const CPoint& where, const Event& event);
|
||||
|
||||
/** enable or disable autosizing subviews. Per default this is enabled. */
|
||||
virtual void setAutosizingEnabled (bool state);
|
||||
bool getAutosizingEnabled () const { return hasViewFlag (kAutosizeSubviews); }
|
||||
|
||||
/** get child views of type ViewClass. ContainerClass must be a stdc++ container */
|
||||
template<class ViewClass, class ContainerClass>
|
||||
uint32_t getChildViewsOfType (ContainerClass& result, bool deep = false) const;
|
||||
|
||||
/** execute proc for each child view */
|
||||
template<typename Proc>
|
||||
void forEachChild (Proc proc) const;
|
||||
|
||||
template<typename Proc>
|
||||
CView* findFirstViewIf (Proc filter) const;
|
||||
|
||||
//@}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// @name View Layouter Methods
|
||||
//-----------------------------------------------------------------------------
|
||||
//@{
|
||||
/** set a view layouter
|
||||
*
|
||||
* Per default the view container has an AutoSizeLayouter set.
|
||||
* Use this method to set a custom layouter.
|
||||
* To reset the layouter to the default AutoSizeLayouter use setViewLayouter (nullptr).
|
||||
*/
|
||||
void setViewLayouter (const SharedPointer<IViewLayouter>& layouter);
|
||||
/** get the current view layouter */
|
||||
SharedPointer<IViewLayouter> getViewLayouter () const;
|
||||
/** calculate the view layout for the new size */
|
||||
std::optional<ViewLayout> calculateViewLayout (const CRect& newSize) const;
|
||||
/** apply a previously calculated view layout */
|
||||
bool applyViewLayout (const ViewLayout& layout);
|
||||
/** check if a view layout is currently applied */
|
||||
bool inApplyViewLayout () const;
|
||||
//@}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// @name Background Methods
|
||||
//-----------------------------------------------------------------------------
|
||||
//@{
|
||||
/** set the background color (will only be drawn if this container is not set to transparent and does not have a background bitmap) */
|
||||
virtual void setBackgroundColor (const CColor& color);
|
||||
/** get the background color */
|
||||
virtual CColor getBackgroundColor () const;
|
||||
/** set the offset of the background bitmap */
|
||||
virtual void setBackgroundOffset (const CPoint& p);
|
||||
/** get the offset of the background bitmap */
|
||||
virtual CPoint getBackgroundOffset () const;
|
||||
/** draw the background */
|
||||
virtual void drawBackgroundRect (CDrawContext* pContext, const CRect& _updateRect);
|
||||
|
||||
virtual void setBackgroundColorDrawStyle (CDrawStyle style);
|
||||
CDrawStyle getBackgroundColorDrawStyle () const;
|
||||
//@}
|
||||
|
||||
/** set custom initial focus view
|
||||
* which is first focused when advanceNextFocusView is called without oldFocus view
|
||||
*/
|
||||
void setInitialFocusView (CView* view);
|
||||
/** get custom initial focus view */
|
||||
CView* getInitialFocusView () const;
|
||||
|
||||
virtual bool advanceNextFocusView (CView* oldFocus, bool reverse = false);
|
||||
virtual bool invalidateDirtyViews ();
|
||||
virtual CRect getVisibleSize (const CRect& rect) const;
|
||||
|
||||
void setTransform (const CGraphicsTransform& t);
|
||||
const CGraphicsTransform& getTransform () const;
|
||||
|
||||
void registerViewContainerListener (IViewContainerListener* listener);
|
||||
void unregisterViewContainerListener (IViewContainerListener* listener);
|
||||
|
||||
// CView
|
||||
void draw (CDrawContext* pContext) override;
|
||||
void drawRect (CDrawContext* pContext, const CRect& updateRect) override;
|
||||
void onMouseDownEvent (MouseDownEvent& event) override;
|
||||
void onMouseMoveEvent (MouseMoveEvent& event) override;
|
||||
void onMouseUpEvent (MouseUpEvent& event) override;
|
||||
void onMouseCancelEvent (MouseCancelEvent& event) override;
|
||||
void onMouseWheelEvent (MouseWheelEvent& event) override;
|
||||
void onZoomGestureEvent (ZoomGestureEvent& event) override;
|
||||
CMessageResult notify (CBaseObject* sender, IdStringPtr message) override;
|
||||
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
bool onWheel (const CPoint& where, const CMouseWheelAxis& axis, const float& distance,
|
||||
const CButtonState& buttons) final;
|
||||
#endif
|
||||
#if VSTGUI_TOUCH_EVENT_HANDLING
|
||||
virtual void onTouchEvent (ITouchEvent& event) override;
|
||||
virtual bool wantsMultiTouchEvents () const override { return true; }
|
||||
virtual bool findSingleTouchEventTarget (ITouchEvent::Touch& event);
|
||||
#endif
|
||||
|
||||
SharedPointer<IDropTarget> getDropTarget () override;
|
||||
|
||||
void looseFocus () override;
|
||||
void takeFocus () override;
|
||||
|
||||
bool isDirty () const override;
|
||||
|
||||
void invalid () override;
|
||||
void invalidRect (const CRect& rect) override;
|
||||
|
||||
void setViewSize (const CRect& rect, bool invalid = true) override;
|
||||
void parentSizeChanged () override;
|
||||
bool sizeToFit () override;
|
||||
|
||||
bool removed (CView* parent) override;
|
||||
bool attached (CView* parent) override;
|
||||
|
||||
CPoint& frameToLocal (CPoint& point) const override;
|
||||
CPoint& localToFrame (CPoint& point) const override;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
using ChildViewConstIterator = ViewList::const_iterator;
|
||||
using ChildViewConstReverseIterator = ViewList::const_reverse_iterator;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<bool reverse>
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
using IteratorType = typename std::conditional<reverse, ChildViewConstReverseIterator,
|
||||
ChildViewConstIterator>::type;
|
||||
|
||||
explicit Iterator (const CViewContainer* container) : children (container->getChildren ())
|
||||
{
|
||||
if constexpr (reverse)
|
||||
iterator = children.rbegin ();
|
||||
else
|
||||
iterator = children.begin ();
|
||||
}
|
||||
|
||||
explicit Iterator (const Iterator<reverse>& vi)
|
||||
: children (vi.children), iterator (vi.iterator)
|
||||
{
|
||||
}
|
||||
|
||||
Iterator (Iterator<reverse>&& o) : children (o.children), iterator (std::move (o.iterator))
|
||||
{
|
||||
}
|
||||
|
||||
Iterator<reverse>& operator++ ()
|
||||
{
|
||||
++iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator<reverse> operator++ (int)
|
||||
{
|
||||
Iterator<reverse> old (*this);
|
||||
++iterator;
|
||||
return old;
|
||||
}
|
||||
|
||||
Iterator<reverse>& operator-- ()
|
||||
{
|
||||
--iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CView* operator* () const
|
||||
{
|
||||
if constexpr (reverse)
|
||||
return (iterator == children.rend ()) ? nullptr : *iterator;
|
||||
else
|
||||
return (iterator == children.end ()) ? nullptr : *iterator;
|
||||
}
|
||||
|
||||
protected:
|
||||
const ViewList& children;
|
||||
IteratorType iterator;
|
||||
};
|
||||
|
||||
//-------------------------------------------
|
||||
CLASS_METHODS(CViewContainer, CView)
|
||||
|
||||
#if DEBUG
|
||||
void dumpInfo () override;
|
||||
virtual void dumpHierarchy ();
|
||||
#endif
|
||||
|
||||
CViewContainer* asViewContainer () final { return this; }
|
||||
const CViewContainer* asViewContainer () const final { return this; }
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
kAutosizeSubviews = 1 << (CView::kLastCViewFlag + 1),
|
||||
kInApplyLayout = 1 << (CView::kLastCViewFlag + 2),
|
||||
};
|
||||
|
||||
~CViewContainer () noexcept override;
|
||||
void beforeDelete () override;
|
||||
|
||||
virtual bool checkUpdateRect (CView* view, const CRect& rect);
|
||||
|
||||
void setMouseDownView (CView* view);
|
||||
CView* getMouseDownView () const;
|
||||
|
||||
const ViewList& getChildren () const;
|
||||
private:
|
||||
static constexpr CViewAttributeID kInitialFocusViewAttribute = 'cifv';
|
||||
|
||||
void dispatchEventToSubViews (Event& event);
|
||||
|
||||
void clearMouseDownView ();
|
||||
CRect getLastDrawnFocus () const;
|
||||
void setLastDrawnFocus (CRect r);
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> pImpl;
|
||||
};
|
||||
|
||||
using ViewIterator = CViewContainer::Iterator<false>;
|
||||
using ReverseViewIterator = CViewContainer::Iterator<true>;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class ViewClass, class ContainerClass>
|
||||
inline uint32_t CViewContainer::getChildViewsOfType (ContainerClass& result, bool deep) const
|
||||
{
|
||||
for (auto& child : getChildren ())
|
||||
{
|
||||
auto vObj = child.cast<ViewClass> ();
|
||||
if (vObj)
|
||||
{
|
||||
result.push_back (vObj);
|
||||
}
|
||||
if (deep)
|
||||
{
|
||||
if (auto container = child->asViewContainer ())
|
||||
{
|
||||
container->getChildViewsOfType<ViewClass, ContainerClass> (result, deep);
|
||||
}
|
||||
}
|
||||
}
|
||||
return static_cast<uint32_t> (result.size ());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename Proc>
|
||||
inline void CViewContainer::forEachChild (Proc proc) const
|
||||
{
|
||||
for (auto& child : getChildren ())
|
||||
{
|
||||
proc (child);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Proc>
|
||||
inline CView* CViewContainer::findFirstViewIf (Proc filter) const
|
||||
{
|
||||
for (const auto& child : getChildren ())
|
||||
{
|
||||
if (filter (child))
|
||||
return child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // VSTGUI
|
||||
Reference in New Issue
Block a user