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/commonheaders.h | 79 ++++ plugins/ModernOpt/src/main.cpp | 54 +++ plugins/ModernOpt/src/modernopt.cpp | 696 ++++++++++++++++++++++++++++++++ plugins/ModernOpt/src/modernopt.h | 53 +++ plugins/ModernOpt/src/mopt_home.cpp | 80 ++++ plugins/ModernOpt/src/mopt_ignore.cpp | 61 +++ plugins/ModernOpt/src/mopt_selector.cpp | 385 ++++++++++++++++++ plugins/ModernOpt/src/resource.h | 36 ++ 8 files changed, 1444 insertions(+) create mode 100644 plugins/ModernOpt/src/commonheaders.h create mode 100644 plugins/ModernOpt/src/main.cpp create mode 100644 plugins/ModernOpt/src/modernopt.cpp create mode 100644 plugins/ModernOpt/src/modernopt.h create mode 100644 plugins/ModernOpt/src/mopt_home.cpp create mode 100644 plugins/ModernOpt/src/mopt_ignore.cpp create mode 100644 plugins/ModernOpt/src/mopt_selector.cpp create mode 100644 plugins/ModernOpt/src/resource.h (limited to 'plugins/ModernOpt/src') diff --git a/plugins/ModernOpt/src/commonheaders.h b/plugins/ModernOpt/src/commonheaders.h new file mode 100644 index 0000000000..2d133a802e --- /dev/null +++ b/plugins/ModernOpt/src/commonheaders.h @@ -0,0 +1,79 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2008 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. +*/ + +// to enable all 0.8.0 core functions +#define MIRANDA_VER 0x0A00 + +#define WINVER 0x0501 +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0501 + +#define _CRT_SECURE_NO_WARNINGS +#define CINTERFACE + +#include "m_stdhdr.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "resource.h" diff --git a/plugins/ModernOpt/src/main.cpp b/plugins/ModernOpt/src/main.cpp new file mode 100644 index 0000000000..c11f8349f9 --- /dev/null +++ b/plugins/ModernOpt/src/main.cpp @@ -0,0 +1,54 @@ +#include "commonheaders.h" + + +HINSTANCE hInst; +int hLangpack; + +PLUGININFOEX pluginInfoEx = { + sizeof(PLUGININFOEX), + "Support for new options design", + PLUGIN_MAKE_VERSION(0,1,0,0), + "Support for new options design.", + "Victor Pavlychko, George Hazan", + "ghazan@miranda-im.org", + "é 2009 Victor Pavlychko, George Hazan", + "http://www.miranda-im.org", + UNICODE_AWARE, + { 0x621f886b, 0xa7f6, 0x457f, { 0x9d, 0x62, 0x8e, 0xe8, 0x4c, 0x27, 0x59, 0x93 }} // {621f886b-a7f6-457f-9d62-8ee84c275993} +}; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// MirandaPluginInfoEx - returns an information about a plugin + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfoEx; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Performs a primary set of actions upon plugin loading + +int LoadModernOptsModule(); + +extern "C" int __declspec(dllexport) Load(void) +{ + + mir_getLP(&pluginInfoEx); + + LoadModernOptsModule(); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Unload a plugin + +extern "C" int __declspec(dllexport) Unload(void) +{ + return 0; +} diff --git a/plugins/ModernOpt/src/modernopt.cpp b/plugins/ModernOpt/src/modernopt.cpp new file mode 100644 index 0000000000..1345631268 --- /dev/null +++ b/plugins/ModernOpt/src/modernopt.cpp @@ -0,0 +1,696 @@ +/* + +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" +#include "../../../src/resource.h" + +//#define MOPT_SAMPLE_PAGES + +extern HMODULE hInst; + +static HANDLE hevtModernOpt_Initialize = 0; + +static HWND hwndModernOpt = NULL; +static INT_PTR CALLBACK ModernOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +struct ModernOptionsObject +{ + MODERNOPTOBJECT optObject; + + HWND hwnd; + BOOL bChanged; + DWORD dwFlags; + int iTreeImageIndex; + DWORD dwIdx; +}; + +static DWORD g_dwIdx = 0; +static int g_iSectionRestore = 0; + +static int ModernOptionsObject_Comparator(const ModernOptionsObject *ptr1, const ModernOptionsObject *ptr2); + +struct ModernOptionsData +{ + __inline void* operator new( size_t size ) + { return calloc( 1, size ); + } + __inline void operator delete( void* p ) + { free( p ); + } + + ModernOptionsData(): pObjectList(1, ModernOptionsObject_Comparator) {} + + LIST pObjectList; + HFONT hfntBold; + int iPage, iSection; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Forwards +static INT_PTR svcModernOpt_Show(WPARAM wParam, LPARAM lParam); +static INT_PTR svcModernOpt_Restore(WPARAM wParam, LPARAM lParam); +static INT_PTR svcModernOpt_SelectPage(WPARAM wParam, LPARAM lParam); +static INT_PTR svcModernOpt_AddObject(WPARAM wParam, LPARAM lParam); +static int hookModernOpt_Initialize(WPARAM wParam, LPARAM lParam); + +static void ModernOptUI_ShowPage(HWND hwndDlg, struct ModernOptionsData *dat, int iPage); +static void ModernOptUI_SelectSection(HWND hwndDlg, struct ModernOptionsData *dat, int iSection); + +//////////////////////////////////////////////////////////////////////////////// +// Main option pages +struct ModernOptMainPageInfo g_ModernOptPages[MODERNOPT_PAGE_COUNT] = +{ + {0, FALSE, IDI_MIRANDA, _T("Home"), _T("Miranda IM configuration center")}, + {IDC_BTN_ACCOUNTS, TRUE, IDI_BIG_NETWORK, _T("Accounts"), _T("Setup your account information to start messaging.")}, + {IDC_BTN_SKINS, TRUE, IDI_BIG_SKINS, _T("Style"), _T("Change the look of Miranda IM according to your taste.")}, + {IDC_BTN_CLIST, TRUE, IDI_BIG_BUDDYLIST, _T("Contacts"), _T("Configure behaviour of your contact list.")}, + {IDC_BTN_MESSAGING, TRUE, IDI_BIG_MESSAGE, _T("Chats"), _T("Customize look&&feel of your chat windows here.")}, + {IDC_BTN_IGNORE, TRUE, IDI_BIG_IGNORE, _T("Ignore"), _T("Ban those users and events, you are annoyed with.")}, + {IDC_BTN_STATUS, TRUE, IDI_BIG_STATUS, _T("Status"), _T("Set your status messages and idle reporting.")}, + {IDC_BTN_ADVANCED, TRUE, IDI_BIG_ADVANCED, _T("Advanced"), _T("")}, + {IDC_BTN_PLUGINS, TRUE, IDI_BIG_MODULES, _T("Addons"), _T("Miranda IM is all about plugins. Manage all the plugins you have here.")}, +}; + +//////////////////////////////////////////////////////////////////////////////// +// Utilities +typedef void (*ItemDestuctor)(void *); + +static void ModernOptionsObject_Dtor(void *ptr) +{ + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)ptr; + + mir_free(obj->optObject.lptzSubsection); + mir_free(obj->optObject.iBoldControls); + mir_free(obj->optObject.lpzClassicGroup); + mir_free(obj->optObject.lpzClassicPage); + mir_free(obj->optObject.lpzClassicTab); + mir_free(obj->optObject.lpzHelpUrl); + mir_free(obj->optObject.lpzThemeExtension); + mir_free(obj->optObject.lpzThemeModuleName); + + switch (obj->optObject.iType) + { + case MODERNOPT_TYPE_IGNOREOBJECT: + mir_free(obj->optObject.lpzIgnoreModule); + mir_free(obj->optObject.lpzIgnoreSetting); + break; + } + + if (obj->hwnd) DestroyWindow(obj->hwnd); + mir_free(obj); +} + +static int ModernOptionsObject_Comparator(const ModernOptionsObject *ptr1, const ModernOptionsObject *ptr2) +{ +#define obj1 ((struct ModernOptionsObject *)ptr1) +#define obj2 ((struct ModernOptionsObject *)ptr2) + + if (obj1->optObject.iSection < obj2->optObject.iSection) return -1; + if (obj1->optObject.iSection > obj2->optObject.iSection) return +1; + + if (obj1->optObject.iType < obj2->optObject.iType) return -1; + if (obj1->optObject.iType > obj2->optObject.iType) return +1; + + if (obj1->optObject.lptzSubsection && obj2->optObject.lptzSubsection) + { + int c = lstrcmp(obj1->optObject.lptzSubsection, obj2->optObject.lptzSubsection); + if (c) return c; + } + + if (obj1->dwIdx < obj2->dwIdx) return -1; + if (obj1->dwIdx > obj2->dwIdx) return +1; + return 0; + +#undef obj1 +#undef obj2 +} + +void li_List_Destruct(LIST &pList, ItemDestuctor pItemDestructor) +{ + int i=0; + for (i=0; ipObjectList.getCount(); ++i) + { + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i]; + if (obj->hwnd && obj->bChanged) + { + obj->bChanged = FALSE; + pshn.hdr.hwndFrom = obj->hwnd; + SendMessage(obj->hwnd, WM_NOTIFY, 0, (LPARAM)&pshn); + } + } +} + +static INT_PTR CALLBACK ModernOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + struct ModernOptionsData *dat = (struct ModernOptionsData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + int i; + HWND hwndCtrl; + + switch (msg) { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + HIMAGELIST himl = 0; + + dat = (struct ModernOptionsData *)lParam; + dat->iPage = -1; + + LOGFONT lf; + dat->hfntBold = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0); + GetObject(dat->hfntBold, sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + dat->hfntBold = CreateFontIndirect(&lf); + + hwndCtrl = GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS); + himl = ImageList_Create(16, 16, ILC_MASK + ( IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16 ), 2, 1); + TreeView_SetImageList(hwndCtrl, himl, TVSIL_NORMAL); + + for (i = 0; i < dat->pObjectList.getCount(); ++i) { + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i]; + if ((obj->optObject.iSection >= 0) && (obj->optObject.iSection < MODERNOPT_PAGE_COUNT)) + g_ModernOptPages[obj->optObject.iSection].bShow = TRUE; + if (obj->optObject.hIcon) + obj->iTreeImageIndex = ImageList_AddIcon(himl, obj->optObject.hIcon); + } + + hwndCtrl = GetDlgItem(hwndDlg, IDC_ICOTABS); + for (i = 0; i < SIZEOF(g_ModernOptPages); ++i) + if (g_ModernOptPages[i].bShow && g_ModernOptPages[i].bShowTab) + { + HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(g_ModernOptPages[i].iIcon), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); + MIcoTab_AddItem(hwndCtrl, TranslateTS(g_ModernOptPages[i].lpzTitle), hIcon, i, FALSE); + DestroyIcon(hIcon); + } + + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); + hwndModernOpt = hwndDlg; + + if (g_iSectionRestore) + CallService(MS_MODERNOPT_SELECTPAGE, g_iSectionRestore, 0); + else + ModernOptUI_SelectSection(hwndDlg, dat, g_iSectionRestore); + + Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "Options", ""); + + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ICOTABS: + { + int iPage = MIcoTab_GetItemData(GetDlgItem(hwndDlg, IDC_ICOTABS), lParam); + ModernOptUI_SelectSection(hwndDlg, dat, iPage); + SetFocus(GetDlgItem(hwndDlg, IDC_ICOTABS)); + } + break; + + case IDC_BTN_HELP: + { + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[dat->iPage]; + if (obj->optObject.lpzHelpUrl) + ShellExecuteA(hwndDlg, "open", obj->optObject.lpzHelpUrl, "", "", SW_SHOW); + } + break; + + case IDC_BTN_EXPERT: + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BTN_APPLY))) + { + int idResult = MessageBox(hwndDlg, + TranslateT("You have some unsaved changes here.\n Do you wish to apply settings before switching?"), + _T("Miranda IM"), MB_ICONQUESTION|MB_YESNOCANCEL); + if (idResult == IDCANCEL) break; + sttNotifyPages(dat, (idResult == IDYES) ? PSN_APPLY : PSN_RESET); + } + + { Utils_SaveWindowPosition(hwndDlg, NULL, "Options", ""); + g_iSectionRestore = dat->iSection; + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[dat->iPage]; + if (obj->optObject.lpzClassicGroup || obj->optObject.lpzClassicPage) + { + OPENOPTIONSDIALOG ood = {0}; + ood.cbSize = sizeof(ood); + ood.pszGroup = obj->optObject.lpzClassicGroup; + ood.pszPage = obj->optObject.lpzClassicPage; + ood.pszTab = obj->optObject.lpzClassicTab; + HWND hwndOpt = (HWND)CallService(MS_OPT_OPENOPTIONSPAGE, 0, (LPARAM)&ood); + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + } + else { + CallService("Options/OptionsCommand", 0, 0); + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + } } + break; + + case IDOK: + sttNotifyPages(dat, PSN_APPLY); + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + break; + + case IDCANCEL: + sttNotifyPages(dat, PSN_RESET); + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + break; + + case IDC_BTN_APPLY: + EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_APPLY), FALSE); + sttNotifyPages(dat, PSN_APPLY); + break; + } + + return TRUE; + + case PSM_CHANGED: + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_APPLY), TRUE); + for (i = 0; i < dat->pObjectList.getCount(); ++i) { + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i]; + if (obj->hwnd && IsWindowVisible(obj->hwnd)) + obj->bChanged = TRUE; + } + break; + + case WM_NOTIFY: + { + LPNMHDR lpnmhdr = (LPNMHDR)lParam; + if (lpnmhdr->idFrom == IDC_TV_SUBSECTIONS ) { + LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)lParam; + if (lpnmhdr->code == TVN_SELCHANGED ) { + ModernOptUI_ShowPage(hwndDlg, dat, lpnmtv->itemNew.lParam); + break; + } + break; + } + return TRUE; + } + + case WM_CLOSE: + DestroyWindow(hwndDlg); + hwndModernOpt = 0; + return TRUE; + + case WM_DESTROY: + if (!dat) return TRUE; + li_List_Destruct(dat->pObjectList, ModernOptionsObject_Dtor); + DeleteObject(dat->hfntBold); + ImageList_Destroy(TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS), NULL, TVSIL_NORMAL)); + Utils_SaveWindowPosition(hwndDlg, NULL, "Options", ""); + delete dat; + } + return FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// +// UI utilities +static HWND ModernOptUI_ShowPage_Impl(HWND hwndDlg, struct ModernOptionsData *dat, int iPage, int dx, HWND hwndInsertAfter) +{ + if ((iPage < 0) || (iPage >= dat->pObjectList.getCount())) + return NULL; + + dat->iPage = iPage; + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[dat->iPage]; + if (!obj->hwnd) { + RECT rc1, rc2; + GetWindowRect(GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS), &rc1); + GetWindowRect(GetDlgItem(hwndDlg, IDC_TXT_DUMMY), &rc2); + MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc1, 2); + MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc2, 2); + rc1.top += dx; rc2.top += dx; + + obj->hwnd = CreateDialogParamA(obj->optObject.hInstance, obj->optObject.lpzTemplate, hwndDlg, obj->optObject.pfnDlgProc, (LPARAM)&obj->optObject); + if (obj->hwnd) { + DWORD dwShowFlags = + SWP_SHOWWINDOW | + ((obj->optObject.dwFlags & MODEROPT_FLG_NORESIZE) ? SWP_NOSIZE : 0); + + int i = 0; + + if (obj->optObject.iBoldControls) + for (i = 0; obj->optObject.iBoldControls[i]; ++i) { + HWND hwndChild = GetDlgItem(obj->hwnd, obj->optObject.iBoldControls[i]); + if (!hwndChild) continue; + SendMessage(hwndChild, WM_SETFONT, (WPARAM)dat->hfntBold, TRUE); + } + + if (obj->optObject.iType == MODERNOPT_TYPE_SECTIONPAGE) + SetWindowPos(obj->hwnd, hwndInsertAfter, rc1.left, rc1.top, rc2.right-rc1.left, rc2.bottom-rc1.top, dwShowFlags); + else + SetWindowPos(obj->hwnd, hwndInsertAfter, rc2.left, rc2.top, rc2.right-rc2.left, rc2.bottom-rc2.top, dwShowFlags); + + if (obj->optObject.iSection == MODERNOPT_PAGE_IGNORE) { + for (i = 0; i < dat->pObjectList.getCount(); ++i) { + struct ModernOptionsObject *ignoreObj = (struct ModernOptionsObject *)dat->pObjectList[i]; + if (ignoreObj->optObject.iType == MODERNOPT_TYPE_IGNOREOBJECT) + ModernOptIgnore_AddItem(&ignoreObj->optObject); + } } } + } + else ShowWindow(obj->hwnd, SW_SHOW); + + ShowWindow(GetDlgItem(hwndDlg, IDC_BTN_EXPERT), (obj->optObject.lpzClassicGroup || obj->optObject.lpzClassicPage) ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_BTN_HELP), obj->optObject.lpzHelpUrl ? SW_SHOW : SW_HIDE); + + return obj->hwnd; +} + +static int lstrcmp_null(TCHAR *p1, TCHAR *p2) +{ + if (!p1 && !p2) return 0; + if (!p1) return -1; + if (!p2) return 1; + return lstrcmp(p1, p2); +} + +static void ModernOptUI_ShowPage(HWND hwndDlg, struct ModernOptionsData *dat, int iPage) +{ + HWND hwndInsertAfter = GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS); + + int dx = 0; + for (int i = 0; i < dat->pObjectList.getCount(); ++i) + if ((dat->pObjectList[i]->optObject.iType == dat->pObjectList[iPage]->optObject.iType) && + (dat->pObjectList[i]->optObject.iSection == dat->pObjectList[iPage]->optObject.iSection) && + !lstrcmp_null(dat->pObjectList[i]->optObject.lptzSubsection, dat->pObjectList[iPage]->optObject.lptzSubsection)) + { + hwndInsertAfter = ModernOptUI_ShowPage_Impl(hwndDlg, dat, i, dx, hwndInsertAfter); + + if (dat->pObjectList[i]->hwnd) { + RECT rcWnd; GetWindowRect(dat->pObjectList[i]->hwnd, &rcWnd); + dx += rcWnd.bottom - rcWnd.top;// + 30; + } + } + else if (dat->pObjectList[i]->hwnd) + { + ShowWindow(dat->pObjectList[i]->hwnd, SW_HIDE); + } +} + +static void ModernOptUI_SelectSection(HWND hwndDlg, struct ModernOptionsData *dat, int iSection) +{ + int i; + int iPageType = -1; + + HWND hwndTree = GetDlgItem(hwndDlg, IDC_TV_SUBSECTIONS); + dat->iSection = iSection; + + SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0); + TreeView_DeleteAllItems(hwndTree); + for (i = 0; i < dat->pObjectList.getCount(); ++i) { + struct ModernOptionsObject *obj = (struct ModernOptionsObject *)dat->pObjectList[i]; + if (obj->optObject.iSection != iSection) continue; + + if ((iPageType < -1) && (iPageType != obj->optObject.iType)) continue; + iPageType = obj->optObject.iType; + + if (obj->optObject.iType == MODERNOPT_TYPE_SECTIONPAGE) { + ModernOptUI_ShowPage(hwndDlg, dat, i); + break; + } + + if (obj->optObject.iType == MODERNOPT_TYPE_SUBSECTIONPAGE) { + TVINSERTSTRUCT tvis = {0}; + tvis.hParent = TVI_ROOT; + tvis.hInsertAfter = TVI_LAST; + tvis.item.mask = TVIF_IMAGE|TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; + tvis.item.pszText = TranslateTS(obj->optObject.lptzSubsection); + tvis.item.cchTextMax = lstrlen(tvis.item.pszText); + tvis.item.iImage = tvis.item.iSelectedImage = obj->iTreeImageIndex; + tvis.item.lParam = i; + TreeView_InsertItem(hwndTree, &tvis); + } } + + SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0); + + if (iPageType < 0) + return; + + if (iPageType != MODERNOPT_TYPE_SECTIONPAGE) { + ShowWindow(hwndTree, SW_SHOW); + RedrawWindow(hwndTree, NULL, NULL, RDW_INVALIDATE); + TreeView_Select(hwndTree, TreeView_GetRoot(hwndTree), TVGN_CARET); + } + else ShowWindow(hwndTree, SW_HIDE); +} + +//////////////////////////////////////////////////////////////////////////////// +// Services +static INT_PTR svcModernOpt_Impl(WPARAM wParam, LPARAM lParam) +{ + if (!hwndModernOpt) { + ModernOptionsData *dat = new ModernOptionsData; + g_dwIdx = 0; + NotifyEventHooks(hevtModernOpt_Initialize, (WPARAM)dat, 0); + hwndModernOpt = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_MODERNOPT), NULL, ModernOptDlgProc, (LPARAM)dat); + ShowWindow(hwndModernOpt, SW_SHOW); + } + else SetForegroundWindow(hwndModernOpt); + + return 0; +} + +static INT_PTR svcModernOpt_Show(WPARAM wParam, LPARAM lParam) +{ + g_iSectionRestore = 0; + return svcModernOpt_Impl(wParam, lParam); +} + +static INT_PTR svcModernOpt_Restore(WPARAM wParam, LPARAM lParam) +{ + if (g_iSectionRestore == 0) return 0; + return svcModernOpt_Impl(wParam, lParam); +} + +static INT_PTR svcModernOpt_SelectPage(WPARAM wParam, LPARAM lParam) +{ + struct ModernOptionsData *dat; + + if (!hwndModernOpt) + return 0; + + dat = (struct ModernOptionsData *)GetWindowLongPtr(hwndModernOpt, GWLP_USERDATA); + if (!dat) + return 0; + + int nIdx = 0; + for (size_t i = 0; i < MODERNOPT_PAGE_COUNT; ++i) + if (g_ModernOptPages[i].bShow && g_ModernOptPages[i].bShowTab) { + if (i == wParam) { + MIcoTab_SetSel(GetDlgItem(hwndModernOpt, IDC_ICOTABS), nIdx); + break; + } + + ++nIdx; + } + +// ModernOptUI_SelectSection(hwndModernOpt, dat, wParam); + return 0; +} + +static INT_PTR svcModernOpt_AddObject(WPARAM wParam, LPARAM lParam) +{ + struct ModernOptionsData *dat = (struct ModernOptionsData *)wParam; + MODERNOPTOBJECT *obj = (MODERNOPTOBJECT *)lParam; + struct ModernOptionsObject *objCopy = (struct ModernOptionsObject *)mir_calloc(sizeof(struct ModernOptionsObject)); + + objCopy->dwIdx = ++g_dwIdx; + + objCopy->optObject.cbSize = sizeof(MODERNOPTOBJECT); + objCopy->optObject.dwFlags = obj->dwFlags; + objCopy->optObject.hIcon = obj->hIcon; + objCopy->optObject.iSection = obj->iSection; + objCopy->optObject.iType = obj->iType; + objCopy->optObject.hInstance = obj->hInstance; + objCopy->optObject.lpzTemplate = obj->lpzTemplate; + objCopy->optObject.pfnDlgProc = obj->pfnDlgProc; + + if (obj->lpzClassicGroup) objCopy->optObject.lpzClassicGroup = mir_strdup(obj->lpzClassicGroup); + if (obj->lpzClassicPage) objCopy->optObject.lpzClassicPage = mir_strdup(obj->lpzClassicPage); + if (obj->lpzClassicTab) objCopy->optObject.lpzClassicTab = mir_strdup(obj->lpzClassicTab); + if (obj->lpzHelpUrl) objCopy->optObject.lpzHelpUrl = mir_strdup(obj->lpzHelpUrl); + + if (obj->iBoldControls) { + int count = 0; + while (obj->iBoldControls[count++]) ; + objCopy->optObject.iBoldControls = (int *)mir_alloc(sizeof(int) * count); + memcpy(objCopy->optObject.iBoldControls, obj->iBoldControls, sizeof(int) * count); + } + + switch (obj->iType) { + case MODERNOPT_TYPE_SECTIONPAGE: + objCopy->optObject.lptzSubsection = NULL; + break; + + case MODERNOPT_TYPE_SUBSECTIONPAGE: + objCopy->optObject.lptzSubsection = (objCopy->optObject.dwFlags & MODEROPT_FLG_UNICODE) ? + mir_u2t(obj->lpwzSubsection) : + mir_a2t(obj->lpzSubsection); + break; + + case MODERNOPT_TYPE_IGNOREOBJECT: + objCopy->optObject.lptzSubsection = (objCopy->optObject.dwFlags & MODEROPT_FLG_UNICODE) ? + mir_u2t(obj->lpwzSubsection) : + mir_a2t(obj->lpzSubsection); + objCopy->optObject.lpzIgnoreModule = mir_strdup(obj->lpzIgnoreModule); + objCopy->optObject.lpzIgnoreSetting = mir_strdup(obj->lpzIgnoreSetting); + objCopy->optObject.dwIgnoreBit = obj->dwIgnoreBit; + break; + + case MODERNOPT_TYPE_SELECTORPAGE: + objCopy->optObject.iType = MODERNOPT_TYPE_SUBSECTIONPAGE; + objCopy->optObject.hInstance = hInst; + objCopy->optObject.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_SKINS); + objCopy->optObject.pfnDlgProc = ModernOptSelector_DlgProc; + objCopy->optObject.lptzSubsection = (objCopy->optObject.dwFlags & MODEROPT_FLG_UNICODE) ? + mir_u2t(obj->lpwzSubsection) : + mir_a2t(obj->lpzSubsection); + objCopy->optObject.lpzThemeExtension = mir_strdup(obj->lpzThemeExtension); + objCopy->optObject.lpzThemeModuleName = mir_strdup(obj->lpzThemeModuleName); + break; + } + + dat->pObjectList.insert(objCopy); + return 0; +} + +static int hookModernOpt_Initialize(WPARAM wParam, LPARAM lParam) +{ + static int iBoldControls[] = + { + IDC_TXT_TITLE1, IDC_TXT_TITLE2, IDC_TXT_TITLE3, IDC_TXT_TITLE4, +// IDC_TXT_TITLE5, IDC_TXT_TITLE6, IDC_TXT_TITLE7, IDC_TXT_TITLE8, + MODERNOPT_CTRL_LAST + }; + + MODERNOPTOBJECT obj = {0}; + + obj.cbSize = sizeof(obj); + obj.dwFlags = MODEROPT_FLG_TCHAR; + + obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + obj.hInstance = hInst; + + obj.iSection = MODERNOPT_PAGE_HOME; + obj.iType = MODERNOPT_TYPE_SECTIONPAGE; + obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_HOME); + obj.pfnDlgProc = ModernOptHome_DlgProc; + obj.lpzHelpUrl = "http://wiki.miranda-im.org/"; + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + + #if defined(_DEBUG) && defined(MOPT_SAMPLE_PAGES) + obj.iSection = MODERNOPT_PAGE_ADVANCED; + obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE; + obj.lptzSubsection = _T("Page 1"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.lptzSubsection = _T("Page 2"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.lptzSubsection = _T("Page 3"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + + obj.iType = MODERNOPT_TYPE_IGNOREOBJECT; + obj.hIcon = LoadSkinnedIcon(SKINICON_EVENT_FILE); + obj.lptzSubsection = _T("Files"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); + obj.lptzSubsection = _T("Messages"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.hIcon = LoadSkinnedIcon(SKINICON_EVENT_URL); + obj.lptzSubsection = _T("URL events"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_TYPING); + obj.lptzSubsection = _T("Typing notifications"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_ADDCONTACT); + obj.lptzSubsection = _T("Added notifications"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + obj.lptzSubsection = _T("Auth requests"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + + obj.iSection = MODERNOPT_PAGE_SKINS; + obj.iType = MODERNOPT_TYPE_SECTIONPAGE; + obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_SKINS); + obj.pfnDlgProc = NULL; + obj.iBoldControls = iBoldControls; + obj.lpzHelpUrl = NULL; + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + + obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_EMPTY); + obj.pfnDlgProc = NULL; + obj.iBoldControls = 0; + obj.lpzClassicGroup = 0; + obj.lpzClassicPage = 0; + obj.lpzHelpUrl = 0; + + obj.iSection = MODERNOPT_PAGE_CLIST; + obj.iType = MODERNOPT_TYPE_SECTIONPAGE; + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + + obj.iSection = MODERNOPT_PAGE_MSGS; + obj.iType = MODERNOPT_TYPE_SECTIONPAGE; + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + + obj.iSection = MODERNOPT_PAGE_ADVANCED; + obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE; + obj.lptzSubsection = _T("Page 1"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.lptzSubsection = _T("Page 2"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.lptzSubsection = _T("Page 3"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + + obj.iSection = MODERNOPT_PAGE_MODULES; + obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE; + obj.lptzSubsection = _T("Configure"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.lptzSubsection = _T("Update"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + obj.lptzSubsection = _T("Download"); + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + #endif + + return 0; +} diff --git a/plugins/ModernOpt/src/modernopt.h b/plugins/ModernOpt/src/modernopt.h new file mode 100644 index 0000000000..728488d810 --- /dev/null +++ b/plugins/ModernOpt/src/modernopt.h @@ -0,0 +1,53 @@ +/* + +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. +*/ + +#ifndef MODERNOPT_H__ +#define MODERNOPT_H__ 1 + +#include "m_descbutton.h" +#include "m_iconheader.h" +#include "m_modernopt.h" + +struct ModernOptMainPageInfo +{ + int idcButton; + BOOL bShowTab; + int iIcon; + TCHAR *lpzTitle; + TCHAR *lpzDescription; + int iPageType; + BOOL bShow; +}; + +extern struct ModernOptMainPageInfo g_ModernOptPages[MODERNOPT_PAGE_COUNT]; + +extern HMODULE hInst; + +INT_PTR CALLBACK ModernOptHome_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK ModernOptSelector_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +void ModernOptIgnore_AddItem(MODERNOPTOBJECT *obj); + +#endif // MODERNOPT_H__ diff --git a/plugins/ModernOpt/src/mopt_home.cpp b/plugins/ModernOpt/src/mopt_home.cpp new file mode 100644 index 0000000000..980f580121 --- /dev/null +++ b/plugins/ModernOpt/src/mopt_home.cpp @@ -0,0 +1,80 @@ +/* + +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" + +extern HMODULE hInst; + +INT_PTR CALLBACK ModernOptHome_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + for (i = 0; i < SIZEOF(g_ModernOptPages); ++i) { + if (g_ModernOptPages[i].idcButton) { + HWND hwndCtrl = GetDlgItem(hwndDlg, g_ModernOptPages[i].idcButton); + if (g_ModernOptPages[i].bShow) { + HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(g_ModernOptPages[i].iIcon), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); + MDescButton_SetIcon(hwndCtrl, hIcon); + MDescButton_SetTitle(hwndCtrl, TranslateTS(g_ModernOptPages[i].lpzTitle)); + MDescButton_SetDescription(hwndCtrl, TranslateTS(g_ModernOptPages[i].lpzDescription)); + DestroyIcon(hIcon); + } + else ShowWindow(hwndCtrl, SW_HIDE); + } } + + return FALSE; + + case WM_COMMAND: + switch ( LOWORD(wParam)) { + case IDC_BTN_CLASSICOPT: + PostMessage(GetParent(hwndDlg), WM_CLOSE, 0, 0); + { + OPENOPTIONSDIALOG ood = {0}; + ood.cbSize = sizeof(ood); + CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood); + } + break; + + case IDC_BTN_HELP: + ShellExecuteA(hwndDlg, "open", "http://www.miranda-im.org/", "", "", SW_SHOW); + break; + + default: + for (i = 0; i < SIZEOF(g_ModernOptPages); ++i) { + if (g_ModernOptPages[i].idcButton == LOWORD(wParam)) + { + CallService(MS_MODERNOPT_SELECTPAGE, i, 0); + return TRUE; + } } } + + case WM_DESTROY: + return FALSE; + } + return FALSE; +} diff --git a/plugins/ModernOpt/src/mopt_ignore.cpp b/plugins/ModernOpt/src/mopt_ignore.cpp new file mode 100644 index 0000000000..74f8b1524d --- /dev/null +++ b/plugins/ModernOpt/src/mopt_ignore.cpp @@ -0,0 +1,61 @@ +/* + +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 HWND g_hwndModernOptIgnore = NULL; + +void ModernOptIgnore_AddItem(MODERNOPTOBJECT *obj) +{ + if ( g_hwndModernOptIgnore ) + SendMessage(g_hwndModernOptIgnore, WM_APP, 0, (LPARAM)obj); +} + +static void ResetListOptions(HWND hwndList) +{ + SendMessage(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); + SendMessage(hwndList,CLM_SETBKCOLOR,GetSysColor(COLOR_WINDOW),0); + SendMessage(hwndList,CLM_SETGREYOUTFLAGS,0,0); + SendMessage(hwndList,CLM_SETLEFTMARGIN,4,0); + SendMessage(hwndList,CLM_SETINDENT,10,0); + SendMessage(hwndList,CLM_SETHIDEEMPTYGROUPS,1,0); + + for(int i=0;i<=FONTID_MAX;i++) + SendMessage(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); +} + +static void SetAllContactIcons(HWND hwndList, int count) +{ + HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + do { + DWORD hItem = SendMessage(hwndList,CLM_FINDCONTACT,(WPARAM)hContact,0); + for (int i = 0; i < count; ++i) + SendMessage(hwndList,CLM_SETEXTRAIMAGE,hItem,MAKELPARAM(i, i+1)); + if (!DBGetContactSettingByte(hContact,"CList","Hidden",0)) + SendMessage(hwndList,CLM_SETCHECKMARK,hItem,1); + } + while(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)); +} 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; +} diff --git a/plugins/ModernOpt/src/resource.h b/plugins/ModernOpt/src/resource.h new file mode 100644 index 0000000000..de4fbab2e0 --- /dev/null +++ b/plugins/ModernOpt/src/resource.h @@ -0,0 +1,36 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// + +#define IDD_MODERNOPT_EMPTY 206 +#define IDD_MODERNOPT 216 +#define IDD_MODERNOPT_HOME 219 +#define IDD_MODERNOPT_SKINS 220 + +#define IDI_BIG_ADVANCED 308 +#define IDI_BIG_BUDDYLIST 309 +#define IDI_BIG_IGNORE 310 +#define IDI_BIG_MESSAGE 311 +#define IDI_BIG_MODULES 312 +#define IDI_BIG_NETWORK 313 +#define IDI_BIG_SKINS 314 +#define IDI_BIG_STATUS 315 + +#define IDC_BTN_HELP 1001 +#define IDC_BTN_CLASSICOPT 1002 +#define IDC_BTN_ACCOUNTS 1004 +#define IDC_BTN_SKINS 1005 +#define IDC_BTN_CLIST 1006 +#define IDC_BTN_MESSAGING 1007 +#define IDC_BTN_IGNORE 1008 +#define IDC_BTN_STATUS 1009 +#define IDC_BTN_ADVANCED 1010 +#define IDC_BTN_PLUGINS 1011 +#define IDC_TV_SUBSECTIONS 1012 +#define IDC_ICOTABS 1013 +#define IDC_BTN_EXPERT 1015 +#define IDC_BTN_APPLY 1016 +#define IDC_TXT_DUMMY 1017 +#define IDC_SKINLIST 1029 +#define IDC_PREVIEW1 1030 -- cgit v1.2.3