Initial commit
This commit is contained in:
286
engines/bagel/mfc/button.cpp
Normal file
286
engines/bagel/mfc/button.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/textconsole.h"
|
||||
#include "bagel/mfc/afxwin.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace MFC {
|
||||
|
||||
IMPLEMENT_DYNAMIC(CButton, CWnd)
|
||||
BEGIN_MESSAGE_MAP(CButton, CWnd)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_LBUTTONUP()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_MESSAGE(BM_CLICK, CButton::OnBnClicked)
|
||||
ON_MESSAGE(BM_SETCHECK, CButton::OnBnSetCheck)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
bool CButton::Create(const char *lpszCaption, uint32 dwStyle,
|
||||
const RECT &rect, CWnd *pParentWnd, unsigned int nID) {
|
||||
return CWnd::Create("BUTTON", lpszCaption, dwStyle, rect,
|
||||
pParentWnd, nID);
|
||||
}
|
||||
|
||||
int CButton::GetCheck() const {
|
||||
return (_itemState & ODS_CHECKED) != 0 ?
|
||||
BST_CHECKED : BST_UNCHECKED;
|
||||
}
|
||||
|
||||
void CButton::SetCheck(int nCheck) {
|
||||
SendMessage(BM_SETCHECK, nCheck);
|
||||
}
|
||||
|
||||
void CButton::SetButtonStyle(unsigned int nStyle, bool bRedraw) {
|
||||
m_nStyle = (m_nStyle & ~0xf) | nStyle;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
unsigned int CButton::GetButtonStyle() const {
|
||||
return GetStyle() & 0xf;
|
||||
}
|
||||
|
||||
void CButton::OnPaint() {
|
||||
switch (GetButtonStyle()) {
|
||||
case BS_PUSHBUTTON:
|
||||
case BS_DEFPUSHBUTTON:
|
||||
OnPushButtonPaint();
|
||||
break;
|
||||
|
||||
case BS_PUSHBOX:
|
||||
OnPushBoxPaint();
|
||||
break;
|
||||
|
||||
case BS_OWNERDRAW:
|
||||
OnOwnerDrawPaint();
|
||||
break;
|
||||
|
||||
default: {
|
||||
// Fallback for unhandled button types
|
||||
RECT clientRect;
|
||||
GetClientRect(&clientRect);
|
||||
CPaintDC dc(this);
|
||||
dc.FillSolidRect(&clientRect, RGB(255, 255, 255));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CButton::OnPushButtonPaint() {
|
||||
CPaintDC dc(this);
|
||||
|
||||
// Get the client rectangle of the window
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
|
||||
// Determine state
|
||||
bool isEnabled = IsWindowEnabled();
|
||||
|
||||
// Choose background color based on state
|
||||
COLORREF bgColor = isEnabled ? RGB(240, 240, 240) : RGB(200, 200, 200);
|
||||
dc.FillSolidRect(rect, bgColor);
|
||||
|
||||
if (_pressed) {
|
||||
dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT);
|
||||
} else {
|
||||
dc.DrawEdge(&rect, EDGE_RAISED, BF_RECT);
|
||||
}
|
||||
|
||||
// Draw text
|
||||
CString text;
|
||||
GetWindowText(text);
|
||||
dc.SetBkMode(TRANSPARENT);
|
||||
dc.DrawText(text, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
|
||||
void CButton::OnPushBoxPaint() {
|
||||
CPaintDC dc(this);
|
||||
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
|
||||
// Choose colors
|
||||
COLORREF clrFace = GetSysColor(COLOR_BTNFACE);
|
||||
COLORREF clrHighlight = GetSysColor(COLOR_BTNHIGHLIGHT); // Top/left
|
||||
COLORREF clrShadow = GetSysColor(COLOR_BTNSHADOW); // Bottom/right
|
||||
COLORREF clrText = GetSysColor(COLOR_BTNTEXT);
|
||||
|
||||
// Fill background
|
||||
dc.FillSolidRect(rect, clrFace);
|
||||
|
||||
// Draw 3D border
|
||||
if (_pressed) {
|
||||
// Inset border (pressed look)
|
||||
dc.Draw3dRect(rect, clrShadow, clrHighlight);
|
||||
rect.DeflateRect(1, 1);
|
||||
dc.Draw3dRect(rect, clrShadow, clrHighlight);
|
||||
} else {
|
||||
// Raised border (normal look)
|
||||
dc.Draw3dRect(rect, clrHighlight, clrShadow);
|
||||
rect.DeflateRect(1, 1);
|
||||
dc.Draw3dRect(rect, clrHighlight, clrShadow);
|
||||
}
|
||||
|
||||
// Adjust text position if pressed
|
||||
CPoint offset = _pressed ? CPoint(1, 1) : CPoint(0, 0);
|
||||
|
||||
// Draw button text
|
||||
dc.SetBkMode(TRANSPARENT);
|
||||
dc.SetTextColor(clrText);
|
||||
dc.SelectObject(GetStockObject(SYSTEM_FONT));
|
||||
|
||||
CRect textRect = rect;
|
||||
textRect.OffsetRect(offset);
|
||||
|
||||
dc.DrawText(_windowText, &textRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
|
||||
// Draw focus rectangle
|
||||
if (_hasFocus) {
|
||||
CRect focusRect = rect;
|
||||
focusRect.DeflateRect(3, 3);
|
||||
dc.DrawFocusRect(&focusRect);
|
||||
}
|
||||
}
|
||||
|
||||
void CButton::OnOwnerDrawPaint() {
|
||||
// Prepare the draw item struct
|
||||
DRAWITEMSTRUCT dis = { 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0 };
|
||||
dis.CtlType = ODT_BUTTON;
|
||||
dis.CtlID = GetDlgCtrlID();
|
||||
dis.itemID = 0;
|
||||
dis.itemAction = ODA_DRAWENTIRE;
|
||||
dis.itemState = 0;
|
||||
|
||||
if (IsWindowEnabled())
|
||||
dis.itemState |= ODS_ENABLED;
|
||||
else
|
||||
dis.itemState |= ODS_DISABLED;
|
||||
if ((GetState() & ODS_CHECKED) != 0 || _pressed)
|
||||
dis.itemState |= ODS_SELECTED;
|
||||
if (GetFocus() == this)
|
||||
dis.itemState |= ODS_FOCUS;
|
||||
|
||||
dis.hwndItem = m_hWnd;
|
||||
|
||||
// Get the client rect for the button
|
||||
GetClientRect(&dis.rcItem);
|
||||
|
||||
// Get a DC for drawing
|
||||
PAINTSTRUCT paintStruct;
|
||||
HDC hdc = BeginPaint(&paintStruct);
|
||||
dis.hDC = hdc;
|
||||
|
||||
// Send WM_DRAWITEM to the parent window
|
||||
GetParent()->SendMessage(WM_DRAWITEM,
|
||||
dis.CtlID, (LPARAM)&dis);
|
||||
|
||||
EndPaint(&paintStruct);
|
||||
}
|
||||
|
||||
void CButton::OnLButtonDown(unsigned int nFlags, CPoint point) {
|
||||
if (!(_itemState & ODS_DISABLED)) {
|
||||
SetCapture();
|
||||
_pressed = true;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void CButton::OnLButtonUp(unsigned int nFlags, CPoint point) {
|
||||
if (GetCapture() == this)
|
||||
ReleaseCapture();
|
||||
if (!_pressed)
|
||||
return;
|
||||
_pressed = false;
|
||||
|
||||
// Redraw the button immediately, before we trigger any actions
|
||||
Invalidate();
|
||||
UpdateWindow();
|
||||
|
||||
switch (GetButtonStyle()) {
|
||||
case BS_PUSHBUTTON:
|
||||
case BS_DEFPUSHBUTTON:
|
||||
case BS_PUSHBOX:
|
||||
case BS_OWNERDRAW:
|
||||
SendMessage(BM_CLICK);
|
||||
break;
|
||||
|
||||
case BS_CHECKBOX:
|
||||
SetCheck(_itemState & BST_CHECKED ?
|
||||
BST_CHECKED : BST_UNCHECKED);
|
||||
SendMessage(BM_SETCHECK, _itemState & BST_CHECKED);
|
||||
break;
|
||||
|
||||
case BS_AUTORADIOBUTTON:
|
||||
SetCheck(BST_CHECKED);
|
||||
SendMessage(BM_SETCHECK, BST_CHECKED);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Unhandled button type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CButton::OnMouseMove(unsigned int nFlags, CPoint point) {
|
||||
if (GetCapture() == this) {
|
||||
if (_pressed != PointInClientRect(point)) {
|
||||
_pressed = !_pressed;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CButton::OnBnClicked(WPARAM wParam, LPARAM lParam) {
|
||||
GetParent()->SendMessage(WM_COMMAND, GetDlgCtrlID(),
|
||||
MAKELPARAM(0, BN_CLICKED));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CButton::OnBnSetCheck(WPARAM wParam, LPARAM lParam) {
|
||||
if (wParam == BST_UNCHECKED) {
|
||||
// Uncheck the button
|
||||
_itemState &= ~BST_CHECKED;
|
||||
} else {
|
||||
// Check the button
|
||||
_itemState |= BST_CHECKED;
|
||||
|
||||
// Need to clear all of the others
|
||||
CWnd *pParent = GetParent();
|
||||
CWnd *pWnd = this;
|
||||
|
||||
for (;;) {
|
||||
pWnd = pParent->GetNextDlgGroupItem(pWnd, true);
|
||||
if (pWnd == this)
|
||||
// No more to do
|
||||
break;
|
||||
|
||||
pWnd->SendMessage(BM_SETCHECK, false);
|
||||
}
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace MFC
|
||||
} // namespace Bagel
|
||||
Reference in New Issue
Block a user