301 lines
7.8 KiB
C++
301 lines
7.8 KiB
C++
|
#include "main.h"
|
||
|
#include "./toolbarButton.h"
|
||
|
#include "./toolbar.h"
|
||
|
#include "./graphics.h"
|
||
|
#include "./resource.h"
|
||
|
#include "../Plugins/General/gen_ml/ml_ipc_0313.h"
|
||
|
#include <strsafe.h>
|
||
|
|
||
|
#define CMDLINK_SPACECX_UNITS 2
|
||
|
|
||
|
ToolbarButton::ToolbarButton(LPCSTR pszName, INT nCommand, UINT nStyle, INT nIcon, LPCWSTR pszText, LPCWSTR pszDescription) :
|
||
|
ToolbarItem(pszName, nStyle, nIcon, pszText, pszDescription),
|
||
|
commandId(nCommand), offsetX(0), offsetY(0), rgbText(0), rgbHilite(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ToolbarItem* CALLBACK ToolbarButton::CreateInstance(ToolbarItem::Template *item)
|
||
|
{
|
||
|
if (NULL == item)
|
||
|
return NULL;
|
||
|
|
||
|
return new ToolbarButton( (NULL != item->name) ? item->name : TOOLCLS_BUTTON,
|
||
|
item->commandId,
|
||
|
item->style,
|
||
|
item->iconId,
|
||
|
item->text,
|
||
|
item->description);
|
||
|
}
|
||
|
|
||
|
static LPCTSTR ToolbarButton_GetResourceString(LPCTSTR pszResource, LPTSTR pszBuffer, INT cchBufferMax)
|
||
|
{
|
||
|
if (IS_INTRESOURCE(pszResource))
|
||
|
{
|
||
|
Plugin_LoadString((INT)(INT_PTR)pszResource, pszBuffer, cchBufferMax);
|
||
|
return pszBuffer;
|
||
|
}
|
||
|
return pszResource;
|
||
|
}
|
||
|
|
||
|
static BOOL ToolbarButton_GetTextSise(HWND hToolbar, LPCWSTR pszText, INT cchText, SIZE *textSize, TEXTMETRIC *ptm)
|
||
|
{
|
||
|
if (NULL == textSize)
|
||
|
return FALSE;
|
||
|
|
||
|
if (cchText < 0)
|
||
|
cchText = lstrlenW(pszText);
|
||
|
|
||
|
HDC hdc = GetDCEx(hToolbar, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||
|
if (NULL == hdc) return FALSE;
|
||
|
|
||
|
BOOL result = FALSE;
|
||
|
HFONT font = (HFONT)SendMessage(hToolbar, WM_GETFONT, 0, 0L);
|
||
|
HFONT originalFont = (HFONT)SelectObject(hdc, font);
|
||
|
|
||
|
if (NULL != ptm && !GetTextMetrics(hdc, ptm))
|
||
|
ZeroMemory(ptm, sizeof(TEXTMETRIC));
|
||
|
|
||
|
if (0 != cchText)
|
||
|
{
|
||
|
if (GetTextExtentPoint32(hdc, pszText, cchText, textSize))
|
||
|
result = TRUE;
|
||
|
}
|
||
|
else
|
||
|
ZeroMemory(textSize, sizeof(SIZE));
|
||
|
|
||
|
SelectObject(hdc, originalFont);
|
||
|
ReleaseDC(hToolbar, hdc);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BOOL ToolbarButton::AdjustRect(HWND hToolbar, RECT *proposedRect)
|
||
|
{
|
||
|
if (0 != (ToolbarButton::styleCommandLink & style))
|
||
|
{
|
||
|
SIZE linkSize = {0};
|
||
|
LPCTSTR pszText;
|
||
|
WCHAR szBuffer[128] = {0};
|
||
|
TOOLBARTEXTMETRIC ttm = {0};
|
||
|
|
||
|
pszText = ToolbarButton_GetResourceString(text, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
if (!ToolbarButton_GetTextSise(hToolbar, pszText, -1, &linkSize, NULL))
|
||
|
ZeroMemory(&linkSize, sizeof(SIZE));
|
||
|
|
||
|
if (!Toolbar_GetTextMetrics(hToolbar, &ttm))
|
||
|
ZeroMemory(&ttm, sizeof(TOOLBARTEXTMETRIC));
|
||
|
|
||
|
offsetX = MulDiv(CMDLINK_SPACECX_UNITS, ttm.aveCharWidth, 4);
|
||
|
offsetY = ttm.baseY;
|
||
|
proposedRect->right = proposedRect->left + linkSize.cx + 2 * offsetX + ttm.overhang;
|
||
|
|
||
|
proposedRect->top = ttm.origY;
|
||
|
proposedRect->bottom = proposedRect->top + ttm.height;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
SIZE iconSize;
|
||
|
if (!Toolbar_GetIconSize(hToolbar, iconId, &iconSize))
|
||
|
ZeroMemory(&iconSize, sizeof(SIZE));
|
||
|
|
||
|
proposedRect->right = proposedRect->left + iconSize.cx;
|
||
|
INT offsetY = (proposedRect->bottom - proposedRect->top) - iconSize.cy;
|
||
|
if (0 != offsetY)
|
||
|
{
|
||
|
proposedRect->top += offsetY/2;
|
||
|
if (0 != (offsetY%2)) proposedRect->top++;
|
||
|
}
|
||
|
proposedRect->bottom = proposedRect->top + iconSize.cy;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void ToolbarButton::UpdateSkin(HWND hToolbar)
|
||
|
{
|
||
|
rgbText = Toolbar_GetTextColor(hToolbar);
|
||
|
rgbHilite = Toolbar_GetHiliteColor(hToolbar);
|
||
|
}
|
||
|
|
||
|
BOOL ToolbarButton::Paint(HWND hToolbar, HDC hdc, const RECT *paintRect, UINT state)
|
||
|
{
|
||
|
if (statePressed == ((statePressed | stateHighlighted) & state))
|
||
|
state &= ~statePressed;
|
||
|
|
||
|
if (0 != (ToolbarButton::styleCommandLink & style))
|
||
|
{
|
||
|
LPCTSTR pszText;
|
||
|
WCHAR szBuffer[256] = {0};
|
||
|
pszText = ToolbarButton_GetResourceString(text, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
INT cchText = lstrlen(pszText);
|
||
|
if (0 == cchText)
|
||
|
return FALSE;
|
||
|
|
||
|
|
||
|
COLORREF originalFg = GetTextColor(hdc);
|
||
|
COLORREF rgbFg = (0 == (stateHighlighted & style)) ? rgbText : rgbHilite;
|
||
|
|
||
|
SetTextColor(hdc, rgbFg);
|
||
|
INT originalMode = SetBkMode(hdc, TRANSPARENT);
|
||
|
UINT originalAlign = SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
|
||
|
|
||
|
ExtTextOut(hdc, rect.left + offsetX, rect.top + offsetY, ETO_CLIPPED | ETO_OPAQUE, &rect, pszText, cchText, NULL);
|
||
|
|
||
|
if (TRANSPARENT != originalMode) SetBkMode(hdc, originalMode);
|
||
|
if ((TA_LEFT | TA_BASELINE) != originalAlign) SetTextAlign(hdc, originalAlign);
|
||
|
|
||
|
if (0 != (stateHighlighted & style))
|
||
|
{
|
||
|
COLORREF originalBk = SetBkColor(hdc, rgbFg);
|
||
|
|
||
|
RECT partRect;
|
||
|
::SetRect(&partRect, rect.left + offsetX, rect.top + offsetY + 1, rect.right - offsetX, rect.top + offsetY + 2);
|
||
|
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &partRect, NULL, 0, NULL);
|
||
|
|
||
|
SetBkColor(hdc, originalBk);
|
||
|
}
|
||
|
|
||
|
if (rgbFg != originalFg)
|
||
|
SetTextColor(hdc, originalFg);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
TOOLBARDRAWICONPARAM param;
|
||
|
param.hdcDst = hdc;
|
||
|
param.iconIndex = iconId;
|
||
|
param.x = rect.left;
|
||
|
param.y = rect.top;
|
||
|
param.cx = rect.right - rect.left;
|
||
|
param.cy = rect.bottom - rect.top;
|
||
|
param.itemState = state;
|
||
|
if (Toolbar_DrawIcon(hToolbar, ¶m))
|
||
|
{
|
||
|
if (stateFocused == ((stateFocused | stateNoFocusRect) & state))
|
||
|
{
|
||
|
RECT focusRect;
|
||
|
CopyRect(&focusRect, &rect);
|
||
|
focusRect.left += 1;
|
||
|
focusRect.top += 2;
|
||
|
focusRect.bottom -= 1;
|
||
|
COLORREF origBk = SetBkColor(hdc, 0x00000000);
|
||
|
COLORREF origFg = SetTextColor(hdc, 0x00FFFFFF);
|
||
|
DrawFocusRect(hdc, &focusRect);
|
||
|
if (origBk != 0x00000000) SetBkColor(hdc, origBk);
|
||
|
if (origFg != 0x00FFFFFF) SetTextColor(hdc, origFg);
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
INT ToolbarButton::GetTip(LPTSTR pszBuffer, INT cchBufferMax)
|
||
|
{
|
||
|
if (IS_INTRESOURCE(description))
|
||
|
{
|
||
|
if (NULL == pszBuffer || cchBufferMax < 1)
|
||
|
return 0;
|
||
|
Plugin_LoadString((INT)(INT_PTR)description, pszBuffer, cchBufferMax);
|
||
|
return lstrlen(pszBuffer);
|
||
|
}
|
||
|
|
||
|
size_t remaining;
|
||
|
HRESULT hr = StringCchCopyEx(pszBuffer, cchBufferMax, description, NULL, &remaining, STRSAFE_IGNORE_NULLS);
|
||
|
return SUCCEEDED(hr) ? (cchBufferMax - (INT)remaining) : 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL ToolbarButton::PtInItem(POINT pt)
|
||
|
{
|
||
|
return (pt.x >= (rect.left + offsetX) && pt.x < (rect.right - offsetX) && rect.bottom != rect.top);
|
||
|
}
|
||
|
INT ToolbarButton::GetCommandId()
|
||
|
{
|
||
|
return commandId;
|
||
|
}
|
||
|
void ToolbarButton::MouseMove(HWND hToolbar, UINT mouseFlags, POINT pt)
|
||
|
{
|
||
|
UINT styleNew = (PtInItem(pt)) ? stateHighlighted : 0;
|
||
|
SetStyle(hToolbar, styleNew, stateHighlighted);
|
||
|
|
||
|
}
|
||
|
|
||
|
void ToolbarButton::MouseLeave(HWND hToolbar)
|
||
|
{
|
||
|
if (0 != (stateHighlighted & style))
|
||
|
{
|
||
|
SetStyle(hToolbar, 0, stateHighlighted);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ToolbarButton::LButtonDown(HWND hToolbar, UINT mouseFlags, POINT pt)
|
||
|
{
|
||
|
SetStyle(hToolbar, statePressed, statePressed);
|
||
|
}
|
||
|
void ToolbarButton::LButtonUp(HWND hToolbar, UINT mouseFlags, POINT pt)
|
||
|
{
|
||
|
SetStyle(hToolbar, 0, statePressed);
|
||
|
}
|
||
|
void ToolbarButton::Click(HWND hToolbar, UINT mouseFlags, POINT pt)
|
||
|
{
|
||
|
if (0 != commandId)
|
||
|
{
|
||
|
Toolbar_SendCommand(hToolbar, commandId);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL ToolbarButton::FillMenuInfo(HWND hToolbar, MENUITEMINFO *pmii, LPWSTR pszBuffer, INT cchBufferMax)
|
||
|
{
|
||
|
pmii->fMask = MIIM_STRING | MIIM_ID | MIIM_STATE;
|
||
|
pmii->wID = commandId;
|
||
|
pmii->fState = MFS_UNHILITE;
|
||
|
pmii->fState |= ((0 == (stateDisabled & style)) ? MFS_ENABLED : MFS_DISABLED);
|
||
|
pmii->dwTypeData = pszBuffer;
|
||
|
|
||
|
if (IS_INTRESOURCE(text))
|
||
|
{
|
||
|
Plugin_LoadString((INT)(INT_PTR)text, pszBuffer, cchBufferMax);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (FAILED(StringCchCopyEx(pszBuffer, cchBufferMax, text, NULL, NULL, STRSAFE_IGNORE_NULLS)))
|
||
|
pszBuffer[0] = L'\0';
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL ToolbarButton::KeyDown(HWND hToolbar, INT vKey, UINT flags)
|
||
|
{
|
||
|
switch(vKey)
|
||
|
{
|
||
|
case VK_SPACE:
|
||
|
case VK_RETURN:
|
||
|
SetStyle(hToolbar, statePressed | stateHighlighted, statePressed | stateHighlighted);
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL ToolbarButton::KeyUp(HWND hToolbar, INT vKey, UINT flags)
|
||
|
{
|
||
|
switch(vKey)
|
||
|
{
|
||
|
case VK_SPACE:
|
||
|
case VK_RETURN:
|
||
|
if (0 != (statePressed & style))
|
||
|
{
|
||
|
SetStyle(hToolbar, 0, (statePressed | stateHighlighted));
|
||
|
if (0 != commandId)
|
||
|
Toolbar_SendCommand(hToolbar, commandId);
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void ToolbarButton::SetFocus(HWND hToolbar, ToolbarItem *focusItem, BOOL fSet)
|
||
|
{
|
||
|
InvalidateRect(hToolbar, &rect, FALSE);
|
||
|
}
|