From 8593e7594773c30b35488bb6a45fcc782ed5df0c Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 20 Jul 2012 13:13:28 +0000 Subject: ModernOpt: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1081 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ModernOpt/src/mopt_selector.cpp | 385 ++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 plugins/ModernOpt/src/mopt_selector.cpp (limited to 'plugins/ModernOpt/src/mopt_selector.cpp') diff --git a/plugins/ModernOpt/src/mopt_selector.cpp b/plugins/ModernOpt/src/mopt_selector.cpp new file mode 100644 index 0000000000..42b15f51bb --- /dev/null +++ b/plugins/ModernOpt/src/mopt_selector.cpp @@ -0,0 +1,385 @@ +/* + +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 "modernopt.h" + +static void sttApplySkin(MODERNOPTOBJECT *obj, TCHAR *fn) +{ + char svc[128]; + mir_snprintf(svc, SIZEOF(svc), "%s%s", obj->lpzThemeModuleName, TS_SKIN_APPLY); + CallService(svc, NULL, (LPARAM)fn); +} + +static TCHAR *sttGetActiveSkin(MODERNOPTOBJECT *obj) +{ + char svc[128]; + mir_snprintf(svc, SIZEOF(svc), "%s%s", obj->lpzThemeModuleName, TS_SKIN_ACTIVE); + return ServiceExists(svc) ? (TCHAR *)CallService(svc, 0, 0) : 0; +} + +static void sttPreviewSkin(MODERNOPTOBJECT *obj, TCHAR *fn, LPDRAWITEMSTRUCT lps) +{ + if (!fn) return; + + char svc[128]; + mir_snprintf(svc, SIZEOF(svc), "%s%s", obj->lpzThemeModuleName, TS_SKIN_PREVIEW); + if (ServiceExists(svc)) + CallService(svc, (WPARAM)lps, (LPARAM)fn); + else { + char *afn = mir_t2a(fn); + char *fnpreview = (char *)mir_alloc(lstrlenA(afn) + 10); + lstrcpyA(fnpreview, afn); + lstrcatA(fnpreview, ".png"); + HBITMAP hbmPreview = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (LPARAM)fnpreview); + mir_free(afn); + mir_free(fnpreview); + + if (!hbmPreview) return; + + BITMAP bmp; + GetObject(hbmPreview, sizeof(bmp), &bmp); + + SIZE szDst = { abs(bmp.bmWidth), abs(bmp.bmHeight) }; + if ((szDst.cx > lps->rcItem.right-lps->rcItem.left) || (szDst.cy > lps->rcItem.bottom-lps->rcItem.top)) { + float q = min( + float(lps->rcItem.right-lps->rcItem.left) / szDst.cx, + float(lps->rcItem.bottom-lps->rcItem.top) / szDst.cy); + szDst.cx *= q; + szDst.cy *= q; + } + POINT ptDst = { + (lps->rcItem.left+lps->rcItem.right-szDst.cx) / 2, + (lps->rcItem.top+lps->rcItem.bottom-szDst.cy) / 2 }; + + HDC hdc = CreateCompatibleDC(lps->hDC); + SelectObject(hdc, hbmPreview); + SetStretchBltMode(hdc, HALFTONE); + StretchBlt(lps->hDC, ptDst.x, ptDst.y, szDst.cx, szDst.cy, hdc, 0, 0, abs(bmp.bmWidth), abs(bmp.bmHeight), SRCCOPY); + DeleteDC(hdc); + DeleteObject(hbmPreview); + } +} + +struct TSkinListItem +{ + TCHAR *path; + TCHAR *title; + TCHAR *filename; + + TSkinListItem(TCHAR *fn) + { + title = mir_tstrdup(fn); + if (TCHAR *p = _tcsrchr(title, _T('.'))) *p = 0; + + TCHAR curPath[MAX_PATH]; + GetCurrentDirectory(SIZEOF(curPath), curPath); + + path = (TCHAR *)mir_alloc(MAX_PATH * sizeof(TCHAR)); + CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)curPath, (LPARAM)path); + + int length = lstrlen(curPath)+lstrlen(fn)+2; + filename = (TCHAR *)mir_alloc(length * sizeof(TCHAR)); + mir_sntprintf(filename, length, _T("%s\\%s"), curPath, fn); + } + + ~TSkinListItem() + { + mir_free(path); + mir_free(title); + mir_free(filename); + } +}; + +struct TSelectorData +{ + MODERNOPTOBJECT *obj; + TCHAR *active; + HBITMAP hbmpPreview; + + TSelectorData() + { + ZeroMemory(this, sizeof(*this)); + } + ~TSelectorData() + { + mir_free(active); + DeleteObject(hbmpPreview); + } +}; + +static bool CheckExt(TCHAR *fn, TCHAR *ext, int n) +{ + int l = lstrlen(fn); + return (l > n) && !lstrcmp(fn + l - n, ext); +} + +static void BuildSkinList(HWND hwndList, TCHAR *szExt, int nExtLength = -1, bool start = true) +{ + if (start) { + static TCHAR mirPath[MAX_PATH]; + GetModuleFileName(NULL, mirPath, SIZEOF(mirPath)); + if (TCHAR *p = _tcsrchr(mirPath, _T('\\'))) *p = 0; + SetCurrentDirectory(mirPath); + SendMessage(hwndList, LB_RESETCONTENT, 0, 0); + nExtLength = lstrlen(szExt); + SendMessage(hwndList, WM_SETREDRAW, FALSE, 0); + } + + WIN32_FIND_DATA ffd = {0}; + HANDLE h = FindFirstFile(_T("*.*"), &ffd); + if (h != INVALID_HANDLE_VALUE) { + do { + if (!lstrcmp(ffd.cFileName, _T("")) || !lstrcmp(ffd.cFileName, _T(".")) || !lstrcmp(ffd.cFileName, _T(".."))) + continue; + + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + SetCurrentDirectory(ffd.cFileName); + BuildSkinList(hwndList, szExt, nExtLength, false); + SetCurrentDirectory(_T("..")); + } + else { + if (CheckExt(ffd.cFileName, szExt, nExtLength)) { + TSkinListItem *dat = new TSkinListItem(ffd.cFileName); + DWORD dwItem = SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)ffd.cFileName); + SendMessage(hwndList, LB_SETITEMDATA, dwItem, (LPARAM)dat); + } } + } + while (FindNextFile(h, &ffd)); + FindClose(h); + } + + if (start) { + SendMessage(hwndList, WM_SETREDRAW, TRUE, 0); + RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); + } +} + +static void CreatePreview(TSelectorData *sd, TCHAR *fn, LPDRAWITEMSTRUCT lps) +{ + HDC hdc = CreateCompatibleDC(lps->hDC); + sd->hbmpPreview = CreateCompatibleBitmap(lps->hDC, lps->rcItem.right - lps->rcItem.left, lps->rcItem.bottom - lps->rcItem.top); + SelectObject(hdc, sd->hbmpPreview); + + RECT rc; + HBRUSH hbr; + + BITMAPINFO bi = {0}; + bi.bmiHeader.biSize = sizeof(bi.bmiHeader); + bi.bmiHeader.biWidth = 8; + bi.bmiHeader.biHeight = -8; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + bi.bmiHeader.biCompression = BI_RGB; + + HBITMAP hBmpBrush = (HBITMAP)CreateDIBSection(0, &bi, DIB_RGB_COLORS, 0, 0, 0); + HDC dcBmp = CreateCompatibleDC(0); + HBITMAP hBmpSave = (HBITMAP)SelectObject(dcBmp, hBmpBrush); + hbr = CreateSolidBrush(RGB(0xcc, 0xcc, 0xcc)); + SetRect(&rc, 0, 0, 8, 8); + FillRect(dcBmp, &rc, hbr); + DeleteObject(hbr); + hbr = CreateSolidBrush(RGB(0xff, 0xff, 0xff)); + SetRect(&rc, 4, 0, 8, 4); + FillRect(dcBmp, &rc, hbr); + SetRect(&rc, 0, 4, 4, 8); + FillRect(dcBmp, &rc, hbr); + DeleteObject(hbr); + SelectObject(dcBmp, hBmpSave); + DeleteDC(dcBmp); + + rc = lps->rcItem; + OffsetRect(&rc, -rc.left, -rc.top); + hbr = CreatePatternBrush(hBmpBrush); + SetBrushOrgEx(hdc, 1, 1, 0); + FillRect(hdc, &rc, hbr); + DeleteObject(hbr); + DeleteObject(hBmpBrush); + + HDC hdcSave = lps->hDC; + lps->hDC = hdc; + sttPreviewSkin(sd->obj, fn, lps); + lps->hDC = hdcSave; + + FrameRect(hdc, &rc, GetStockBrush(LTGRAY_BRUSH)); + DeleteDC(hdc); +} + +INT_PTR CALLBACK ModernOptSelector_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TSelectorData *sd = (TSelectorData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + MODERNOPTOBJECT *&obj = sd->obj; + + switch (msg) { + case WM_INITDIALOG: + { + sd = new TSelectorData; + MODERNOPTOBJECT *&obj = sd->obj; + + sd->obj = (MODERNOPTOBJECT *)lParam; + sd->active = sttGetActiveSkin(obj); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)sd); + + TCHAR *s = mir_a2t(obj->lpzThemeExtension); + BuildSkinList(GetDlgItem(hwndDlg, IDC_SKINLIST), s); + mir_free(s); + } + return FALSE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDC_SKINLIST) { + switch (HIWORD(wParam)) { + case LBN_SELCHANGE: + DeleteObject(sd->hbmpPreview); + sd->hbmpPreview = 0; + RedrawWindow(GetDlgItem(hwndDlg, IDC_PREVIEW1), NULL, NULL, RDW_INVALIDATE); + break; + + case LBN_DBLCLK: + { + int idx = SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETCURSEL, 0, 0); + if (idx >= 0) + { + TSkinListItem *dat = (TSkinListItem *)SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETITEMDATA, idx, 0); + sttApplySkin(obj, dat->filename); + mir_free(sd->active); + sd->active = sttGetActiveSkin(obj); + RedrawWindow(GetDlgItem(hwndDlg, IDC_SKINLIST), NULL, NULL, RDW_INVALIDATE); + } + break; + } } + break; + } + return FALSE; + + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT lps = (LPMEASUREITEMSTRUCT)lParam; + if (lps->CtlID != IDC_SKINLIST) + break; + TSkinListItem *dat = (TSkinListItem *)lps->itemData; + if (!dat) break; + + lps->itemWidth = 10; + lps->itemHeight = 30; + + return FALSE; + } + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam; + if (lps->CtlID == IDC_SKINLIST) { + TSkinListItem *dat = (TSkinListItem *)lps->itemData; + if (!dat) break; + + SetBkMode(lps->hDC, TRANSPARENT); + COLORREF clLine1, clLine2, clBack; + if (lps->itemState & ODS_SELECTED) { + FillRect(lps->hDC, &lps->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); + clBack = GetSysColor(COLOR_HIGHLIGHT); + clLine1 = GetSysColor(COLOR_HIGHLIGHTTEXT); + } + else { + FillRect(lps->hDC, &lps->rcItem, GetSysColorBrush(COLOR_WINDOW)); + clBack = GetSysColor(COLOR_WINDOW); + clLine1 = GetSysColor(COLOR_WINDOWTEXT); + } + clLine2 = RGB( + GetRValue(clLine1) * 0.66 + GetRValue(clBack) * 0.34, + GetGValue(clLine1) * 0.66 + GetGValue(clBack) * 0.34, + GetBValue(clLine1) * 0.66 + GetBValue(clBack) * 0.34 + ); + + lps->rcItem.left += 2; + lps->rcItem.top += 2; + lps->rcItem.bottom -= 2; + lps->rcItem.right -= 5; + + int cxIcon = GetSystemMetrics(SM_CXSMICON); + int cyIcon = GetSystemMetrics(SM_CYSMICON); + + if (sd->active && !lstrcmp(sd->active, dat->filename)) { + DrawIconEx(lps->hDC, lps->rcItem.left, (lps->rcItem.top+lps->rcItem.bottom-cyIcon)/2, + LoadSkinnedIcon(SKINICON_OTHER_EMPTYBLOB), + cxIcon, cyIcon, 0, NULL, DI_NORMAL); + } + else { + DrawIconEx(lps->hDC, lps->rcItem.left, (lps->rcItem.top+lps->rcItem.bottom-cyIcon)/2, + LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT), + cxIcon, cyIcon, 0, NULL, DI_NORMAL); + } + lps->rcItem.left += cxIcon; + lps->rcItem.left += 5; + +// SelectObject(lps->hDC, dat->hfntTitle); + SetTextColor(lps->hDC, clLine1); + DrawText(lps->hDC, dat->title, -1, &lps->rcItem, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_END_ELLIPSIS|DT_TOP); + lps->rcItem.left += cxIcon; + + SetTextColor(lps->hDC, clLine2); + DrawText(lps->hDC, dat->path, -1, &lps->rcItem, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_PATH_ELLIPSIS|DT_BOTTOM); + } + else if (lps->CtlID == IDC_PREVIEW1) { + int idx = SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETCURSEL, 0, 0); + + if (!sd->hbmpPreview) { + if (idx >= 0) { + TSkinListItem *dat = (TSkinListItem *)SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETITEMDATA, idx, 0); + CreatePreview(sd, dat->filename, lps); + //sttPreviewSkin(obj, dat->filename, lps); + } + else CreatePreview(sd, NULL, lps); + } + + if (sd->hbmpPreview) { + HDC hdc = CreateCompatibleDC(lps->hDC); + SelectObject(hdc, sd->hbmpPreview); + BitBlt(lps->hDC, + lps->rcItem.left, lps->rcItem.top, + lps->rcItem.right - lps->rcItem.left, lps->rcItem.bottom - lps->rcItem.top, + hdc, 0, 0, SRCCOPY); + DeleteDC(hdc); + } + } + + return TRUE; + } + + case WM_DELETEITEM: + { + LPDELETEITEMSTRUCT lps = (LPDELETEITEMSTRUCT)lParam; + if (lps->CtlID != IDC_SKINLIST) break; + TSkinListItem *dat = (TSkinListItem *)lps->itemData; + if (dat) delete dat; + return FALSE; + } + + case WM_DESTROY: + delete sd; + return FALSE; + } + return FALSE; +} -- cgit v1.2.3