summaryrefslogtreecommitdiff
path: root/src/modules/options/headerbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/options/headerbar.cpp')
-rw-r--r--src/modules/options/headerbar.cpp372
1 files changed, 372 insertions, 0 deletions
diff --git a/src/modules/options/headerbar.cpp b/src/modules/options/headerbar.cpp
new file mode 100644
index 0000000000..a2407d2aab
--- /dev/null
+++ b/src/modules/options/headerbar.cpp
@@ -0,0 +1,372 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2007 Artem Shpynov
+Copyright 2000-2007 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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 2
+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, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "commonheaders.h"
+#include "m_iconheader.h"
+
+extern HINSTANCE hMirandaInst;
+
+
+static BOOL IsAeroMode()
+{
+ BOOL result;
+ return dwmIsCompositionEnabled && (dwmIsCompositionEnabled(&result) == S_OK) && result;
+}
+
+static BOOL IsVSMode()
+{
+ return isThemeActive && IsWinVerVistaPlus() && isThemeActive();
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Internals
+
+static LRESULT CALLBACK MHeaderbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// structure is used for storing list of tab info
+struct MHeaderbarCtrl
+{
+ __inline void* operator new( size_t size )
+ { return mir_calloc( size );
+ }
+ __inline void operator delete( void* p )
+ { mir_free( p );
+ }
+
+ MHeaderbarCtrl() {}
+ ~MHeaderbarCtrl() { mir_free( controlsToRedraw ); }
+
+ HWND hwnd;
+
+ // UI info
+ RECT rc;
+ int width, height;
+ HICON hIcon;
+
+ // control colors
+ RGBQUAD rgbBkgTop, rgbBkgBottom;
+ COLORREF clText;
+
+ int nControlsToRedraw;
+ HWND *controlsToRedraw;
+
+ // fonts
+ HFONT hFont;
+};
+
+int LoadHeaderbarModule()
+{
+ WNDCLASSEX wc;
+
+ ZeroMemory(&wc, sizeof(wc));
+ wc.cbSize = sizeof(wc);
+ wc.lpszClassName = _T("MHeaderbarCtrl"); //MIRANDAHEADERBARCLASS;
+ wc.lpfnWndProc = MHeaderbarWndProc;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.cbWndExtra = sizeof(MHeaderbarCtrl*);
+ wc.hbrBackground = 0; //GetStockObject(WHITE_BRUSH);
+ wc.style = CS_GLOBALCLASS|CS_SAVEBITS;
+ RegisterClassEx(&wc);
+ return 0;
+}
+
+static void MHeaderbar_SetupColors(MHeaderbarCtrl *dat)
+{
+ COLORREF cl;
+
+ cl = GetSysColor(COLOR_WINDOW);
+ dat->rgbBkgBottom.rgbRed = (dat->rgbBkgTop.rgbRed = GetRValue(cl)) * .95;
+ dat->rgbBkgBottom.rgbGreen = (dat->rgbBkgTop.rgbGreen = GetGValue(cl)) * .95;
+ dat->rgbBkgBottom.rgbBlue = (dat->rgbBkgTop.rgbBlue = GetBValue(cl)) * .95;
+
+ dat->clText = GetSysColor(COLOR_WINDOWTEXT);
+
+ if (!dat->hFont) dat->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+}
+
+static void MHeaderbar_FillRect(HDC hdc, int x, int y, int width, int height, COLORREF cl)
+{
+ int oldMode = SetBkMode(hdc, OPAQUE);
+ COLORREF oldColor = SetBkColor(hdc, cl);
+
+ RECT rc; SetRect(&rc, x, y, x+width, y+height);
+ ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0);
+
+ SetBkMode(hdc, oldMode);
+ SetBkColor(hdc, oldColor);
+}
+
+static void MHeaderbar_DrawGradient(HDC hdc, int x, int y, int width, int height, RGBQUAD *rgb0, RGBQUAD *rgb1)
+{
+ int i;
+
+ int oldMode = SetBkMode(hdc, OPAQUE);
+ COLORREF oldColor = SetBkColor(hdc, 0);
+
+ RECT rc; SetRect(&rc, x, 0, x+width, 0);
+ for (i=y+height; --i >= y; )
+ {
+ COLORREF color = RGB(
+ ((height-i-1)*rgb0->rgbRed + i*rgb1->rgbRed) / height,
+ ((height-i-1)*rgb0->rgbGreen + i*rgb1->rgbGreen) / height,
+ ((height-i-1)*rgb0->rgbBlue + i*rgb1->rgbBlue) / height);
+ rc.top = rc.bottom = i;
+ ++rc.bottom;
+ SetBkColor(hdc, color);
+ ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0);
+ }
+
+ SetBkMode(hdc, oldMode);
+ SetBkColor(hdc, oldColor);
+}
+
+static LRESULT MHeaderbar_OnPaint(HWND hwndDlg, MHeaderbarCtrl *mit, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int iTopSpace = IsAeroMode() ? 0 : 3;
+ PAINTSTRUCT ps;
+ HBITMAP hBmp, hOldBmp;
+
+ int titleLength = GetWindowTextLength(hwndDlg) + 1;
+ TCHAR *szTitle = (TCHAR *)mir_alloc(sizeof(TCHAR) * titleLength);
+ GetWindowText(hwndDlg, szTitle, titleLength);
+
+ TCHAR *szSubTitle = _tcschr(szTitle, _T('\n'));
+ if (szSubTitle) *szSubTitle++ = 0;
+
+ HDC hdc=BeginPaint(hwndDlg,&ps);
+ HDC tempDC=CreateCompatibleDC(hdc);
+
+ BITMAPINFO bmi;
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = mit->width;
+ bmi.bmiHeader.biHeight = -mit->height; // we need this for DrawThemeTextEx
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ hBmp = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
+
+ hOldBmp=(HBITMAP)SelectObject(tempDC,hBmp);
+
+ if (IsAeroMode()) {
+ RECT temprc;
+ temprc.left=0;
+ temprc.right=mit->width;
+ temprc.top=0;
+ temprc.bottom=mit->width;
+ FillRect(tempDC, &temprc, (HBRUSH)GetStockObject(BLACK_BRUSH));
+
+ MARGINS margins = {0,0,mit->height,0};
+ dwmExtendFrameIntoClientArea(GetParent(hwndDlg), &margins);
+
+ WTA_OPTIONS opts;
+ opts.dwFlags = opts.dwMask = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON;
+ setWindowThemeAttribute(GetParent(hwndDlg), WTA_NONCLIENT, &opts, sizeof(opts));
+ }
+ else {
+ if (IsVSMode())
+ MHeaderbar_FillRect(tempDC, 0, 0, mit->width, mit->height, GetSysColor(COLOR_WINDOW));
+ else
+ MHeaderbar_DrawGradient(tempDC, 0, 0, mit->width, mit->height, &mit->rgbBkgTop, &mit->rgbBkgBottom);
+
+ MHeaderbar_FillRect(tempDC, 0, mit->height-2, mit->width, 1, GetSysColor(COLOR_BTNSHADOW));
+ MHeaderbar_FillRect(tempDC, 0, mit->height-1, mit->width, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
+ }
+
+ HFONT hFont = mit->hFont;
+ SetBkMode(tempDC, TRANSPARENT);
+ SetTextColor(tempDC, mit->clText);
+
+ LOGFONT lf;
+ GetObject(hFont, sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ HFONT hFntBold = CreateFontIndirect(&lf);
+
+ if (mit->hIcon)
+ DrawIcon(tempDC, 10, iTopSpace, mit->hIcon);
+ else {
+ HICON hIcon = (HICON)SendMessage(GetParent(hwndDlg), WM_GETICON, ICON_BIG, 0);
+ if (hIcon == NULL)
+ hIcon = (HICON)SendMessage(GetParent(hwndDlg), WM_GETICON, ICON_SMALL, 0);
+ DrawIcon(tempDC, 10, iTopSpace, hIcon);
+ }
+
+ RECT textRect;
+ textRect.left=50;
+ textRect.right=mit->width;
+ textRect.top=2 + iTopSpace;
+ textRect.bottom=GetSystemMetrics(SM_CYICON)-2 + iTopSpace;
+
+ if (IsAeroMode()) {
+ DTTOPTS dto = {0};
+ dto.dwSize = sizeof(dto);
+ dto.dwFlags = DTT_COMPOSITED|DTT_GLOWSIZE;
+ dto.iGlowSize = 10;
+
+ HANDLE hTheme = openThemeData(hwndDlg, L"Window");
+ textRect.left=50;
+ SelectObject(tempDC, hFntBold);
+
+ wchar_t *szTitleW = mir_t2u(szTitle);
+ drawThemeTextEx(hTheme, tempDC, WP_CAPTION, CS_ACTIVE, szTitleW, -1, DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX|DT_NOCLIP|DT_END_ELLIPSIS, &textRect, &dto);
+ mir_free(szTitleW);
+
+ if (szSubTitle) {
+ textRect.left=66;
+ SelectObject(tempDC, hFont);
+
+ wchar_t *szSubTitleW = mir_t2u(szSubTitle);
+ drawThemeTextEx(hTheme, tempDC, WP_CAPTION, CS_ACTIVE, szSubTitleW, -1, DT_BOTTOM|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX|DT_NOCLIP|DT_END_ELLIPSIS, &textRect, &dto);
+ mir_free(szSubTitleW);
+ }
+ closeThemeData(hTheme);
+ }
+ else {
+ textRect.left=50;
+ SelectObject(tempDC, hFntBold);
+ DrawText(tempDC, szTitle, -1, &textRect, DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX|DT_NOCLIP|DT_END_ELLIPSIS);
+
+ if (szSubTitle) {
+ textRect.left=66;
+ SelectObject(tempDC, hFont);
+ DrawText(tempDC, szSubTitle, -1, &textRect, DT_BOTTOM|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX|DT_NOCLIP|DT_END_ELLIPSIS);
+ } }
+
+ DeleteObject(hFntBold);
+
+ mir_free(szTitle);
+
+ //Copy to output
+ if (mit->nControlsToRedraw)
+ {
+ RECT temprc;
+ temprc.left=0;
+ temprc.right=mit->width;
+ temprc.top=0;
+ temprc.bottom=mit->width;
+ HRGN hRgn = CreateRectRgnIndirect(&temprc);
+
+ for (int i = 0; i < mit->nControlsToRedraw; ++i)
+ {
+ GetWindowRect(mit->controlsToRedraw[i], &temprc);
+ MapWindowPoints(NULL, hwndDlg, (LPPOINT)&temprc, 2);
+ HRGN hRgnTmp = CreateRectRgnIndirect(&temprc);
+ CombineRgn(hRgn, hRgn, hRgnTmp, RGN_DIFF);
+ DeleteObject(hRgnTmp);
+ }
+ SelectClipRgn(hdc,hRgn);
+ DeleteObject(hRgn);
+ }
+
+ BitBlt(hdc,mit->rc.left,mit->rc.top,mit->width,mit->height,tempDC,0,0,SRCCOPY);
+
+ SelectClipRgn(hdc,NULL);
+
+ SelectObject(tempDC,hOldBmp);
+ DeleteObject(hBmp);
+ DeleteDC(tempDC);
+
+ EndPaint(hwndDlg,&ps);
+
+ return TRUE;
+}
+
+static LRESULT CALLBACK MHeaderbarWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ MHeaderbarCtrl* itc = (MHeaderbarCtrl *)GetWindowLongPtr(hwndDlg, 0);
+ switch(msg) {
+ case WM_NCCREATE:
+ itc = new MHeaderbarCtrl; //(MHeaderbarCtrl*)mir_alloc(sizeof(MHeaderbarCtrl));
+ if (itc==NULL)
+ return FALSE;
+
+ SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)itc);
+ MHeaderbar_SetupColors(itc);
+
+ { HWND hParent = GetParent(hwndDlg);
+ RECT rcWnd; GetWindowRect(hwndDlg, &rcWnd);
+ itc->controlsToRedraw = 0;
+ itc->nControlsToRedraw = 0;
+ for (HWND hChild = FindWindowEx(hParent, NULL, NULL, NULL); hChild; hChild = FindWindowEx(hParent, hChild, NULL, NULL))
+ {
+ if (hChild != hwndDlg)
+ {
+ RECT rcChild; GetWindowRect(hChild, &rcChild);
+ RECT rc;
+ IntersectRect(&rc, &rcChild, &rcWnd);
+ if (!IsRectEmpty(&rc))
+ {
+ ++itc->nControlsToRedraw;
+ itc->controlsToRedraw = (HWND *)mir_realloc(itc->controlsToRedraw, sizeof(HWND) * itc->nControlsToRedraw);
+ itc->controlsToRedraw[itc->nControlsToRedraw - 1] = hChild;
+ }
+ }
+ }
+ }
+
+ break;
+
+ case WM_SETFONT:
+ itc->hFont = (HFONT)wParam;
+ break;
+
+ case WM_SIZE:
+ GetClientRect(hwndDlg,&itc->rc);
+ itc->width=itc->rc.right-itc->rc.left;
+ itc->height=itc->rc.bottom-itc->rc.top;
+ return TRUE;
+
+ case WM_THEMECHANGED:
+ case WM_STYLECHANGED:
+ MHeaderbar_SetupColors(itc);
+ return TRUE;
+
+ case WM_LBUTTONDOWN:
+ SendMessage(GetParent(hwndDlg), WM_SYSCOMMAND, 0xF012, 0);
+ return 0;
+
+ case WM_SETICON:
+ if (wParam < 3) {
+ itc->hIcon = (HICON)lParam;
+ InvalidateRect(hwndDlg, NULL, FALSE);
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ return 1;
+
+ case WM_NCPAINT:
+ InvalidateRect(hwndDlg, NULL, FALSE);
+ break;
+
+ case WM_PAINT:
+ MHeaderbar_OnPaint(hwndDlg, itc, msg, wParam, lParam);
+ break;
+
+ case WM_DESTROY:
+ delete itc;
+ break;
+ }
+ return DefWindowProc(hwndDlg, msg, wParam, lParam);
+}