mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
331 lines
6.6 KiB
C++
331 lines
6.6 KiB
C++
#include "stdafx.h"
|
|
#include "ButtonBase.h"
|
|
|
|
namespace Forms
|
|
{
|
|
ButtonBase::ButtonBase()
|
|
: Control(), _OwnerDraw(false), _Flags((ButtonFlags)0), _FlatStyle(FlatStyle::Standard), _TextAlign(Drawing::ContentAlignment::MiddleCenter)
|
|
{
|
|
SetStyle(ControlStyles::SupportsTransparentBackColor |
|
|
ControlStyles::Opaque |
|
|
ControlStyles::ResizeRedraw |
|
|
ControlStyles::OptimizedDoubleBuffer |
|
|
ControlStyles::CacheText |
|
|
ControlStyles::StandardClick, true);
|
|
|
|
SetStyle(ControlStyles::UserMouse |
|
|
ControlStyles::UserPaint, this->_OwnerDraw);
|
|
}
|
|
|
|
bool ButtonBase::OwnerDraw()
|
|
{
|
|
return this->_OwnerDraw;
|
|
}
|
|
|
|
void ButtonBase::SetOwnerDraw(bool Value)
|
|
{
|
|
this->_OwnerDraw = Value;
|
|
|
|
SetStyle(ControlStyles::UserMouse | ControlStyles::UserPaint, Value);
|
|
|
|
UpdateStyles();
|
|
Invalidate();
|
|
}
|
|
|
|
Drawing::ContentAlignment ButtonBase::TextAlign()
|
|
{
|
|
return this->_TextAlign;
|
|
}
|
|
|
|
void ButtonBase::SetTextAlign(Drawing::ContentAlignment Value)
|
|
{
|
|
this->_TextAlign = Value;
|
|
|
|
if (this->_OwnerDraw)
|
|
Invalidate();
|
|
else
|
|
UpdateStyles();
|
|
}
|
|
|
|
FlatStyle ButtonBase::GetFlatStyle()
|
|
{
|
|
return this->_FlatStyle;
|
|
}
|
|
|
|
void ButtonBase::SetFlatStyle(FlatStyle Value)
|
|
{
|
|
this->_FlatStyle = Value;
|
|
|
|
Invalidate();
|
|
|
|
// Force update styles...
|
|
SetStyle(ControlStyles::UserMouse | ControlStyles::UserPaint, this->_OwnerDraw);
|
|
UpdateStyles();
|
|
}
|
|
|
|
bool ButtonBase::IsDefault()
|
|
{
|
|
return GetFlag(ButtonFlags::FlagIsDefault);
|
|
}
|
|
|
|
void ButtonBase::SetIsDefault(bool Value)
|
|
{
|
|
if (IsDefault() != Value)
|
|
{
|
|
SetFlag(ButtonFlags::FlagIsDefault, Value);
|
|
|
|
if (this->_OwnerDraw)
|
|
Invalidate();
|
|
else
|
|
UpdateStyles();
|
|
}
|
|
}
|
|
|
|
bool ButtonBase::GetFlag(ButtonFlags Flag)
|
|
{
|
|
return ((int)this->_Flags & (int)Flag) == (int)Flag;
|
|
}
|
|
|
|
void ButtonBase::SetFlag(ButtonFlags Flags, bool Value)
|
|
{
|
|
this->_Flags = Value ? (ButtonFlags)((int)this->_Flags | (int)Flags) : (ButtonFlags)((int)this->_Flags & ~(int)Flags);
|
|
}
|
|
|
|
void ButtonBase::OnLostFocus()
|
|
{
|
|
Control::OnLostFocus();
|
|
|
|
// Hitting tab while holding down the space key
|
|
SetFlag(ButtonFlags::FlagMouseDown, false);
|
|
SetCapture(false);
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
void ButtonBase::OnGotFocus()
|
|
{
|
|
Control::OnGotFocus();
|
|
Invalidate();
|
|
}
|
|
|
|
void ButtonBase::OnMouseEnter()
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseOver, true);
|
|
Invalidate();
|
|
|
|
// Call base event last
|
|
Control::OnMouseEnter();
|
|
}
|
|
|
|
void ButtonBase::OnMouseLeave()
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseOver, false);
|
|
Invalidate();
|
|
|
|
// Call base event last
|
|
Control::OnMouseLeave();
|
|
}
|
|
|
|
void ButtonBase::OnEnabledChanged()
|
|
{
|
|
Control::OnEnabledChanged();
|
|
|
|
if (!Enabled())
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseDown | ButtonFlags::FlagMouseOver, false);
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void ButtonBase::OnTextChanged()
|
|
{
|
|
Control::OnTextChanged();
|
|
Invalidate();
|
|
}
|
|
|
|
void ButtonBase::OnMouseMove(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
|
{
|
|
if (EventArgs->Button != MouseButtons::None && GetFlag(ButtonFlags::FlagMousePressed))
|
|
{
|
|
auto CRect = this->ClientRectangle();
|
|
|
|
if (!CRect.Contains(EventArgs->X, EventArgs->Y))
|
|
{
|
|
if (GetFlag(ButtonFlags::FlagMouseDown))
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseDown, false);
|
|
Invalidate();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!GetFlag(ButtonFlags::FlagMouseDown))
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseDown, true);
|
|
Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Call base event last
|
|
Control::OnMouseMove(EventArgs);
|
|
}
|
|
|
|
void ButtonBase::OnMouseDown(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
|
{
|
|
if (EventArgs->Button == MouseButtons::Left)
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseDown | ButtonFlags::FlagMousePressed, true);
|
|
Invalidate();
|
|
}
|
|
|
|
// Call base event last
|
|
Control::OnMouseDown(EventArgs);
|
|
}
|
|
|
|
void ButtonBase::OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
|
{
|
|
// Call base event last
|
|
Control::OnMouseUp(EventArgs);
|
|
}
|
|
|
|
void ButtonBase::OnKeyUp(const std::unique_ptr<KeyEventArgs>& EventArgs)
|
|
{
|
|
if (GetFlag(ButtonFlags::FlagMouseDown))
|
|
{
|
|
if (this->_OwnerDraw)
|
|
ResetFlagsAndPaint();
|
|
else
|
|
{
|
|
SetFlag(ButtonFlags::FlagMousePressed | ButtonFlags::FlagMouseDown, false);
|
|
SendMessageA(this->_Handle, BM_SETSTATE, 0, 0);
|
|
}
|
|
|
|
if (EventArgs->KeyCode() == Keys::Enter || EventArgs->KeyCode() == Keys::Space)
|
|
OnClick();
|
|
|
|
EventArgs->SetHandled(true);
|
|
}
|
|
|
|
// Call base event last
|
|
Control::OnKeyUp(EventArgs);
|
|
}
|
|
|
|
void ButtonBase::OnKeyDown(const std::unique_ptr<KeyEventArgs>& EventArgs)
|
|
{
|
|
if (EventArgs->KeyData() == Keys::Space)
|
|
{
|
|
if (!GetFlag(ButtonFlags::FlagMouseDown))
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseDown, true);
|
|
|
|
if (!this->_OwnerDraw)
|
|
SendMessageA(this->_Handle, BM_SETSTATE, 1, 0);
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
EventArgs->SetHandled(true);
|
|
}
|
|
|
|
// Call base event last
|
|
Control::OnKeyDown(EventArgs);
|
|
}
|
|
|
|
void ButtonBase::WndProc(Message& Msg)
|
|
{
|
|
switch (Msg.Msg)
|
|
{
|
|
case BM_CLICK:
|
|
OnClick();
|
|
return;
|
|
}
|
|
|
|
if (this->_OwnerDraw)
|
|
{
|
|
switch (Msg.Msg)
|
|
{
|
|
case BM_SETSTATE:
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
case WM_CANCELMODE:
|
|
case WM_CAPTURECHANGED:
|
|
|
|
if (!GetFlag(ButtonFlags::FlagInButtonUp) && GetFlag(ButtonFlags::FlagMousePressed))
|
|
{
|
|
SetFlag(ButtonFlags::FlagMousePressed, false);
|
|
|
|
if (GetFlag(ButtonFlags::FlagMouseDown))
|
|
{
|
|
SetFlag(ButtonFlags::FlagMouseDown, false);
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
Control::WndProc(Msg);
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
case WM_MBUTTONUP:
|
|
case WM_RBUTTONUP:
|
|
|
|
SetFlag(ButtonFlags::FlagInButtonUp, true);
|
|
Control::WndProc(Msg);
|
|
SetFlag(ButtonFlags::FlagInButtonUp, false);
|
|
|
|
break;
|
|
|
|
default:
|
|
Control::WndProc(Msg);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Msg.Msg == (WM_REFLECT + WM_COMMAND) && HIWORD(Msg.WParam) == BN_CLICKED)
|
|
OnClick();
|
|
else
|
|
Control::WndProc(Msg);
|
|
}
|
|
}
|
|
|
|
CreateParams ButtonBase::GetCreateParams()
|
|
{
|
|
auto Cp = Control::GetCreateParams();
|
|
|
|
if (!this->_OwnerDraw)
|
|
{
|
|
Cp.ExStyle &= ~WS_EX_RIGHT; // Messes up the BM_ Alignment flags
|
|
|
|
Cp.Style |= BS_MULTILINE;
|
|
|
|
if (IsDefault())
|
|
Cp.Style |= BS_DEFPUSHBUTTON;
|
|
|
|
if (((int)this->_TextAlign & (int)Drawing::AnyLeftAlign) != 0)
|
|
Cp.Style |= BS_LEFT;
|
|
else if (((int)this->_TextAlign & (int)Drawing::AnyRightAlign) != 0)
|
|
Cp.Style |= BS_RIGHT;
|
|
else
|
|
Cp.Style |= BS_CENTER;
|
|
|
|
if (((int)this->_TextAlign & (int)Drawing::AnyTopAlign) != 0)
|
|
Cp.Style |= BS_TOP;
|
|
else if (((int)this->_TextAlign & (int)Drawing::AnyBottomAlign) != 0)
|
|
Cp.Style |= BS_BOTTOM;
|
|
else
|
|
Cp.Style |= BS_VCENTER;
|
|
}
|
|
|
|
return Cp;
|
|
}
|
|
|
|
void ButtonBase::ResetFlagsAndPaint()
|
|
{
|
|
SetFlag(ButtonFlags::FlagMousePressed | ButtonFlags::FlagMouseDown, false);
|
|
Invalidate();
|
|
Update();
|
|
}
|
|
}
|