Skip to content

Commit e221eb1

Browse files
committed
[SUTK] Created a separate ScrollableContainer<> template class, and derive MaskedScrollableContainer class from that one.
- This refactoring increases testability of Scroll container and Scrollable container using only ScrollableContainer class.
1 parent 5769f90 commit e221eb1

File tree

2 files changed

+47
-28
lines changed

2 files changed

+47
-28
lines changed

sutk/include/sutk/MaskedScrollableContainer.hpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#pragma once
22

33
#include <sutk/defines.hpp>
4-
#include <sutk/Scrollable.hpp> // for SUTK::Scrollable
54
#include <sutk/ScrollContainer.hpp> // for SUTK::ScrollContainer
5+
#include <sutk/ScrollableContainer.hpp> // for SUTK::ScrollableContainer<>
66
#include <sutk/Renderable.hpp> // for SUTK::GfxDriverRenderable
77
#include <sutk/ContainerUtility.hpp> // for SUTK::ContainerUtility::RenderablesVisit
88
#include <sutk/InputEventHandlerObject.hpp> // for SUTK::MouseEventsBlockerObject
9-
#include <sutk/Concepts.hpp> // for SUTK::ContainerT
109

1110
namespace SUTK
1211
{
13-
template<ContainerT ContainerType>
14-
class MaskedScrollableContainer : public ContainerType, public MouseEventsBlockerObject, public Scrollable
12+
template<ContainerT ContainerType, typename ScrollableContainerType = ScrollableContainer<ContainerType>>
13+
class SUTK_API MaskedScrollableContainer : public ScrollableContainerType, public MouseEventsBlockerObject
1514
{
15+
using BaseType = ScrollableContainerType;
1616
protected:
1717
void setMaskFor(Container* container, Rect2Df rect) const noexcept;
1818
// Recursively finds all SUTK::GfxDriverRenderable objects
@@ -38,15 +38,15 @@ namespace SUTK
3838
void restoreMaskFor(Container* container) noexcept;
3939
};
4040

41-
template<ContainerT ContainerType>
41+
template<ContainerT ContainerType, typename ScrollableContainerType>
4242
template<typename... Args>
43-
MaskedScrollableContainer<ContainerType>::MaskedScrollableContainer(UIDriver& driver, Container* parent, Args&&... args) noexcept : ContainerType(driver, parent, std::forward<Args&&>(args)...), MouseEventsBlockerObject(driver, this, this->getDepth() + 10000), Scrollable(this)
43+
MaskedScrollableContainer<ContainerType, ScrollableContainerType>::MaskedScrollableContainer(UIDriver& driver, Container* parent, Args&&... args) noexcept : BaseType(driver, parent, std::forward<Args&&>(args)...), MouseEventsBlockerObject(driver, this, this->getDepth() + 10000)
4444
{
4545
_com_assert(dynamic_cast<ScrollContainer*>(parent) != NULL);
4646
}
4747

48-
template<ContainerT ContainerType>
49-
void MaskedScrollableContainer<ContainerType>::setMaskFor(Container* container, Rect2Df rect) const noexcept
48+
template<ContainerT ContainerType, typename ScrollableContainerType>
49+
void MaskedScrollableContainer<ContainerType, ScrollableContainerType>::setMaskFor(Container* container, Rect2Df rect) const noexcept
5050
{
5151
ContainerUtility::RenderablesVisit(container, [rect](Renderable* renderable)
5252
{
@@ -57,58 +57,58 @@ namespace SUTK
5757
}
5858
});
5959
}
60-
template<ContainerT ContainerType>
61-
void MaskedScrollableContainer<ContainerType>::updateMaskFor(Container* container) const noexcept
60+
template<ContainerT ContainerType, typename ScrollableContainerType>
61+
void MaskedScrollableContainer<ContainerType, ScrollableContainerType>::updateMaskFor(Container* container) const noexcept
6262
{
63-
const ScrollContainer* scrollCont = getScrollContainer();
63+
const ScrollContainer* scrollCont = BaseType::getScrollContainer();
6464
if(!scrollCont)
6565
return;
6666
Rect2Df rect = scrollCont->getGlobalRect();
6767
setMaskFor(container, rect);
6868
}
6969

70-
template<ContainerT ContainerType>
71-
void MaskedScrollableContainer<ContainerType>::updateMask() noexcept
70+
template<ContainerT ContainerType, typename ScrollableContainerType>
71+
void MaskedScrollableContainer<ContainerType, ScrollableContainerType>::updateMask() noexcept
7272
{
7373
updateMaskFor(this);
7474
}
7575

76-
template<ContainerT ContainerType>
77-
void MaskedScrollableContainer<ContainerType>::onParentResize(const Rect2Df& newRect, bool isPositionChanged, bool isSizeChanged)
76+
template<ContainerT ContainerType, typename ScrollableContainerType>
77+
void MaskedScrollableContainer<ContainerType, ScrollableContainerType>::onParentResize(const Rect2Df& newRect, bool isPositionChanged, bool isSizeChanged)
7878
{
7979
// Mandatory to be called by the overriding method
80-
ContainerType::onParentResize(newRect, isPositionChanged, isSizeChanged);
80+
BaseType::onParentResize(newRect, isPositionChanged, isSizeChanged);
8181
updateMask();
8282
}
8383

84-
template<ContainerT ContainerType>
85-
void MaskedScrollableContainer<ContainerType>::onAddChild(Container* child)
84+
template<ContainerT ContainerType, typename ScrollableContainerType>
85+
void MaskedScrollableContainer<ContainerType, ScrollableContainerType>::onAddChild(Container* child)
8686
{
87-
ContainerType::onAddChild(child);
87+
BaseType::onAddChild(child);
8888
updateMaskFor(child);
8989
}
9090

91-
template<ContainerT ContainerType>
92-
void MaskedScrollableContainer<ContainerType>::restoreMaskFor(Container* container) noexcept
91+
template<ContainerT ContainerType, typename ScrollableContainerType>
92+
void MaskedScrollableContainer<ContainerType, ScrollableContainerType>::restoreMaskFor(Container* container) noexcept
9393
{
9494
// Restore visible area to the entire window for this removed child
9595
// as it is now no longer affected by Scrolling and Masking.
96-
Vec2Df size = ContainerType::getUIDriver().getWindowSize();
96+
Vec2Df size = BaseType::getUIDriver().getWindowSize();
9797
setMaskFor(container, { {0, 0}, size });
9898
}
9999

100-
template<ContainerT ContainerType>
101-
void MaskedScrollableContainer<ContainerType>::onRemoveChild(Container* child)
100+
template<ContainerT ContainerType, typename ScrollableContainerType>
101+
void MaskedScrollableContainer<ContainerType, ScrollableContainerType>::onRemoveChild(Container* child)
102102
{
103103
restoreMaskFor(child);
104-
ContainerType::onRemoveChild(child);
104+
BaseType::onRemoveChild(child);
105105
}
106106

107-
template<ContainerT ContainerType>
108-
bool MaskedScrollableContainer<ContainerType>::isInside(Vec2Df point) const noexcept
107+
template<ContainerT ContainerType, typename ScrollableContainerType>
108+
bool MaskedScrollableContainer<ContainerType, ScrollableContainerType>::isInside(Vec2Df point) const noexcept
109109
{
110110
bool isInsideOfOuterRect = MouseEventsBlockerObject::isInside(point);
111-
const ScrollContainer* scrollCont = getScrollContainer();
111+
const ScrollContainer* scrollCont = BaseType::getScrollContainer();
112112
if(!scrollCont || !isInsideOfOuterRect)
113113
return isInsideOfOuterRect;
114114
Rect2Df rect = scrollCont->getGlobalRect();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
#include <sutk/Scrollable.hpp> // for SUTK::Scrollable
4+
#include <sutk/Concepts.hpp> // for SUTK::ContainerT
5+
6+
namespace SUTK
7+
{
8+
// Any Container which is supposed to be a child of ScrollContainer, i.e. it is Scrollable, then
9+
// It must be derived from this class.
10+
// NOTE: If the container also handles inputs and display visuals (Renderables) then you're probably lookin for
11+
// MaskedScrollableContainer which is also derived from this class. (see: MaskedScrollableContainer.hpp)
12+
template<ContainerT ContainerType = Container>
13+
class SUTK_API ScrollableContainer : public ContainerType, public Scrollable
14+
{
15+
public:
16+
template<typename... Args>
17+
ScrollableContainer(UIDriver& driver, Container* parent, Args&&... args) noexcept : ContainerType(driver, parent, std::forward<Args&&>(args)...), Scrollable(this) { }
18+
};
19+
}

0 commit comments

Comments
 (0)