summaryrefslogtreecommitdiff
path: root/src/modules/options/descbutton.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /src/modules/options/descbutton.cpp
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/modules/options/descbutton.cpp')
-rw-r--r--src/modules/options/descbutton.cpp332
1 files changed, 332 insertions, 0 deletions
diff --git a/src/modules/options/descbutton.cpp b/src/modules/options/descbutton.cpp
new file mode 100644
index 0000000000..2e5d55c7a4
--- /dev/null
+++ b/src/modules/options/descbutton.cpp
@@ -0,0 +1,332 @@
+/*
+
+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_descbutton.h"
+
+extern HINSTANCE hMirandaInst;
+
+////////////////////////////////////////////////////////////////////////////////////
+// Internals
+
+#define DBC_BORDER_SIZE 7
+#define DBC_VSPACING 15
+#define DBC_HSPACING 10
+
+static LRESULT CALLBACK MDescButtonWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// structure is used for storing list of tab info
+typedef struct {
+ HWND hwnd;
+ BOOL bSharedIcon;
+ HICON hIcon;
+ TCHAR *lpzTitle;
+ TCHAR *lpzDescription;
+
+ // UI info
+ BOOL bMouseInside;
+ RECT rc;
+ int width, height;
+ HFONT hfntTitle;
+
+ // control colors
+ RGBQUAD rgbBkgTop, rgbBkgBottom;
+ RGBQUAD rgbSelTop, rgbSelBottom;
+ RGBQUAD rgbHotTop, rgbHotBottom;
+ COLORREF clText, clBackground;
+ COLORREF clSelText, clSelBorder;
+ COLORREF clHotText, clHotBorder;
+
+ // fonts
+ HFONT hFont;
+} MDescButtonCtrl;
+
+int LoadDescButtonModule()
+{
+ WNDCLASSEX wc;
+
+ ZeroMemory(&wc, sizeof(wc));
+ wc.cbSize = sizeof(wc);
+ wc.lpszClassName = MIRANDADESCBUTTONCLASS;
+ wc.lpfnWndProc = MDescButtonWndProc;
+ wc.hCursor = LoadCursor(NULL, IDC_HAND);
+ wc.cbWndExtra = sizeof(MDescButtonCtrl *);
+ wc.hbrBackground = 0; //GetStockObject(WHITE_BRUSH);
+ wc.style = CS_GLOBALCLASS|CS_SAVEBITS;
+ RegisterClassEx(&wc);
+ return 0;
+}
+
+static void MDescButton_SetupColors(MDescButtonCtrl *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;
+
+ cl = GetSysColor(COLOR_HIGHLIGHT);
+ dat->rgbSelTop.rgbRed = (dat->rgbSelBottom.rgbRed = GetRValue(cl)) * .75;
+ dat->rgbSelTop.rgbGreen = (dat->rgbSelBottom.rgbGreen = GetGValue(cl)) * .75;
+ dat->rgbSelTop.rgbBlue = (dat->rgbSelBottom.rgbBlue = GetBValue(cl)) * .75;
+
+ dat->rgbHotTop.rgbRed = (dat->rgbSelTop.rgbRed + 255) / 2;
+ dat->rgbHotTop.rgbGreen = (dat->rgbSelTop.rgbGreen + 255) / 2;
+ dat->rgbHotTop.rgbBlue = (dat->rgbSelTop.rgbBlue + 255) / 2;
+
+ dat->rgbHotBottom.rgbRed = (dat->rgbSelBottom.rgbRed + 255) / 2;
+ dat->rgbHotBottom.rgbGreen = (dat->rgbSelBottom.rgbGreen + 255) / 2;
+ dat->rgbHotBottom.rgbBlue = (dat->rgbSelBottom.rgbBlue + 255) / 2;
+
+ dat->clBackground = GetSysColor(COLOR_3DFACE);
+ dat->clText = GetSysColor(COLOR_WINDOWTEXT);
+ dat->clSelText = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ dat->clSelBorder = RGB(dat->rgbSelTop.rgbRed, dat->rgbSelTop.rgbGreen, dat->rgbSelTop.rgbBlue);
+ dat->clHotBorder = RGB(dat->rgbHotTop.rgbRed, dat->rgbHotTop.rgbGreen, dat->rgbHotTop.rgbBlue);
+
+ if (!dat->hFont) dat->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+}
+
+static void MDescButton_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 MDescButton_DrawGradient(HDC hdc, int x, int y, int width, int height, RGBQUAD *rgb0, RGBQUAD *rgb1)
+{
+ int oldMode = SetBkMode(hdc, OPAQUE);
+ COLORREF oldColor = SetBkColor(hdc, 0);
+
+ RECT rc; SetRect(&rc, x, 0, x+width, 0);
+ for (int 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 MDescButton_OnPaint(HWND hwndDlg, MDescButtonCtrl *dat, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ PAINTSTRUCT ps;
+ HBITMAP hBmp, hOldBmp;
+ RECT temprc;
+ HFONT hfntSave;
+
+ HDC hdc=BeginPaint(hwndDlg,&ps);
+ HDC tempDC=CreateCompatibleDC(hdc);
+
+ SIZE titleSize = {0};
+
+ hBmp=CreateCompatibleBitmap(hdc,dat->width, dat->height);
+ hOldBmp=(HBITMAP)SelectObject(tempDC,hBmp);
+
+ temprc.left=0;
+ temprc.right=dat->width;
+ temprc.top=0;
+
+ //Draw background
+ if (dat->bMouseInside || (GetFocus() == hwndDlg)) {
+ MDescButton_FillRect(tempDC, 0, 0, dat->width, dat->height, dat->clSelBorder);
+ MDescButton_DrawGradient(tempDC, 1, 1, dat->width-2, dat->height-2, &dat->rgbSelTop, &dat->rgbSelBottom);
+ SetTextColor(tempDC, dat->clSelText);
+ }
+ else {
+ MDescButton_FillRect(tempDC, 0, 0, dat->width, dat->height, dat->clBackground);
+ SetTextColor(tempDC, dat->clText);
+ }
+
+ if (dat->hIcon)
+ DrawIcon(tempDC, DBC_BORDER_SIZE, DBC_BORDER_SIZE, dat->hIcon);
+
+ hfntSave = (HFONT)SelectObject(tempDC, dat->hFont);
+ SetBkMode(tempDC, TRANSPARENT);
+
+ if (dat->lpzTitle) {
+ LOGFONT lf;
+ RECT textRect;
+ HFONT hfntSave;
+
+ GetObject(dat->hFont, sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ lf.lfHeight *= 1.5;
+ hfntSave = (HFONT)SelectObject(tempDC, CreateFontIndirect(&lf));
+
+ textRect.left = DBC_BORDER_SIZE + dat->hIcon ? 32 + DBC_VSPACING : 0;
+ textRect.right = dat->width - DBC_BORDER_SIZE;
+ textRect.top = DBC_BORDER_SIZE;
+ textRect.bottom = dat->height - DBC_BORDER_SIZE;
+ DrawText(tempDC, dat->lpzTitle, -1, &textRect, DT_TOP|DT_LEFT|DT_END_ELLIPSIS);
+ GetTextExtentPoint32(tempDC, dat->lpzTitle, lstrlen(dat->lpzTitle), &titleSize);
+
+ DeleteObject(SelectObject(tempDC, hfntSave));
+ }
+
+ if (dat->lpzDescription) {
+ RECT textRect;
+ textRect.left = DBC_BORDER_SIZE + dat->hIcon ? 32 + DBC_VSPACING : 0;
+ textRect.right = dat->width - DBC_BORDER_SIZE;
+ textRect.top = DBC_BORDER_SIZE + titleSize.cy ? titleSize.cy + DBC_HSPACING : 0;
+ textRect.bottom = dat->height - DBC_BORDER_SIZE;
+ DrawText(tempDC, dat->lpzDescription, -1, &textRect, DT_TOP|DT_LEFT|DT_WORDBREAK|DT_END_ELLIPSIS);
+ GetTextExtentPoint32(tempDC, dat->lpzTitle, lstrlen(dat->lpzTitle), &titleSize);
+ }
+
+ SelectObject(tempDC, hfntSave);
+
+ //Copy to output
+ BitBlt(hdc,dat->rc.left,dat->rc.top,dat->width,dat->height,tempDC,0,0,SRCCOPY);
+ SelectObject(tempDC,hOldBmp);
+ DeleteObject(hBmp);
+ DeleteDC(tempDC);
+ EndPaint(hwndDlg,&ps);
+
+ return TRUE;
+}
+
+static LRESULT CALLBACK MDescButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ MDescButtonCtrl *dat = (MDescButtonCtrl *)GetWindowLongPtr(hwndDlg, 0);
+ switch(msg) {
+ case WM_NCCREATE:
+ dat = (MDescButtonCtrl*)mir_alloc(sizeof(MDescButtonCtrl));
+ if (dat==NULL)
+ return FALSE;
+
+ memset(dat, 0, sizeof(MDescButtonCtrl));
+ SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)dat);
+ MDescButton_SetupColors(dat);
+ return TRUE;
+
+ case WM_SETFONT:
+ dat->hFont = (HFONT)wParam;
+ break;
+
+ case WM_SIZE:
+ GetClientRect(hwndDlg,&dat->rc);
+ dat->width=dat->rc.right-dat->rc.left;
+ dat->height=dat->rc.bottom-dat->rc.top;
+ return TRUE;
+
+ case WM_THEMECHANGED:
+ case WM_STYLECHANGED:
+ MDescButton_SetupColors(dat);
+ return TRUE;
+
+ case WM_MOUSEMOVE:
+ if (!dat->bMouseInside) {
+ TRACKMOUSEEVENT tme = {0};
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwndDlg;
+ _TrackMouseEvent(&tme);
+ dat->bMouseInside = TRUE;
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE);
+ }
+ return 0;
+
+ case WM_MOUSELEAVE:
+ dat->bMouseInside = FALSE;
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE);
+ return 0;
+
+ case WM_LBUTTONUP:
+ SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwndDlg, GWL_ID), 0), 0);
+ return 0;
+
+ case WM_ERASEBKGND:
+ return 1;
+
+ case WM_NCPAINT:
+ InvalidateRect(hwndDlg, NULL, FALSE);
+ break;
+
+ case WM_PAINT:
+ MDescButton_OnPaint(hwndDlg, dat, msg, wParam, lParam);
+ break;
+
+ case DBCM_SETTITLE:
+ if (dat->lpzTitle)
+ mir_free(dat->lpzTitle);
+ if (wParam & MDBCF_UNICODE)
+ dat->lpzTitle = mir_u2t((WCHAR *)lParam);
+ else
+ dat->lpzTitle = mir_a2t((char *)lParam);
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE);
+ return TRUE;
+
+ case DBCM_SETDESCRIPTION:
+ if (dat->lpzDescription)
+ mir_free(dat->lpzDescription);
+ if (wParam & MDBCF_UNICODE)
+ dat->lpzDescription = mir_u2t((WCHAR *)lParam);
+ else
+ dat->lpzDescription = mir_a2t((char *)lParam);
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE);
+ return TRUE;
+
+ case DBCM_SETICON:
+ if (dat->hIcon && !dat->bSharedIcon)
+ DestroyIcon(dat->hIcon);
+
+ if (wParam & MDBCF_SHAREDICON) {
+ dat->bSharedIcon = TRUE;
+ dat->hIcon = (HICON)lParam;
+ }
+ else {
+ dat->bSharedIcon = FALSE;
+ dat->hIcon = CopyIcon((HICON)lParam);
+ }
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE);
+ return TRUE;
+
+ case WM_DESTROY:
+ if (dat->lpzTitle)
+ mir_free(dat->lpzTitle);
+ if (dat->lpzDescription)
+ mir_free(dat->lpzDescription);
+ if (dat->hIcon && !dat->bSharedIcon)
+ DestroyIcon(dat->hIcon);
+ mir_free(dat);
+ return TRUE;
+ }
+
+ return DefWindowProc(hwndDlg, msg, wParam, lParam);
+}