Skip to content

customizable toolbars #3259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/mpc-hc/AppSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "date/date.h"
#include "PPageExternalFilters.h"
#include "../VideoRenderers/MPCVRAllocatorPresenter.h"
std::map<DWORD, const wmcmd_base*> CAppSettings::CommandIDToWMCMD;

#pragma warning(push)
#pragma warning(disable: 4351) // new behavior: elements of array 'array' will be default initialized
Expand Down Expand Up @@ -755,6 +756,7 @@ void CAppSettings::CreateCommands()
for (const auto& wc : default_wmcmds) {
wmcmd w = wmcmd(wc);
w.fVirt |= FVIRTKEY | FNOINVERT;
CommandIDToWMCMD[wc.cmd] = &wc;
wmcmds.AddTail(w);
}
ASSERT(wmcmds.GetCount() <= ACCEL_LIST_SIZE);
Expand Down
1 change: 1 addition & 0 deletions src/mpc-hc/AppSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ class CAppSettings
// cmdline params
UINT64 nCLSwitches;
CAtlList<CString> slFiles, slDubs, slSubs, slFilters;
static std::map<DWORD, const wmcmd_base*> CommandIDToWMCMD;

// Initial position (used by command line flags)
REFERENCE_TIME rtShift;
Expand Down
9 changes: 9 additions & 0 deletions src/mpc-hc/CMPCThemeDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ CMPCThemeDialog::~CMPCThemeDialog()
IMPLEMENT_DYNAMIC(CMPCThemeDialog, CDialog)

BEGIN_MESSAGE_MAP(CMPCThemeDialog, CDialog)
ON_COMMAND_EX(IDOK, OnOK_EX)
ON_WM_CTLCOLOR()
ON_WM_HSCROLL()
END_MESSAGE_MAP()
Expand Down Expand Up @@ -56,3 +57,11 @@ void CMPCThemeDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
UpdateAnalogCaptureDeviceSlider(pScrollBar);
}
}

BOOL CMPCThemeDialog::OnOK_EX(UINT nId) {
if (ToolbarCustomizeDialog == specialCase) { //the toolbar customize dialog has assigned 1==IDOK to the "add" button, which CDialog interprets as `EndDialog(IDOK)`
return FALSE;
}
__super::OnOK();
return TRUE;
}
1 change: 1 addition & 0 deletions src/mpc-hc/CMPCThemeDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class CMPCThemeDialog :
DECLARE_MESSAGE_MAP()
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
BOOL PreTranslateMessage(MSG* pMsg);
virtual BOOL OnOK_EX(UINT nId);
private:
bool isDummy = false;
CMPCThemeUtil::SpecialThemeCases specialCase = NoSpecialCase;
Expand Down
26 changes: 22 additions & 4 deletions src/mpc-hc/CMPCThemeListBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
IMPLEMENT_DYNAMIC(CMPCThemeListBox, CListBox)

CMPCThemeListBox::CMPCThemeListBox()
:customizeToolBar(nullptr)
{
themedToolTipCid = (UINT_PTR) - 1;
themedSBHelper = nullptr;
Expand Down Expand Up @@ -42,27 +43,44 @@ void CMPCThemeListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
}
dc.Attach(lpDrawItemStruct->hDC);

int buttonID = (int16_t)LOWORD(lpDrawItemStruct->itemData);

CRect rc(lpDrawItemStruct->rcItem);

COLORREF crOldTextColor = dc.GetTextColor();
COLORREF crOldBkColor = dc.GetBkColor();

if ((lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED)) {
dc.SetTextColor(CMPCTheme::TextFGColor);
dc.SetBkColor(CMPCTheme::ContentSelectedColor);
dc.FillSolidRect(&lpDrawItemStruct->rcItem, CMPCTheme::ContentSelectedColor);
dc.FillSolidRect(&rc, CMPCTheme::ContentSelectedColor);
} else {
dc.SetTextColor(CMPCTheme::TextFGColor);
dc.SetBkColor(CMPCTheme::ContentBGColor);
dc.FillSolidRect(&lpDrawItemStruct->rcItem, CMPCTheme::ContentBGColor);
dc.FillSolidRect(&rc, CMPCTheme::ContentBGColor);
}

if (customizeToolBar) {
if (buttonID != -1) {
auto list = customizeToolBar->GetToolBarCtrl().GetImageList();
IMAGEINFO ii;
list->GetImageInfo(buttonID, &ii);
CRect rci(ii.rcImage);
int border = (rc.Height() - rci.Height()) / 2;
border = border < 0 ? 0 : border;
list->Draw(&dc, buttonID, rc.TopLeft() + CPoint(border, border), ILD_NORMAL);
}
rc.left += rc.Height();
}

lpDrawItemStruct->rcItem.left += 3;
rc.left += 3;

CString strText;
GetText(lpDrawItemStruct->itemID, strText);

CFont* font = GetFont();
CFont* pOldFont = dc.SelectObject(font);
dc.DrawTextW(strText, strText.GetLength(), &lpDrawItemStruct->rcItem, DT_VCENTER | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX);
dc.DrawTextW(strText, strText.GetLength(), &rc, DT_VCENTER | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX);

dc.SetTextColor(crOldTextColor);
dc.SetBkColor(crOldBkColor);
Expand Down
2 changes: 2 additions & 0 deletions src/mpc-hc/CMPCThemeListBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class CMPCThemeListBox :
CMPCThemeToolTipCtrl themedToolTip;
UINT_PTR themedToolTipCid;
CMPCThemeScrollBarHelper* themedSBHelper;
CToolBar* customizeToolBar;
protected:
virtual void PreSubclassWindow();
public:
Expand All @@ -31,5 +32,6 @@ class CMPCThemeListBox :
void setIntegralHeight();
afx_msg void OnSize(UINT nType, int cx, int cy);
void EnsureVisible(int index);
void SetCustomizeToolbar(CToolBar* tb) { customizeToolBar = tb; };
};

17 changes: 10 additions & 7 deletions src/mpc-hc/CMPCThemePPageBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,33 @@ BOOL CMPCThemePPageBase::OnInitDialog()
return 0;
}

void CMPCThemePPageBase::SetMPCThemeButtonIcon(UINT nIDButton, UINT nIDIcon, ImageGrayer::mpcColorStyle colorStyle)
void CMPCThemePPageBase::SetMPCThemeButtonIcon(UINT nIDButton, IconDef iconDef, ImageGrayer::mpcColorStyle colorStyle)
{
if (AppIsThemeLoaded()) {
if (!m_buttonIcons.count(nIDIcon)) {
if (!m_buttonIcons.count(iconDef)) {
CImage img, imgEnabled, imgDisabled;
img.LoadFromResource(AfxGetInstanceHandle(), nIDIcon);
if (iconDef.svgTargetWidth) {
SVGImage::LoadIconDef(iconDef, img);
} else {
img.LoadFromResource(AfxGetInstanceHandle(), iconDef.nIDIcon);
}

ImageGrayer::UpdateColor(img, imgEnabled, false, colorStyle);
ImageGrayer::UpdateColor(img, imgDisabled, true, colorStyle);

CImageList& imageList = m_buttonIcons[nIDIcon];
CImageList& imageList = m_buttonIcons[iconDef];
imageList.Create(img.GetWidth(), img.GetHeight(), ILC_COLOR32, 2, 0);
imageList.Add(CBitmap::FromHandle(imgEnabled), nullptr);
imageList.Add(CBitmap::FromHandle(imgDisabled), nullptr);
}

BUTTON_IMAGELIST buttonImageList;
buttonImageList.himl = m_buttonIcons[nIDIcon];
buttonImageList.himl = m_buttonIcons[iconDef];
buttonImageList.margin = { 0, 0, 0, 0 };
buttonImageList.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
static_cast<CButton*>(GetDlgItem(nIDButton))->SetImageList(&buttonImageList);
} else {
CPPageBase::SetButtonIcon(nIDButton, nIDIcon);

CPPageBase::SetButtonIcon(nIDButton, iconDef);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/mpc-hc/CMPCThemePPageBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CMPCThemePPageBase :
protected:
virtual BOOL OnInitDialog();
virtual void AdjustDynamicWidgets() {};
void SetMPCThemeButtonIcon(UINT nIDButton, UINT nIDIcon, ImageGrayer::mpcColorStyle colorStyle = ImageGrayer::mpcMono);
void SetMPCThemeButtonIcon(UINT nIDButton, IconDef iconDef, ImageGrayer::mpcColorStyle colorStyle = ImageGrayer::mpcMono);
BOOL PreTranslateMessage(MSG* pMsg);
CPPageBase* FindSiblingPage(CRuntimeClass* pClass);
};
Expand Down
15 changes: 11 additions & 4 deletions src/mpc-hc/CMPCThemePlayerListCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,13 +406,15 @@ void CMPCThemePlayerListCtrl::drawItem(CDC* pDC, int nItem, int nSubItem)
}

if (IsWindowEnabled()) {
bool selected = false;
if (GetItemState(nItem, LVIS_SELECTED) == LVIS_SELECTED && (nSubItem == 0 || fullRowSelect) && (GetStyle() & LVS_SHOWSELALWAYS || GetFocus() == this)) {
bgColor = selectedBGColor;
if (LVS_REPORT != dwStyle) { //in list mode we don't fill the "whole" column
CRect tmp = rText;
dcMem.DrawTextW(text, tmp, textFormat | DT_CALCRECT); //end of string
rTextBG.right = tmp.right + (rText.left - rTextBG.left); //end of string plus same indent from the left side
}
selected = true;
} else if (hasCheckedColors) {
if (isChecked && checkedBGClr != -1) {
bgColor = checkedBGClr;
Expand All @@ -426,11 +428,11 @@ void CMPCThemePlayerListCtrl::drawItem(CDC* pDC, int nItem, int nSubItem)
}
dcMem.FillSolidRect(rTextBG, bgColor);

if (themeGridLines || nullptr != customThemeInterface) {
if (themeGridLines || (nullptr != customThemeInterface && customThemeInterface->UseCustomGrid())) {
CRect rGrid = rect;
rGrid.bottom -= 1;
CPen gridPenV, gridPenH, *oldPen;
if (nullptr != customThemeInterface) {
if (nullptr != customThemeInterface && customThemeInterface->UseCustomGrid()) {
COLORREF horzGridColor, vertGridColor;
customThemeInterface->GetCustomGridColors(nItem, horzGridColor, vertGridColor);
gridPenV.CreatePen(PS_SOLID, 1, vertGridColor);
Expand All @@ -457,6 +459,11 @@ void CMPCThemePlayerListCtrl::drawItem(CDC* pDC, int nItem, int nSubItem)
dcMem.SelectObject(oldPen);
gridPenV.DeleteObject();
gridPenH.DeleteObject();
} else if (selected) {
CBrush borderBG;
borderBG.CreateSolidBrush(CMPCTheme::ListCtrlDisabledBGColor);
dcMem.FrameRect(rTextBG, &borderBG);
borderBG.DeleteObject();
}
}

Expand Down Expand Up @@ -533,7 +540,7 @@ BOOL CMPCThemePlayerListCtrl::OnEraseBkgnd(CDC* pDC)
}
pDC->FillSolidRect(r, CMPCTheme::ContentBGColor);

if (themeGridLines || nullptr != customThemeInterface) {
if (themeGridLines || (nullptr != customThemeInterface && customThemeInterface->UseCustomGrid())) {

CPen gridPen, *oldPen;
gridPen.CreatePen(PS_SOLID, 1, CMPCTheme::ListCtrlGridColor);
Expand All @@ -556,7 +563,7 @@ BOOL CMPCThemePlayerListCtrl::OnEraseBkgnd(CDC* pDC)
{
CPen horzPen;
pDC->MoveTo(r.left, gr.bottom - 1);
if (nullptr != customThemeInterface) {
if (nullptr != customThemeInterface && customThemeInterface->UseCustomGrid()) {
COLORREF horzGridColor, tmp;
customThemeInterface->GetCustomGridColors(y, horzGridColor, tmp);
horzPen.CreatePen(PS_SOLID, 1, horzGridColor);
Expand Down
1 change: 1 addition & 0 deletions src/mpc-hc/CMPCThemePlayerListCtrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CMPCThemeListCtrlCustomInterface
virtual void GetCustomTextColors(INT_PTR nItem, int iSubItem, COLORREF& clrText, COLORREF& clrTextBk, bool& overrideSelectedBG) = 0;
virtual void DoCustomPrePaint() = 0;
virtual void GetCustomGridColors(int nItem, COLORREF& horzGridColor, COLORREF& vertGridColor) = 0;
virtual bool UseCustomGrid() { return true; };
};

class CMPCThemePlayerListCtrl : public CListCtrl, CMPCThemeUtil, CMPCThemeScrollable
Expand Down
31 changes: 27 additions & 4 deletions src/mpc-hc/CMPCThemeUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,25 @@ CMPCThemeUtil::~CMPCThemeUtil()
}
}

void CMPCThemeUtil::subClassTBCustomizeDialog(CWnd* wnd, CToolBar* customizeToolBar)
{
CWnd* c = CWnd::FromHandle(themableDialogHandle);
CMPCThemeDialog* pObject = DEBUG_NEW CMPCThemeDialog();
pObject->SetSpecialCase(ToolbarCustomizeDialog);
makeThemed(pObject, c);
fulfillThemeReqs(c, ToolbarCustomizeDialog, customizeToolBar);

::RedrawWindow(themableDialogHandle, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_ERASE);

if (AfxGetAppSettings().bWindows10DarkThemeActive) {
enableWindows10DarkFrame(pObject);
//force titlebar redraw
c->SendMessage(WM_NCACTIVATE, FALSE);
c->SendMessage(WM_NCACTIVATE, TRUE);
}
}

void CMPCThemeUtil::fulfillThemeReqs(CWnd* wnd, SpecialThemeCases specialCase /* = 0 */)
void CMPCThemeUtil::fulfillThemeReqs(CWnd* wnd, SpecialThemeCases specialCase /* = 0 */, CWnd* otherWindow /* = nullptr */)
{
if (AppIsThemeLoaded()) {

Expand Down Expand Up @@ -129,6 +146,12 @@ void CMPCThemeUtil::fulfillThemeReqs(CWnd* wnd, SpecialThemeCases specialCase /*
} else if (0 == _tcsicmp(windowClass, WC_COMBOBOX)) {
CMPCThemeComboBox* pObject = DEBUG_NEW CMPCThemeComboBox();
makeThemed(pObject, tChild);
} else if (0 == _tcsicmp(windowClass, WC_LISTBOX)) {
CMPCThemeListBox* pObject = DEBUG_NEW CMPCThemeListBox();
makeThemed(pObject, tChild);
if (specialCase == ToolbarCustomizeDialog) {
pObject->SetCustomizeToolbar ((CToolBar*)otherWindow);
}
} else if (0 == _tcsicmp(windowClass, TRACKBAR_CLASS)) {
CMPCThemeSliderCtrl* pObject = DEBUG_NEW CMPCThemeSliderCtrl();
makeThemed(pObject, tChild);
Expand Down Expand Up @@ -274,16 +297,16 @@ void CMPCThemeUtil::subClassFileDialog(CWnd* wnd) {
if (AfxGetAppSettings().bWindows10DarkThemeActive) {
initHelperObjects();

HWND duiview = ::FindWindowExW(fileDialogHandle, NULL, L"DUIViewWndClassName", NULL);
HWND duiview = ::FindWindowExW(themableDialogHandle, NULL, L"DUIViewWndClassName", NULL);
HWND duihwnd = ::FindWindowExW(duiview, NULL, L"DirectUIHWND", NULL);

if (duihwnd) { //we found the FileDialog
if (dialogProminentControlStringID) { //if this is set, we assume there is a single prominent control (note, it's in the filedialog main window)
subClassFileDialogRecurse(wnd, fileDialogHandle, ProminentControlIDWidget);
subClassFileDialogRecurse(wnd, themableDialogHandle, ProminentControlIDWidget);
} else {
subClassFileDialogRecurse(wnd, duihwnd, RecurseSinkWidgets);
}
fileDialogHandle = nullptr;
themableDialogHandle = nullptr;
::RedrawWindow(duiview, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/mpc-hc/CMPCThemeUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class CMPCThemeUtil
NoSpecialCase = 0,
ExternalPropertyPageWithDefaultButton,
ExternalPropertyPageWithAnalogCaptureSliders,
ToolbarCustomizeDialog
};

enum WidgetPairType {
Expand All @@ -44,20 +45,21 @@ class CMPCThemeUtil
,ProminentControlIDWidget
};

HWND fileDialogHandle = nullptr;
HWND themableDialogHandle = nullptr;
void enableFileDialogHook();
void subClassFileDialogRecurse(CWnd* wnd, HWND hWnd, FileDialogWidgetSearch searchType);
void subClassFileDialog(CWnd* wnd);
void subClassFileDialogWidgets(HWND widget, HWND parent, wchar_t* childWindowClass);
void redrawAllThemedWidgets();
void subClassTBCustomizeDialog(CWnd* wnd, CToolBar* tb);
protected:
int dialogProminentControlStringID = 0;

static CBrush contentBrush, windowBrush, controlAreaBrush, W10DarkThemeFileDialogInjectedBGBrush;
static NONCLIENTMETRICS nonClientMetrics;
std::vector<CWnd*> allocatedWindows;

void fulfillThemeReqs(CWnd* wnd, SpecialThemeCases specialCase = SpecialThemeCases::NoSpecialCase);
void fulfillThemeReqs(CWnd* wnd, SpecialThemeCases specialCase = SpecialThemeCases::NoSpecialCase, CWnd* otherWindow = nullptr);
static void initHelperObjects();
void makeThemed(CWnd* pObject, CWnd* tChild);

Expand Down
18 changes: 17 additions & 1 deletion src/mpc-hc/ImageGrayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ bool ImageGrayer::UpdateColor(const CImage& imgSource, CImage& imgDest, bool dis
if (disabled) {
themeColor = CMPCTheme::ImageDisabledColor;
} else {
themeColor = CMPCTheme::TextFGColor;
themeColor = CMPCTheme::TextFGColorFade;
}
newColor.rgbRed = GetRValue(themeColor);
newColor.rgbGreen = GetGValue(themeColor);
Expand Down Expand Up @@ -286,3 +286,19 @@ bool ImageGrayer::Colorize(const CImage& imgSrc, CImage& imgDest, COLORREF fg, C

return true;
}

void ImageGrayer::PreMultiplyAlpha(CImage& imgSource) {
BYTE* bits = static_cast<BYTE*>(imgSource.GetBits());
for (int y = 0; y < imgSource.GetHeight(); y++, bits += imgSource.GetPitch()) {
RGBQUAD* p = reinterpret_cast<RGBQUAD*>(bits);
for (int x = 0; x < imgSource.GetWidth(); x++) {
HLS hls(p[x]);

RGBQUAD rgb = hls.toRGBQUAD();

p[x].rgbRed = static_cast<BYTE>(round((float)p[x].rgbRed * p[x].rgbReserved / 255.0f));
p[x].rgbBlue = static_cast<BYTE>(round((float)p[x].rgbBlue * p[x].rgbReserved / 255.0f));
p[x].rgbGreen = static_cast<BYTE>(round((float)p[x].rgbGreen * p[x].rgbReserved / 255.0f));
}
}
}
3 changes: 2 additions & 1 deletion src/mpc-hc/ImageGrayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ namespace ImageGrayer
enum mpcColorStyle {
classicGrayscale,
mpcMono,
mpcGrayDisabled
mpcGrayDisabled,
};

bool Gray(const CImage& imgSource, CImage& imgDest, float brightness = 1.0f);
bool UpdateColor(const CImage& imgSource, CImage& imgDest, bool disabled, mpcColorStyle colorStyle);
bool Colorize(const CImage& imgSource, CImage& imgDest, COLORREF fg, COLORREF bg, bool rot90);
void PreMultiplyAlpha(CImage& imgSource);
}
Loading