mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
188 lines
3.6 KiB
C++
188 lines
3.6 KiB
C++
#include <Common/Hook.h>
|
|
#include <Overlay/Control.h>
|
|
|
|
namespace Overlay
|
|
{
|
|
Control::Control(Control* parent, const RECT& rect, DWORD style)
|
|
: m_parent(parent)
|
|
, m_rect(rect)
|
|
, m_style(style)
|
|
, m_highlightedChild(nullptr)
|
|
{
|
|
if (parent)
|
|
{
|
|
parent->m_children.insert(this);
|
|
}
|
|
}
|
|
|
|
Control::~Control()
|
|
{
|
|
if (m_parent)
|
|
{
|
|
m_parent->m_children.erase(this);
|
|
}
|
|
}
|
|
|
|
void Control::drawAll(HDC dc)
|
|
{
|
|
draw(dc);
|
|
|
|
for (auto control : m_children)
|
|
{
|
|
control->drawAll(dc);
|
|
}
|
|
|
|
if (m_style & WS_BORDER)
|
|
{
|
|
RECT r = m_rect;
|
|
if (!m_parent)
|
|
{
|
|
OffsetRect(&r, -r.left, -r.top);
|
|
}
|
|
SetDCPenColor(dc, isEnabled() ? FOREGROUND_COLOR : DISABLED_COLOR);
|
|
CALL_ORIG_FUNC(Rectangle)(dc, r.left, r.top, r.right, r.bottom);
|
|
SetDCPenColor(dc, FOREGROUND_COLOR);
|
|
}
|
|
|
|
if (m_highlightedChild && m_highlightedChild->isEnabled())
|
|
{
|
|
RECT r = m_highlightedChild->getHighlightRect();
|
|
SetDCPenColor(dc, HIGHLIGHT_COLOR);
|
|
CALL_ORIG_FUNC(Rectangle)(dc, r.left, r.top, r.right, r.bottom);
|
|
SetDCPenColor(dc, FOREGROUND_COLOR);
|
|
}
|
|
}
|
|
|
|
void Control::drawArrow(HDC dc, RECT rect, UINT state)
|
|
{
|
|
CALL_ORIG_FUNC(Rectangle)(dc, rect.left, rect.top, rect.right, rect.bottom);
|
|
|
|
POINT center = { (rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2 };
|
|
rect = { center.x, center.y, center.x, center.y };
|
|
InflateRect(&rect, 3, 3);
|
|
POINT poly[3] = {};
|
|
|
|
switch (state)
|
|
{
|
|
case DFCS_SCROLLDOWN:
|
|
poly[0] = { rect.left, rect.top };
|
|
poly[1] = { rect.right, rect.top };
|
|
poly[2] = { center.x, rect.bottom };
|
|
break;
|
|
|
|
case DFCS_SCROLLLEFT:
|
|
poly[0] = { rect.left, center.y };
|
|
poly[1] = { rect.right, rect.top };
|
|
poly[2] = { rect.right, rect.bottom };
|
|
break;
|
|
|
|
case DFCS_SCROLLRIGHT:
|
|
poly[0] = { rect.left, rect.top };
|
|
poly[1] = { rect.left, rect.bottom };
|
|
poly[2] = { rect.right, center.y };
|
|
break;
|
|
|
|
case DFCS_SCROLLUP:
|
|
poly[0] = { center.x, rect.top };
|
|
poly[1] = { rect.left, rect.bottom };
|
|
poly[2] = { rect.right, rect.bottom };
|
|
break;
|
|
}
|
|
|
|
CALL_ORIG_FUNC(Polygon)(dc, poly, 3);
|
|
}
|
|
|
|
const Control& Control::getRoot() const
|
|
{
|
|
if (m_parent)
|
|
{
|
|
return m_parent->getRoot();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
Control& Control::getRoot()
|
|
{
|
|
return const_cast<Control&>(std::as_const(*this).getRoot());
|
|
}
|
|
|
|
void Control::invalidate()
|
|
{
|
|
if (m_parent)
|
|
{
|
|
m_parent->invalidate();
|
|
}
|
|
}
|
|
|
|
bool Control::isEnabled() const
|
|
{
|
|
return !(m_style & WS_DISABLED) && (!m_parent || m_parent->isEnabled());
|
|
}
|
|
|
|
void Control::setEnabled(bool isEnabled)
|
|
{
|
|
if (!(m_style & WS_DISABLED) != isEnabled)
|
|
{
|
|
m_style = isEnabled ? (m_style & ~WS_DISABLED) : (m_style | WS_DISABLED);
|
|
invalidate();
|
|
}
|
|
}
|
|
|
|
void Control::onLButtonDown(POINT pos)
|
|
{
|
|
propagateMouseEvent(&Control::onLButtonDown, pos);
|
|
}
|
|
|
|
void Control::onLButtonUp(POINT pos)
|
|
{
|
|
propagateMouseEvent(&Control::onLButtonUp, pos);
|
|
}
|
|
|
|
void Control::onMouseMove(POINT pos)
|
|
{
|
|
if (m_style & WS_DISABLED)
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto prevHighlightedChild = m_highlightedChild;
|
|
m_highlightedChild = nullptr;
|
|
propagateMouseEvent(&Control::onMouseMove, pos);
|
|
if (m_highlightedChild != prevHighlightedChild)
|
|
{
|
|
invalidate();
|
|
}
|
|
if (m_parent && (m_style & WS_TABSTOP))
|
|
{
|
|
m_parent->m_highlightedChild = this;
|
|
invalidate();
|
|
}
|
|
}
|
|
|
|
void Control::propagateMouseEvent(void(Control::* onEvent)(POINT), POINT pos)
|
|
{
|
|
if (m_style & WS_DISABLED)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (auto child : m_children)
|
|
{
|
|
if (PtInRect(&child->m_rect, pos))
|
|
{
|
|
(child->*onEvent)(pos);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Control::setVisible(bool isVisible)
|
|
{
|
|
if (isVisible != Control::isVisible())
|
|
{
|
|
m_style ^= WS_VISIBLE;
|
|
invalidate();
|
|
}
|
|
}
|
|
}
|