From 1e92bf5cf72665b5fec103a0a70d734340725539 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 24 Jul 2012 09:26:39 +0000 Subject: StopSpamPlus, TipperYM, TooltipNotify, TopToolBar, TranslitSwitcher, UserGuide: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1159 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/TopToolBar/src/BkgrCfg.h | 18 + plugins/TopToolBar/src/InternalButtons.cpp | 121 +++++ plugins/TopToolBar/src/common.h | 157 +++++++ plugins/TopToolBar/src/main.cpp | 51 +++ plugins/TopToolBar/src/resource.h | 66 +++ plugins/TopToolBar/src/toolbar.cpp | 707 +++++++++++++++++++++++++++++ plugins/TopToolBar/src/toolbarwnd.cpp | 330 ++++++++++++++ plugins/TopToolBar/src/topbutton.cpp | 178 ++++++++ plugins/TopToolBar/src/ttbopt.cpp | 559 +++++++++++++++++++++++ plugins/TopToolBar/src/version.h | 46 ++ 10 files changed, 2233 insertions(+) create mode 100644 plugins/TopToolBar/src/BkgrCfg.h create mode 100644 plugins/TopToolBar/src/InternalButtons.cpp create mode 100644 plugins/TopToolBar/src/common.h create mode 100644 plugins/TopToolBar/src/main.cpp create mode 100644 plugins/TopToolBar/src/resource.h create mode 100644 plugins/TopToolBar/src/toolbar.cpp create mode 100644 plugins/TopToolBar/src/toolbarwnd.cpp create mode 100644 plugins/TopToolBar/src/topbutton.cpp create mode 100644 plugins/TopToolBar/src/ttbopt.cpp create mode 100644 plugins/TopToolBar/src/version.h (limited to 'plugins/TopToolBar/src') diff --git a/plugins/TopToolBar/src/BkgrCfg.h b/plugins/TopToolBar/src/BkgrCfg.h new file mode 100644 index 0000000000..4533267fcb --- /dev/null +++ b/plugins/TopToolBar/src/BkgrCfg.h @@ -0,0 +1,18 @@ +// +// Register of plugin's user +// +// wParam = (WPARAM)szSetting - string that describes a user +// format: Category/ModuleName, +// eg: "Contact list background/CLUI", +// "Status bar background/StatusBar" +// lParam = (LPARAM)dwFlags +// +#define MS_BACKGROUNDCONFIG_REGISTER "BkgrCfg/Register" + +// +// Notification about changed background +// wParam = ModuleName +// lParam = 0 +#define ME_BACKGROUNDCONFIG_CHANGED "BkgrCfg/Changed" + +#define CLBF_TILEVTOROWHEIGHT 0x0100 diff --git a/plugins/TopToolBar/src/InternalButtons.cpp b/plugins/TopToolBar/src/InternalButtons.cpp new file mode 100644 index 0000000000..7fcdc1cef8 --- /dev/null +++ b/plugins/TopToolBar/src/InternalButtons.cpp @@ -0,0 +1,121 @@ + +#include "common.h" + +#define TTBI_GROUPSHOWHIDE "TTBInternal/GroupShowHide" +#define TTBI_SOUNDSONOFF "TTBInternal/SoundsOnOFF" +#define TTBI_MAINMENUBUTT "TTBInternal/MainMenuBUTT" + +extern HINSTANCE hInst; + +static HWND hwndContactTree; + +struct +{ + char *name, *pszService; + int iconidUp, iconidDn; + char *tooltipUp, *tooltipDn; + HANDLE hButton; +} +static stdButtons[] = +{ + { "Show only Online Users", MS_CLIST_SETHIDEOFFLINE, IDI_SHOWONLINEUP, IDI_SHOWONLINEDN, "Hide Offline Users", "Show All Users" }, + { "Groups On/Off", TTBI_GROUPSHOWHIDE, IDI_GROUPSUP, IDI_GROUPSDN, "Hide Groups", "Show Groups" }, + { "Sounds Enable/Disable", TTBI_SOUNDSONOFF, IDI_SOUNDUP, IDI_SOUNDDN, "Disable Sounds", "Enable Sounds" }, + + { "Show Options Page", "Options/OptionsCommand", IDI_OPTIONSUP, 0, "Show Options" }, + { "Minimize Button", MS_CLIST_SHOWHIDE, IDI_MINIMIZEUP, 0, NULL }, + { "Find/Add Contacts", MS_FINDADD_FINDADD, IDI_FINDADDUP, 0, NULL }, + { "Show Main Menu", TTBI_MAINMENUBUTT, IDI_MIRANDAUP, 0, "Show Main Menu" } +}; + +/////////////////////////////////////////////////////////////////////////////// + +int OnSettingChanging(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *)lParam; + if (wParam != 0 || dbcws == NULL) + return 0; + + if ( !strcmp(dbcws->szModule, "CList")) { + if ( !strcmp(dbcws->szSetting, "HideOffline")) + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)stdButtons[0].hButton, (dbcws->value.bVal) ? TTBST_PUSHED : TTBST_RELEASED); + + else if (!strcmp(dbcws->szSetting, "UseGroups")) + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)stdButtons[1].hButton, (dbcws->value.bVal) ? TTBST_PUSHED : TTBST_RELEASED); + } + + else if (!strcmp(dbcws->szModule, "Skin")) { + if (!strcmp(dbcws->szSetting, "UseSound")) + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)stdButtons[2].hButton, (dbcws->value.bVal) ? TTBST_RELEASED : TTBST_PUSHED); + } + + return 0; +} + +INT_PTR TTBInternalMainMenuButt(WPARAM wParam, LPARAM lParam) +{ + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); + + POINT pt; + GetCursorPos(&pt); + TrackPopupMenu(hMenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), NULL); + return 0; +} + +INT_PTR TTBInternalGroupShowHide(WPARAM wParam, LPARAM lParam) +{ + int newVal = !(GetWindowLongPtr(hwndContactTree, GWL_STYLE)&CLS_USEGROUPS); + db_set_b(NULL, "CList", "UseGroups", (BYTE)newVal); + SendMessage(hwndContactTree, CLM_SETUSEGROUPS, newVal, 0); + return 0; +} + +INT_PTR TTBInternalSoundsOnOff(WPARAM wParam, LPARAM lParam) +{ + int newVal = !(db_get_b(NULL, "Skin", "UseSound", 1)); + db_set_b(NULL, "Skin", "UseSound", (BYTE)newVal); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +int InitInternalButtons(WPARAM, LPARAM) +{ + hwndContactTree = (HWND)CallService(MS_CLUI_GETHWNDTREE, 0, 0); + + CreateServiceFunction(TTBI_GROUPSHOWHIDE, TTBInternalGroupShowHide); + CreateServiceFunction(TTBI_SOUNDSONOFF, TTBInternalSoundsOnOff); + CreateServiceFunction(TTBI_MAINMENUBUTT, TTBInternalMainMenuButt); + + TTBButton ttb = { 0 }; + ttb.cbSize = sizeof(ttb); + + for (int i=0; i < SIZEOF(stdButtons); i++) { + ttb.name = stdButtons[i].name; + ttb.pszService = stdButtons[i].pszService; + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_INTERNAL; + if ((ttb.pszTooltipDn = stdButtons[i].tooltipDn) != NULL) + ttb.dwFlags |= TTBBF_SHOWTOOLTIP; + ttb.pszTooltipUp = stdButtons[i].tooltipUp; + ttb.hIconUp = (HICON)LoadImage(hInst, MAKEINTRESOURCE(stdButtons[i].iconidUp), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + if (stdButtons[i].iconidDn) { + ttb.dwFlags |= TTBBF_ASPUSHBUTTON; + ttb.hIconDn = (HICON)LoadImage(hInst, MAKEINTRESOURCE(stdButtons[i].iconidDn), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + } + else ttb.hIconDn = NULL; + + stdButtons[i].hButton = (HANDLE)TTBAddButton((WPARAM)&ttb, 0); + } + + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)stdButtons[0].hButton, + db_get_b(NULL, "CList", "HideOffline", 0) ? TTBST_PUSHED : TTBST_RELEASED); + + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)stdButtons[1].hButton, + db_get_b(NULL, "CList", "UseGroups", 1) ? TTBST_PUSHED : TTBST_RELEASED); + + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)stdButtons[2].hButton, + db_get_b(NULL, "Skin", "UseSound", 1) ? TTBST_RELEASED : TTBST_PUSHED); + + HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnSettingChanging); + return 0; +} diff --git a/plugins/TopToolBar/src/common.h b/plugins/TopToolBar/src/common.h new file mode 100644 index 0000000000..0840111f2f --- /dev/null +++ b/plugins/TopToolBar/src/common.h @@ -0,0 +1,157 @@ +#ifndef TTB_COMMON_H +#define TTB_COMMON_H + + +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include +#include +#include + +#include "win2k.h" +#include "newpluginapi.h" +#include "m_system.h" +#include "m_system_cpp.h" +#include "m_database.h" +#include "m_clist.h" +#include "m_skin.h" +#include "m_utils.h" +#include "m_cluiframes.h" +#include "m_clui.h" +#include "m_clc.h" +#include "m_findadd.h" +#include "m_langpack.h" +#include "m_options.h" +#include "resource.h" +#include "m_protocols.h" +#include "m_protosvc.h" +#include "m_toptoolbar.h" +#include "m_button.h" +#include "m_icolib.h" +#include "BkgrCfg.h" + +#define TTB_BUTTON_CLASS _T("TopToolbarButtonClass") + +#define TTB_REPOSBUTTONS (WM_USER+10) +#define TTB_UPDATEFRAMEVISIBILITY (WM_USER+11) + +#define TTBDEFAULT_BKBMPUSE CLB_STRETCH +#define TTBDEFAULT_BKCOLOUR GetSysColor(COLOR_3DFACE) +#define TTBDEFAULT_USEBITMAP 0 +#define TTBDEFAULT_SELBKCOLOUR GetSysColor(COLOR_HIGHLIGHT) + +#define TTBBF_INTERNAL 0x1000000 +#define TTBBF_OPTIONAL 0x2000000 + +/////////////////////////////////////////////////////////////////////////////// +// TopButtonInt class + +struct TopButtonInt : public MZeroedObject +{ + ~TopButtonInt(); + + DWORD CheckFlags(DWORD Flags); + void CreateWnd(void); + void LoadSettings(void); + void SaveSettings(int *SepCnt, int *LaunchCnt); + void SetBitmap(void); + + __inline bool isSep() const + { return (dwFlags & TTBBF_ISSEPARATOR) != 0; + } + + __inline bool isVisible() const + { return (dwFlags & TTBBF_VISIBLE) != 0; + } + + HWND hwnd; + int id; + BOOL bPushed; + int dwFlags; + int x, y, arrangedpos; + HICON hIconUp, hIconDn; + HANDLE hIconHandleUp, hIconHandleDn; + + char *pszService; + TCHAR *ptszProgram; + char *pszName; + TCHAR *ptszTooltip; + + LPARAM lParamUp; + WPARAM wParamUp; + LPARAM lParamDown; + WPARAM wParamDown; + + int hLangpack; + TCHAR *ptszTooltipUp, *ptszTooltipDn; +}; + +/////////////////////////////////////////////////////////////////////////////// + +int TTBOptInit(WPARAM wParam, LPARAM lParam); +//append string +char __inline *AS(char *str, const char *setting, char *addstr); + +TopButtonInt* CreateButton(TTBButton* but); + +int LoadBackgroundOptions(); + +int ArrangeButtons(); + +#define DEFBUTTWIDTH 20 +#define DEFBUTTHEIGHT 20 +#define DEFBUTTGAP 1 + +#define SEPWIDTH 3 + +extern TTBCtrl* g_ctrl; + +extern LIST Buttons; +extern HINSTANCE hInst; +extern HBITMAP hBmpBackground, hBmpSeparator; +extern CRITICAL_SECTION csButtonsHook; +extern pfnCustomProc g_CustomProc; +extern LPARAM g_CustomProcParam; +extern HANDLE hTTBModuleLoaded, hTTBInitButtons; + +void AddToOptions(TopButtonInt* b); +void RemoveFromOptions(int id); + +//append string +char *AS(char *str, const char *setting, char *addstr) +{ + if (str != NULL) { + strcpy(str, setting); + strcat(str, addstr); + } + return str; +} + +#define TTB_LAUNCHSERVICE "TTB/LaunchService" + +TopButtonInt* idtopos(int id, int* pPos=NULL); + +INT_PTR TTBAddButton(WPARAM, LPARAM); +INT_PTR TTBRemoveButton(WPARAM, LPARAM); + +int InitInternalButtons(WPARAM, LPARAM); + +int LoadToolbarModule( void ); +int UnloadToolbarModule( void ); + +void SetAllBitmaps( void ); +int SaveAllLButs( void ); +int SaveAllButtonsOptions( void ); + +void InsertSeparator( int i ); +void DeleteSeparator(int i); +void DeleteLBut(int i); +void InsertLBut(int i); + +int OnModulesLoad(WPARAM, LPARAM); + +#endif \ No newline at end of file diff --git a/plugins/TopToolBar/src/main.cpp b/plugins/TopToolBar/src/main.cpp new file mode 100644 index 0000000000..601de36408 --- /dev/null +++ b/plugins/TopToolBar/src/main.cpp @@ -0,0 +1,51 @@ + +#include "common.h" +#include "version.h" + +HINSTANCE hInst; +int hLangpack; + +PLUGININFOEX pluginInfo = +{ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __PLUGIN_DESC, + __PLUGIN_AUTHOR, + __PLUGIN_EMAIL, + __PLUGIN_RIGHTS, + __PLUGIN_AUTHORWEB, + UNICODE_AWARE, + {0xf593c752, 0x51d8, 0x4d46, {0xba, 0x27, 0x37, 0x57, 0x79, 0x53, 0xf5, 0x5c}} +}; + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +extern "C" int __declspec(dllexport) Load(void) +{ + mir_getLP(&pluginInfo); + + LoadToolbarModule(); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +extern "C" int __declspec(dllexport) Unload(void) +{ + UnloadToolbarModule(); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} diff --git a/plugins/TopToolBar/src/resource.h b/plugins/TopToolBar/src/resource.h new file mode 100644 index 0000000000..498762de51 --- /dev/null +++ b/plugins/TopToolBar/src/resource.h @@ -0,0 +1,66 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by main.rc +// +#define IDB_SEP 118 +#define IDI_SHOWONLINEUP 125 +#define IDI_SHOWONLINEDN 126 +#define IDI_GROUPSUP 127 +#define IDI_GROUPSDN 128 +#define IDI_SOUNDDN 129 +#define IDI_SOUNDUP 130 +#define IDI_OPTIONSUP 131 +#define IDI_MINIMIZEUP 133 +#define IDI_FINDADDUP 135 +#define IDI_MIRANDAUP 137 +#define IDI_RUN 140 +#define IDD_OPT_TTBBKG 230 +#define IDD_OPT_INTERNALORDER 262 +#define IDD_OPT_BUTORDER 262 +#define IDD_FRAMEPLUG2 265 +#define IDC_BUTTON1 1002 +#define IDC_ADDSEP 1003 +#define IDC_REMOVEBUTTON 1004 +#define IDC_ADDLBUTTON 1005 +#define IDC_DELLBUTTON 1006 +#define IDC_ENAME 1007 +#define IDC_LBUTTONNAME 1008 +#define IDC_EPATH 1009 +#define IDC_AUTOSIZE 1010 +#define IDC_LBUTTONPATH 1011 +#define IDC_LBUTTONSET 1012 +#define IDC_BUTTHEIGHT 1015 +#define IDC_EDIT2 1016 +#define IDC_BUTTWIDTH 1016 +#define IDC_BUTTGAP 1017 +#define IDC_USEFLAT 1018 +#define IDC_AUTORESIZE 1019 +#define IDC_SINGLELINE 1020 +#define IDC_SPIN_HEIGHT 1024 +#define IDC_SPIN_WIDTH 1025 +#define IDC_SPIN_GAP 1026 +#define IDC_BROWSE 1184 +#define IDC_BKGCOLOUR 1269 +#define IDC_FILENAME 1271 +#define IDC_SCROLL 1277 +#define IDC_PROPORTIONAL 1278 +#define IDC_SELCOLOUR 1281 +#define IDC_STRETCHH 1298 +#define IDC_STRETCHV 1299 +#define IDC_TILEH 1300 +#define IDC_TILEV 1301 +#define IDC_BITMAP 1363 +#define IDC_P2ONLINEBUTT 1562 +#define IDC_P2GROUPBUTT 1564 +#define IDC_BUTTONORDERTREE 1591 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 139 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1025 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/TopToolBar/src/toolbar.cpp b/plugins/TopToolBar/src/toolbar.cpp new file mode 100644 index 0000000000..156b83dbb7 --- /dev/null +++ b/plugins/TopToolBar/src/toolbar.cpp @@ -0,0 +1,707 @@ + +#include "common.h" + +#define OLD_TBBUTTON_SIZE (offsetof(TTBButton, pszTooltipUp)) + +pfnCustomProc g_CustomProc = NULL; +LPARAM g_CustomProcParam = 0; +TTBCtrl *g_ctrl = NULL; + +INT_PTR OnEventFire(WPARAM wParam, LPARAM lParam); + +HWND hwndContactList = 0; + +int nextButtonId = 200; + +HANDLE hTTBModuleLoaded, hTTBInitButtons; +static WNDPROC buttonWndProc; + +CRITICAL_SECTION csButtonsHook; + +int sortfunc(const TopButtonInt* a, const TopButtonInt* b) +{ + return a->arrangedpos - b->arrangedpos; +} + +LIST Buttons(8, sortfunc); + +TopButtonInt* idtopos(int id, int* pPos) +{ + for ( int i = 0; i < Buttons.getCount(); i++) + if (Buttons[i]->id == id) { + if (pPos) *pPos = i; + return Buttons[i]; + } + + if (pPos) *pPos = -1; + return NULL; +} + +//----- Service buttons ----- +void InsertSBut(int i) +{ + TTBButton ttb = { 0 }; + ttb.cbSize = sizeof(ttb); + ttb.hIconDn = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + ttb.hIconUp = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISSBUTTON | TTBBF_INTERNAL; + ttb.wParamDown = i; + TTBAddButton(( WPARAM )&ttb, 0); +} + +void LoadAllSButs() +{ + //must be locked + int cnt = db_get_b(0, TTB_OPTDIR, "ServiceCnt", 0); + if (cnt > 0) { + for (int i = 1; i<=cnt; i++) + InsertSBut(i); + } +} + +//----- Launch buttons ----- +INT_PTR LaunchService(WPARAM wParam, LPARAM lParam) +{ + PROCESS_INFORMATION pi; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + + if ( CreateProcess(NULL, Buttons[lParam]->ptszProgram, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + + return 0; +} + +void InsertLBut(int i) +{ + TTBButton ttb = { 0 }; + ttb.cbSize = sizeof(ttb); + ttb.hIconDn = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISLBUTTON | TTBBF_INTERNAL; + ttb.name = LPGEN("Default"); + ttb.program = _T("Execute Path"); + ttb.wParamDown = i; + TTBAddButton(( WPARAM )&ttb, 0); +} + +void LoadAllLButs() +{ + //must be locked + int cnt = db_get_b(0, TTB_OPTDIR, "LaunchCnt", 0); + for (int i = 0; i < cnt; i++) + InsertLBut(i); +} + +//----- Separators ----- + +void InsertSeparator(int i) +{ + TTBButton ttb = { 0 }; + ttb.cbSize = sizeof(ttb); + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISSEPARATOR | TTBBF_INTERNAL; + ttb.wParamDown = i; + TTBAddButton((WPARAM)&ttb, 0); +} + +void LoadAllSeparators() +{ + //must be locked + int cnt = db_get_b(0, TTB_OPTDIR, "SepCnt", 0); + for (int i = 0; i < cnt; i++) + InsertSeparator(i); +} + +int SaveAllButtonsOptions() +{ + int SeparatorCnt = 0; + int LaunchCnt = 0; + { + mir_cslock lck(csButtonsHook); + for (int i = 0; i < Buttons.getCount(); i++) + Buttons[i]->SaveSettings(&SeparatorCnt, &LaunchCnt); + } + db_set_b(0, TTB_OPTDIR, "SepCnt", SeparatorCnt); + db_set_b(0, TTB_OPTDIR, "LaunchCnt", LaunchCnt); + return 0; +} + +static bool nameexists(const char *name) +{ + if (name == NULL) + return false; + + for (int i = 0; i < Buttons.getCount(); i++) + if ( !lstrcmpA(Buttons[i]->pszName, name)) + return true; + + return false; +} + +static void Icon2button(TTBButton* but, HANDLE& hIcoLib, HICON& hIcon, bool bIsUp) +{ + HANDLE hSrc = bIsUp ? but->hIconHandleUp : but->hIconHandleDn; + if (hSrc == NULL) { + hIcoLib = NULL, hIcon = NULL; + return; + } + + hIcoLib = (HANDLE)CallService(MS_SKIN2_ISMANAGEDICON, WPARAM(hSrc), 0); + if (!hIcoLib) { + char buf[256]; + mir_snprintf(buf, SIZEOF(buf), "toptoolbar_%s%s", but->name, (bIsUp) ? (but->hIconDn ? "%s_up" : "%s") : "%s_dn"); + SKINICONDESC sid = {0}; + sid.cbSize = sizeof(sid); + sid.pszSection = "Toolbar"; + sid.pszName = buf; + sid.pszDefaultFile = NULL; + sid.pszDescription = but->name; + sid.hDefaultIcon = (bIsUp) ? but->hIconUp : but->hIconDn; + hIcoLib = Skin_AddIcon(&sid); + } + + hIcon = Skin_GetIconByHandle(hIcoLib); +} + +TopButtonInt* CreateButton(TTBButton* but) +{ + TopButtonInt* b = new TopButtonInt; + b->id = nextButtonId++; + + b->dwFlags = but->dwFlags; + + b->wParamUp = but->wParamUp; + b->lParamUp = but->lParamUp; + b->wParamDown = but->wParamDown; + b->lParamDown = but->lParamDown; + + if ( !(b->dwFlags & TTBBF_ISSEPARATOR)) { + b->bPushed = (but->dwFlags & TTBBF_PUSHED) ? TRUE : FALSE; + + if (but->dwFlags & TTBBF_ISLBUTTON) { + b->ptszProgram = mir_tstrdup(but->program); + b->pszService = mir_strdup(TTB_LAUNCHSERVICE); + } + else { + b->ptszProgram = NULL; + b->pszService = mir_strdup(but->pszService); + } + + b->pszName = mir_strdup(but->name); + + Icon2button(but, b->hIconHandleUp, b->hIconUp, true); + Icon2button(but, b->hIconHandleDn, b->hIconDn, false); + + if (but->cbSize > OLD_TBBUTTON_SIZE) { + b->ptszTooltipUp = mir_a2t(but->pszTooltipUp); + b->ptszTooltipDn = mir_a2t(but->pszTooltipDn); + } + } + return b; +} + +int ArrangeButtons() +{ + mir_cslock lck(csButtonsHook); + + RECT rcClient; + GetClientRect(g_ctrl->hWnd, &rcClient); + int nBarSize = rcClient.right - rcClient.left; + if (nBarSize == 0) + return 0; + + int nLineCount = 0; + int i, ypos = 1, xpos = g_ctrl->nButtonSpace, nextX = 0, y = 0; + int newheight = g_ctrl->nButtonHeight+1, nButtonCount=0; + + for (i=0; i < Buttons.getCount(); i++) + if (Buttons[i]->hwnd) + nButtonCount++; + + if (nButtonCount == 0) + return 0; + + HDWP hdwp = BeginDeferWindowPos(nButtonCount); + + bool bWasButttonBefore; + int nUsedWidth, iFirstButtonId = 0, iLastButtonId = 0; + + do + { + nLineCount++; + bWasButttonBefore = false; + nUsedWidth = 0; + + for (i=iFirstButtonId; i < Buttons.getCount(); i++) { + TopButtonInt *b = Buttons[i]; + if (b->hwnd == NULL) + continue; + + int width = 0; + if ( b->isVisible()) + width = (b->isSep()) ? SEPWIDTH+2 : g_ctrl->nButtonWidth + ((bWasButttonBefore) ? g_ctrl->nButtonSpace : 0); + if (nUsedWidth + width > nBarSize) + break; + + nUsedWidth += width; + iLastButtonId = i+1; + bWasButttonBefore = !b->isSep(); + } + + int nFreeSpace = nBarSize - nUsedWidth; + + for (i=iFirstButtonId; i < iLastButtonId; i++) { + TopButtonInt *b = Buttons[i]; + if (b->hwnd == NULL) + continue; + + bool bOldVisible = IsWindowVisible(b->hwnd) != 0; + if (bOldVisible != b->isVisible()) + g_ctrl->bOrderChanged = TRUE; + + if ( b->isVisible()) { + hdwp = DeferWindowPos(hdwp, b->hwnd, NULL, nextX, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + if ( b->isSep()) + nextX += SEPWIDTH+2; + else + nextX += g_ctrl->nButtonWidth + g_ctrl->nButtonSpace; + } + else hdwp = DeferWindowPos(hdwp, Buttons[i]->hwnd, NULL, nextX, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW); + } + + if (iFirstButtonId == iLastButtonId) + break; + + iFirstButtonId = iLastButtonId; + y += g_ctrl->nButtonHeight + g_ctrl->nButtonSpace; + nextX = 0; + if (g_ctrl->bSingleLine) + break; + } + while (iFirstButtonId < Buttons.getCount() && y >= 0 && (g_ctrl->bAutoSize || (y + g_ctrl->nButtonHeight <= rcClient.bottom - rcClient.top))); + + if (hdwp) + EndDeferWindowPos(hdwp); + + return (g_ctrl->nButtonHeight + g_ctrl->nButtonSpace)*nLineCount - g_ctrl->nButtonSpace; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Toolbar services + +// wparam = (TTBButton*)lpTTBButton +// lparam = hLangpack +INT_PTR TTBAddButton(WPARAM wParam, LPARAM lParam) +{ + if (wParam == 0) + return -1; + + TTBButton *but = (TTBButton*)wParam; + if (but->cbSize != sizeof(TTBButton) && but->cbSize != OLD_TBBUTTON_SIZE) + return -1; + + if ( !(but->dwFlags && TTBBF_ISLBUTTON) && nameexists(but->name)) + return -1; + + TopButtonInt* b = CreateButton(but); + b->hLangpack = (int)lParam; + b->LoadSettings(); + b->CreateWnd(); + if (b->hwnd == NULL) { + delete b; + return -1; + } + { + mir_cslock lck(csButtonsHook); + Buttons.insert(b); + } + + g_ctrl->bOrderChanged = TRUE; + ArrangeButtons(); + AddToOptions(b); + return b->id; +} + +// wparam = (HANDLE)hTTButton +// lparam = 0 +INT_PTR TTBRemoveButton(WPARAM wParam, LPARAM lParam) +{ + mir_cslock lck(csButtonsHook); + + int idx; + TopButtonInt* b = idtopos(wParam, &idx); + if (b == NULL) + return -1; + + RemoveFromOptions(b->id); + + Buttons.remove(idx); + delete b; + + g_ctrl->bOrderChanged = TRUE; + ArrangeButtons(); + return 0; +} + +// wparam = hTTBButton +// lparam = state +INT_PTR TTBSetState(WPARAM wParam, LPARAM lParam) +{ + mir_cslock lck(csButtonsHook); + + TopButtonInt* b = idtopos(wParam); + if (b == NULL) + return -1; + + b->bPushed = (lParam & TTBST_PUSHED)?TRUE:FALSE; + b->bPushed = (lParam & TTBST_RELEASED)?FALSE:TRUE; + b->SetBitmap(); + return 0; +} + +// wparam = hTTBButton +// lparam = 0 +//return = state +INT_PTR TTBGetState(WPARAM wParam, LPARAM lParam) +{ + mir_cslock lck(csButtonsHook); + TopButtonInt* b = idtopos(wParam); + if (b == NULL) + return -1; + + int retval = (b->bPushed == TRUE) ? TTBST_PUSHED : TTBST_RELEASED; + return retval; +} + +INT_PTR TTBGetOptions(WPARAM wParam, LPARAM lParam) +{ + INT_PTR retval; + + mir_cslock lck(csButtonsHook); + TopButtonInt* b = idtopos(wParam); + if (b == NULL) + return -1; + + switch(LOWORD(wParam)) { + case TTBO_FLAGS: + retval = b->dwFlags & (~TTBBF_PUSHED); + if (b->bPushed) + retval |= TTBBF_PUSHED; + break; + + case TTBO_TIPNAME: + retval = (INT_PTR)b->ptszTooltip; + break; + + case TTBO_ALLDATA: + if (lParam) { + lpTTBButton lpTTB = (lpTTBButton)lParam; + if (lpTTB->cbSize != sizeof(TTBButton)) + break; + + lpTTB->dwFlags = b->dwFlags & (~TTBBF_PUSHED); + if (b->bPushed) + lpTTB->dwFlags |= TTBBF_PUSHED; + + lpTTB->hIconDn = b->hIconDn; + lpTTB->hIconUp = b->hIconUp; + + lpTTB->lParamUp = b->lParamUp; + lpTTB->wParamUp = b->wParamUp; + lpTTB->lParamDown = b->lParamDown; + lpTTB->wParamDown = b->wParamDown; + + if (b->dwFlags & TTBBF_ISLBUTTON) + replaceStrT(lpTTB->program, b->ptszProgram); + else + replaceStr(lpTTB->pszService, b->pszService); + + retval = ( INT_PTR )lpTTB; + } + break; + + default: + retval = -1; + break; + } + + return retval; +} + +INT_PTR TTBSetOptions(WPARAM wParam, LPARAM lParam) +{ + int retval; + + mir_cslock lck(csButtonsHook); + TopButtonInt* b = idtopos(HIWORD(wParam)); + if (b == NULL) + return -1; + + switch(LOWORD(wParam)) { + case TTBO_FLAGS: + if (b->dwFlags == lParam) + break; + + retval = b->CheckFlags(lParam); + + if (retval & TTBBF_PUSHED) + b->SetBitmap(); + if (retval & TTBBF_VISIBLE) { + ArrangeButtons(); + b->SaveSettings(0,0); + } + + retval = 1; + break; + + case TTBO_TIPNAME: + if (lParam == 0) + break; + + replaceStrT(b->ptszTooltip, TranslateTS( _A2T((LPCSTR)lParam))); + SendMessage(b->hwnd,BUTTONADDTOOLTIP,(WPARAM)b->ptszTooltip,BATF_UNICODE); + retval = 1; + break; + + case TTBO_ALLDATA: + if (lParam) { + lpTTBButton lpTTB = (lpTTBButton)lParam; + if (lpTTB->cbSize != sizeof(TTBButton)) + break; + + retval = b->CheckFlags(lpTTB->dwFlags); + + int changed = 0; + if (b->hIconUp != lpTTB->hIconUp) { + b->hIconUp = lpTTB->hIconUp; + changed = 1; + } + if (b->hIconDn != lpTTB->hIconDn) { + b->hIconDn = lpTTB->hIconDn; + changed = 1; + } + if (changed) + b->SetBitmap(); + + if (retval & TTBBF_VISIBLE) { + ArrangeButtons(); + b->SaveSettings(0,0); + } + + if (b->dwFlags & TTBBF_ISLBUTTON) + replaceStrT(b->ptszProgram, lpTTB->program); + else + replaceStr(b->pszService, lpTTB->pszService); + + b->lParamUp = lpTTB->lParamUp; + b->wParamUp = lpTTB->wParamUp; + b->lParamDown = lpTTB->lParamDown; + b->wParamDown = lpTTB->wParamDown; + + retval = 1; + } + break; + + default: + retval = -1; + break; + } + + return retval; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Reload all icons from their icolib handles + +int OnIconChange(WPARAM wParam, LPARAM lParam) +{ + mir_cslock lck(csButtonsHook); + for (int i = 0; i < Buttons.getCount(); i++) { + TopButtonInt* b = Buttons[i]; + if ( !b->hIconHandleUp && !b->hIconHandleDn) + continue; + + if (b->hIconHandleUp) { + Skin_ReleaseIcon(b->hIconUp); + b->hIconUp = Skin_GetIconByHandle(b->hIconHandleUp); + } + if (b->hIconHandleDn) { + Skin_ReleaseIcon(b->hIconDn); + b->hIconDn = Skin_GetIconByHandle(b->hIconHandleDn); + } + DestroyWindow(b->hwnd); + b->CreateWnd(); + } + + if (g_ctrl->hWnd) { + g_ctrl->bOrderChanged = true; + PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, TRUE, 0); + } + + return 0; +} + +static int OnBGChange(WPARAM wParam, LPARAM lParam) +{ + LoadBackgroundOptions(); + return 0; +} + +static INT_PTR TTBSetCustomProc(WPARAM wParam, LPARAM lParam) +{ + g_CustomProc = (pfnCustomProc)wParam; + g_CustomProcParam = lParam; + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Adds buttons of plugins being loaded. lParam = HINSTANCE + +int OnPluginLoad(WPARAM wParam, LPARAM lParam) +{ + CallPluginEventHook((HINSTANCE)lParam, hTTBModuleLoaded, 0, 0); + if (g_ctrl->hWnd && g_ctrl->bOrderChanged) + PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, TRUE, 0); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Removes buttons of plugins being unloaded. lParam = HINSTANCE + +int OnPluginUnload(WPARAM wParam, LPARAM lParam) +{ + int hLangpack = CallService(MS_LANGPACK_LOOKUPHANDLE, 0, lParam); + if (hLangpack) { + bool bNeedUpdate = false; + mir_cslock lck(csButtonsHook); + + for (int i=Buttons.getCount()-1; i >= 0; i--) + if (Buttons[i]->hLangpack == hLangpack) { + TTBRemoveButton(Buttons[i]->id, 0); + bNeedUpdate = true; + } + + if (bNeedUpdate) { + ArrangeButtons(); + if (g_ctrl->hWnd) + PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, TRUE, 0); + } + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int OnModulesLoad(WPARAM wParam, LPARAM lParam) +{ + LoadAllSeparators(); + LoadAllLButs(); + + ArrangeButtons(); + + HANDLE hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);//anonymous event + if (hEvent != 0) + CallService(MS_SYSTEM_WAITONHANDLE, (WPARAM)hEvent, (LPARAM)"TTB_ONSTARTUPFIRE"); + + if ( HookEvent(ME_BACKGROUNDCONFIG_CHANGED, OnBGChange)) { + char buf[256]; + sprintf(buf, "TopToolBar Background/%s", TTB_OPTDIR); + CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)buf, 0); + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static LRESULT CALLBACK TTBButtonWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT lResult = buttonWndProc(hwnd, msg, wParam, lParam); + + if (msg == WM_NCCREATE) { + TopButtonInt* p = (TopButtonInt*)((CREATESTRUCT*)lParam)->lpCreateParams; + if (g_CustomProc) + g_CustomProc((HANDLE)p->id, hwnd, g_CustomProcParam); + } + + return lResult; +} + +int LoadToolbarModule() +{ + if ( !ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) { + if ( !db_get_b(NULL, TTB_OPTDIR, "WarningDone", 0)) + MessageBox(0, TranslateT("Frames Services not found - plugin disabled.You need MultiWindow plugin."), _T("TopToolBar"), 0); + db_set_b(NULL, TTB_OPTDIR, "WarningDone", 1); + return 1; + } + + g_ctrl = (TTBCtrl*)mir_calloc( sizeof(TTBCtrl)); + g_ctrl->nButtonHeight = db_get_dw(0, TTB_OPTDIR, "BUTTHEIGHT", DEFBUTTHEIGHT); + g_ctrl->nButtonWidth = db_get_dw(0, TTB_OPTDIR, "BUTTWIDTH", DEFBUTTWIDTH); + g_ctrl->nButtonSpace = db_get_dw(0, TTB_OPTDIR, "BUTTGAP", DEFBUTTGAP); + g_ctrl->nLastHeight = db_get_dw(0, TTB_OPTDIR, "LastHeight", DEFBUTTHEIGHT); + + g_ctrl->bFlatButtons = db_get_b(0, TTB_OPTDIR, "UseFlatButton", true); + g_ctrl->bSingleLine = db_get_b(0, TTB_OPTDIR, "SingleLine", false); + g_ctrl->bAutoSize = db_get_b(0, TTB_OPTDIR, "AutoSize", true); + + db_unset(NULL, TTB_OPTDIR, "WarningDone"); + + InitializeCriticalSection(&csButtonsHook); + hBmpSeparator = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SEP)); + + HookEvent(ME_SYSTEM_MODULELOAD, OnPluginLoad); + HookEvent(ME_SYSTEM_MODULEUNLOAD, OnPluginUnload); + HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoad); + HookEvent(ME_SKIN2_ICONSCHANGED, OnIconChange); + HookEvent(ME_OPT_INITIALISE, TTBOptInit); + + hTTBModuleLoaded = CreateHookableEvent(ME_TTB_MODULELOADED); + hTTBInitButtons = CreateHookableEvent(ME_TTB_INITBUTTONS); + SetHookDefaultForHookableEvent(hTTBInitButtons, InitInternalButtons); + + CreateServiceFunction("TopToolBar/AddButton", TTBAddButton); + CreateServiceFunction(MS_TTB_REMOVEBUTTON, TTBRemoveButton); + + CreateServiceFunction(MS_TTB_SETBUTTONSTATE, TTBSetState); + CreateServiceFunction(MS_TTB_GETBUTTONSTATE, TTBGetState); + + CreateServiceFunction(MS_TTB_GETBUTTONOPTIONS, TTBGetOptions); + CreateServiceFunction(MS_TTB_SETBUTTONOPTIONS, TTBSetOptions); + + CreateServiceFunction(TTB_LAUNCHSERVICE, LaunchService); + + CreateServiceFunction("TopToolBar/SetCustomProc", TTBSetCustomProc); + CreateServiceFunction("TTB_ONSTARTUPFIRE", OnEventFire); + + buttonWndProc = (WNDPROC)CallService("Button/GetWindowProc",0,0); + WNDCLASSEX wc = {0}; + wc.cbSize = sizeof(wc); + wc.lpszClassName = TTB_BUTTON_CLASS; + wc.lpfnWndProc = TTBButtonWndProc; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.cbWndExtra = sizeof(void*); + wc.hbrBackground = 0; + wc.style = CS_GLOBALCLASS; + RegisterClassEx(&wc); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int UnloadToolbarModule() +{ + DestroyHookableEvent(hTTBModuleLoaded); + DestroyHookableEvent(hTTBInitButtons); + + DeleteObject(hBmpSeparator); + DeleteCriticalSection(&csButtonsHook); + + for (int i=0; i < Buttons.getCount(); i++) + delete Buttons[i]; + Buttons.destroy(); + + mir_free(g_ctrl); + return 0; +} diff --git a/plugins/TopToolBar/src/toolbarwnd.cpp b/plugins/TopToolBar/src/toolbarwnd.cpp new file mode 100644 index 0000000000..e3f19f693b --- /dev/null +++ b/plugins/TopToolBar/src/toolbarwnd.cpp @@ -0,0 +1,330 @@ + +#include "common.h" + +COLORREF bkColour; +HBITMAP hBmpBackground, hBmpSeparator; +int backgroundBmpUse; + +static TCHAR pluginname[] = _T("TopToolBar"); + +///////////////////////////////////////////////////////////////////////////////////////// +// Toolbar window procedure + +static void PaintToolbar(HWND hwnd) +{ + InvalidateRect(hwnd, 0, FALSE); + + PAINTSTRUCT paintst; + HDC hdc = BeginPaint(hwnd, &paintst); + RECT *rcPaint = &paintst.rcPaint; + + RECT clRect; + GetClientRect(hwnd, &clRect); + if (rcPaint == NULL) rcPaint = &clRect; + + int yScroll = 0; + int y = -yScroll; + + HDC hdcMem = CreateCompatibleDC(hdc); + HBITMAP hBmpOsb = CreateBitmap(clRect.right, clRect.bottom, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL); + HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcMem, hBmpOsb); + SetBkMode(hdcMem, TRANSPARENT); + + HBRUSH hBrush = CreateSolidBrush(bkColour); + HBRUSH hoBrush = (HBRUSH)SelectObject(hdcMem, hBrush); + FillRect(hdcMem, rcPaint, hBrush); + SelectObject(hdcMem, hoBrush); + DeleteObject(hBrush); + if (hBmpBackground) { + BITMAP bmp; + GetObject(hBmpBackground, sizeof(bmp), &bmp); + + HDC hdcBmp = CreateCompatibleDC(hdcMem); + SelectObject(hdcBmp, hBmpBackground); + int y = backgroundBmpUse & CLBF_SCROLL ? -yScroll : 0; + int maxx = backgroundBmpUse & CLBF_TILEH ? clRect.right : 1; + int maxy = backgroundBmpUse & CLBF_TILEV ? maxy = rcPaint->bottom : y+1; + + int destw, desth; + switch(backgroundBmpUse & CLBM_TYPE) { + case CLB_STRETCH: + if (backgroundBmpUse&CLBF_PROPORTIONAL) { + if (clRect.right * bmp.bmHeight < clRect.bottom * bmp.bmWidth) { + desth = clRect.bottom; + destw = desth * bmp.bmWidth/bmp.bmHeight; + } + else { + destw = clRect.right; + desth = destw * bmp.bmHeight/bmp.bmWidth; + } + } + else { + destw = clRect.right; + desth = clRect.bottom; + } + break; + case CLB_STRETCHH: + if (backgroundBmpUse & CLBF_PROPORTIONAL) { + destw = clRect.right; + desth = destw * bmp.bmHeight/bmp.bmWidth; + if (backgroundBmpUse & CLBF_TILEVTOROWHEIGHT) + desth = g_ctrl->nButtonHeight+2; + } + else { + destw = clRect.right; + desth = bmp.bmHeight; + } + break; + case CLB_STRETCHV: + if (backgroundBmpUse & CLBF_PROPORTIONAL) { + desth = clRect.bottom; + destw = desth*bmp.bmWidth/bmp.bmHeight; + } + else { + destw = bmp.bmWidth; + desth = clRect.bottom; + } + break; + default: //clb_topleft + destw = bmp.bmWidth; + desth = bmp.bmHeight; + if (backgroundBmpUse & CLBF_TILEVTOROWHEIGHT) + desth = g_ctrl->nButtonHeight+2; + break; + } + + for (; y < maxy; y += desth) { + if (y < rcPaint->top - desth) + continue; + + for (int x = 0; x < maxx; x += destw) + StretchBlt(hdcMem, x, y, destw, desth, hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); + } + DeleteDC(hdcBmp); + } + BitBlt(hdc, rcPaint->left, rcPaint->top, rcPaint->right-rcPaint->left, rcPaint->bottom-rcPaint->top, hdcMem, rcPaint->left, rcPaint->top, SRCCOPY); + SelectObject(hdcMem, hOldBmp); + DeleteDC(hdcMem); + DeleteObject(hBmpOsb); + + paintst.fErase = FALSE; + EndPaint(hwnd, &paintst); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK TopToolBarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static bool supressRepos = false; + + if (g_ctrl->fnWindowProc != NULL) + if ( g_ctrl->fnWindowProc(hwnd, msg, wParam, lParam)) + return g_ctrl->lResult; + + switch(msg) { + case WM_CREATE: + g_ctrl->hWnd = hwnd; + PostMessage(hwnd, TTB_UPDATEFRAMEVISIBILITY, 1, 0); + return FALSE; + + case WM_MOVE: + return 0; + + case WM_WINDOWPOSCHANGING: + case WM_SIZE: + if (g_ctrl->nLastHeight != HIWORD(lParam)) { + db_set_dw(0, TTB_OPTDIR, "LastHeight", g_ctrl->nLastHeight = HIWORD(lParam)); + ArrangeButtons(); + } + if (supressRepos) { + supressRepos = false; + break; + } + // fall through + + case TTB_REPOSBUTTONS: + if (g_ctrl->hWnd == hwnd) { + int iHeight = ArrangeButtons(); + if ( g_ctrl->bAutoSize) { + RECT rcClient; + GetClientRect(g_ctrl->hWnd, &rcClient); + if (rcClient.bottom - rcClient.top != iHeight && iHeight) { + supressRepos = true; + PostMessage(hwnd, TTB_UPDATEFRAMEVISIBILITY, -1, 0); + } + } + return 0; + } + break; + + case WM_NCPAINT: + case WM_PAINT: + PaintToolbar(hwnd); + return 0; + + case WM_LBUTTONDOWN: + if (db_get_b(NULL, "CLUI", "ClientAreaDrag", 0)) { + POINT pt; + GetCursorPos(&pt); + return SendMessage(GetParent(hwnd), WM_SYSCOMMAND, SC_MOVE|HTCAPTION, MAKELPARAM(pt.x, pt.y)); + } + return 0; + + case WM_COMMAND: + switch (HIWORD(wParam)) { + case BN_CLICKED: + case BN_DOUBLECLICKED: + { + int id = GetWindowLongPtr((HWND)lParam, GWLP_USERDATA); + if (id != 0) { + mir_cslock lck(csButtonsHook); + TopButtonInt* b = idtopos(id); + if (b == NULL || b->isSep()) + return 0; + + if (b->dwFlags & TTBBF_ASPUSHBUTTON) + b->bPushed = !b->bPushed; + + if (b->bPushed) { //Dn -> Up + if (!(b->dwFlags & TTBBF_ISLBUTTON)) // must be always true + if (b->pszService != NULL) + CallService(b->pszService, b->wParamUp, b->lParamUp); + } + else { //Up -> Dn + if (b->pszService != NULL) + CallService(b->pszService, b->wParamDown, b->lParamDown); + } + + b->SetBitmap(); + } + } + break; + } + break; + + case TTB_UPDATEFRAMEVISIBILITY: + { + BOOL vis=(BOOL)wParam; + BOOL curvis = IsWindowVisible(hwnd); + bool bResize = false; + int Height = ArrangeButtons(); + + if (g_ctrl->bAutoSize) { + INT_PTR frameopt = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, g_ctrl->hFrame), 0); + if (Height != frameopt) { + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, g_ctrl->hFrame), Height); + bResize = TRUE; + } + } + + if (g_ctrl->bOrderChanged) + bResize = TRUE, g_ctrl->bOrderChanged = FALSE; + + if ((curvis != vis || bResize) && vis != -1) { + INT_PTR frameopt = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, g_ctrl->hFrame), 0); + frameopt &= ~F_VISIBLE; + frameopt |= vis ? F_VISIBLE : 0; + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, g_ctrl->hFrame), frameopt); + } + } + break; + + case TTB_SETCUSTOM: + { + TTBCtrlCustomize *pCustom = (TTBCtrlCustomize*)lParam; + if (pCustom == NULL || g_ctrl->fnWindowProc) + break; + + g_ctrl = (TTBCtrl*)mir_realloc(g_ctrl, pCustom->cbLen); + if (pCustom->cbLen > sizeof(TTBCtrl)) + memset(g_ctrl+1, 0, pCustom->cbLen - sizeof(TTBCtrl)); + + g_ctrl->fnWindowProc = pCustom->fnWindowProc; + SetWindowLongPtr(hwnd, 0, (LONG_PTR)g_ctrl); + } + break; + + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return(TRUE); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR OnEventFire(WPARAM wParam, LPARAM lParam) +{ + CallService(MS_SYSTEM_REMOVEWAIT, wParam, 0); + CloseHandle((HANDLE)wParam); + + HWND parent = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); + if (parent == NULL) // no clist, no buttons + return -1; + + WNDCLASS wndclass = { 0 }; + wndclass.lpfnWndProc = TopToolBarProc; + wndclass.cbWndExtra = sizeof(void*); + wndclass.hInstance = hInst; + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); + wndclass.lpszClassName = pluginname; + RegisterClass(&wndclass); + + g_ctrl->pButtonList = (SortedList*)&Buttons; + g_ctrl->hWnd = CreateWindow(pluginname, _T("Toolbar"), + WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + 0, 0, 0, g_ctrl->nLastHeight, parent, NULL, hInst, NULL); + SetWindowLongPtr(g_ctrl->hWnd, 0, (LPARAM)g_ctrl); + + LoadBackgroundOptions(); + + // if we're working in skinned clist, receive the standard buttons & customizations + if (g_CustomProc && g_ctrl->hWnd) + g_CustomProc(TTB_WINDOW_HANDLE, g_ctrl->hWnd, g_CustomProcParam); + + // if there's no customized frames, create our own + if (g_ctrl->hFrame == NULL) { + CLISTFrame Frame = { 0 }; + Frame.cbSize = sizeof(Frame); + Frame.tname = _T("Toolbar"); + Frame.hWnd = g_ctrl->hWnd; + Frame.align = alTop; + Frame.Flags = F_VISIBLE | F_NOBORDER | F_LOCKED | F_TCHAR; + Frame.height = g_ctrl->nLastHeight; + g_ctrl->hFrame = (HANDLE)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0); + } + + // receive all buttons + NotifyEventHooks(hTTBInitButtons, 0, 0); + NotifyEventHooks(hTTBModuleLoaded, 0, 0); + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int LoadBackgroundOptions() +{ + //load options + bkColour = DBGetContactSettingDword(NULL, TTB_OPTDIR, "BkColour", TTBDEFAULT_BKCOLOUR); + if (hBmpBackground) { + DeleteObject(hBmpBackground); + hBmpBackground = NULL; + } + + if (db_get_b(NULL, TTB_OPTDIR, "UseBitmap", TTBDEFAULT_USEBITMAP)) { + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, TTB_OPTDIR, "BkBitmap", &dbv)) { + hBmpBackground = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (LPARAM)dbv.pszVal); + DBFreeVariant(&dbv); + } + } + backgroundBmpUse = DBGetContactSettingWord(NULL, TTB_OPTDIR, "BkBmpUse", TTBDEFAULT_BKBMPUSE); + + RECT rc; + GetClientRect(g_ctrl->hWnd, &rc); + InvalidateRect(g_ctrl->hWnd, &rc, TRUE); + UpdateWindow(g_ctrl->hWnd); + + return 0; +} diff --git a/plugins/TopToolBar/src/topbutton.cpp b/plugins/TopToolBar/src/topbutton.cpp new file mode 100644 index 0000000000..8e2f8a1cfd --- /dev/null +++ b/plugins/TopToolBar/src/topbutton.cpp @@ -0,0 +1,178 @@ + +#include "common.h" + +#define BitChanged(c) (dwFlags ^ Flags) & c + +static int maxid = 10000; + +TopButtonInt::~TopButtonInt() +{ + if (hwnd) + DestroyWindow(hwnd); + + if (dwFlags & TTBBF_ISLBUTTON) { + mir_free(ptszProgram); + } + else if (pszService != NULL) + mir_free(pszService); + + mir_free(pszName); + mir_free(ptszTooltip); + mir_free(ptszTooltipDn); + mir_free(ptszTooltipUp); +} + +DWORD TopButtonInt::CheckFlags(DWORD Flags) +{ + int res = 0; + if ( BitChanged(TTBBF_DISABLED)) { + dwFlags ^= TTBBF_DISABLED; + EnableWindow(hwnd,(dwFlags & TTBBF_DISABLED)?FALSE:TRUE); + } + if ( BitChanged(TTBBF_ASPUSHBUTTON)) { + dwFlags ^= TTBBF_ASPUSHBUTTON; + SendMessage(hwnd, BUTTONSETASPUSHBTN, (dwFlags & TTBBF_ASPUSHBUTTON)?1:0, 0); + } + if ( BitChanged(TTBBF_SHOWTOOLTIP)) { + dwFlags ^= TTBBF_SHOWTOOLTIP; + SendMessage(hwnd,BUTTONADDTOOLTIP, + (WPARAM)((dwFlags & TTBBF_SHOWTOOLTIP) ? ptszTooltip : _T("")), BATF_TCHAR); + } + // next settings changing visual side, requires additional actions + if ( BitChanged(TTBBF_VISIBLE)) { + dwFlags ^= TTBBF_VISIBLE; + res |= TTBBF_VISIBLE; + } + if ( BitChanged(TTBBF_PUSHED)) { + dwFlags ^= TTBBF_PUSHED; + res |= TTBBF_PUSHED; + bPushed = (dwFlags & TTBBF_PUSHED) ? TRUE : FALSE; + } + return res; +} + +void TopButtonInt::CreateWnd() +{ + if ( !(dwFlags & TTBBF_ISSEPARATOR)) { + hwnd = CreateWindow(TTB_BUTTON_CLASS, _T(""), BS_PUSHBUTTON|WS_CHILD|WS_TABSTOP|SS_NOTIFY, 0, 0, g_ctrl->nButtonWidth, g_ctrl->nButtonHeight, g_ctrl->hWnd, NULL, hInst, this); + + if (dwFlags & TTBBF_ASPUSHBUTTON) + SendMessage(hwnd, BUTTONSETASPUSHBTN, 1, 0); + + if (db_get_b(0, TTB_OPTDIR, "UseFlatButton", 1)) + SendMessage(hwnd, BUTTONSETASFLATBTN, TRUE, 0); + + EnableWindow(hwnd,(dwFlags & TTBBF_DISABLED)?FALSE:TRUE); + } + // maybe SEPWIDTH, not g_ctrl->nButtonWidth? + else + hwnd = CreateWindow( _T("STATIC"), _T(""), WS_CHILD|SS_NOTIFY, 0, 0, g_ctrl->nButtonWidth, g_ctrl->nButtonHeight, g_ctrl->hWnd, NULL, hInst, 0); + + SetWindowLongPtr(hwnd, GWLP_USERDATA, id); + SetBitmap(); +} + +void TopButtonInt::LoadSettings() +{ + char buf[255]; + + BYTE oldv = isVisible(); + dwFlags = dwFlags & (~TTBBF_VISIBLE); + + if (dwFlags & TTBBF_ISSEPARATOR) { + char buf1[10]; + _itoa(wParamDown, buf1, 10); + char buf2[20]; + AS(buf2, "Sep", buf1); + + arrangedpos = db_get_b(0, TTB_OPTDIR, AS(buf, buf2, "_Position"), Buttons.getCount()); + if ( db_get_b(0, TTB_OPTDIR, AS(buf, buf2, "_Visible"), oldv) > 0 ) + dwFlags |= TTBBF_VISIBLE; + } + else if ((dwFlags & TTBBF_ISLBUTTON ) && (dwFlags & TTBBF_INTERNAL)) { + char buf1[10]; + _itoa(wParamDown, buf1, 10); + char buf2[20]; + AS(buf2, "Launch", buf1); + + mir_free(pszName); + pszName = DBGetString(0, TTB_OPTDIR, AS(buf, buf2, "_name")); + + mir_free(ptszProgram); + ptszProgram = DBGetStringT(0, TTB_OPTDIR, AS(buf, buf2, "_lpath")); + + arrangedpos = db_get_b(0, TTB_OPTDIR, AS(buf, buf2, "_Position"), Buttons.getCount()); + if ( db_get_b(0, TTB_OPTDIR, AS(buf, buf2, "_Visible"), oldv) > 0 ) + dwFlags |= TTBBF_VISIBLE; + } + else { + arrangedpos = db_get_b(0, TTB_OPTDIR, AS(buf, pszName, "_Position"), Buttons.getCount()); + if ( db_get_b(0, TTB_OPTDIR, AS(buf, pszName, "_Visible"), oldv) > 0 ) + dwFlags |= TTBBF_VISIBLE; + } + + if (Buttons.getIndex(this) != -1) + arrangedpos = maxid++; +} + +void TopButtonInt::SaveSettings(int *SepCnt, int *LaunchCnt) +{ + char buf[255]; + + if (SepCnt && (dwFlags & TTBBF_ISSEPARATOR) && (dwFlags & TTBBF_INTERNAL)) { + char buf1[10]; + _itoa(SepCnt[0]++, buf1, 10); + char buf2[20]; + AS(buf2, "Sep", buf1); + + db_set_b(0, TTB_OPTDIR, AS(buf, buf2, "_Position"), arrangedpos); + db_set_b(0, TTB_OPTDIR, AS(buf, buf2, "_Visible"), isVisible()); + } + else if (LaunchCnt && (dwFlags & TTBBF_ISLBUTTON ) && (dwFlags & TTBBF_INTERNAL)) { + char buf1[10]; + _itoa(LaunchCnt[0]++, buf1, 10); + char buf2[20]; + AS(buf2, "Launch", buf1); + + DBWriteContactSettingString(0, TTB_OPTDIR, AS(buf, buf2, "_name"), pszName); + DBWriteContactSettingTString(0, TTB_OPTDIR, AS(buf, buf2, "_lpath"), ptszProgram); + db_set_b(0, TTB_OPTDIR, AS(buf, buf2, "_Position"), arrangedpos); + db_set_b(0, TTB_OPTDIR, AS(buf, buf2, "_Visible"), isVisible()); + } + else { + db_set_b(0, TTB_OPTDIR, AS(buf, pszName, "_Position"), arrangedpos); + db_set_b(0, TTB_OPTDIR, AS(buf, pszName, "_Visible"), isVisible()); + } +} + +void TopButtonInt::SetBitmap() +{ + int curstyle = GetWindowLongPtr(hwnd, GWL_STYLE); + curstyle &= (~SS_BITMAP); + curstyle &= (~SS_ICON); + + if (dwFlags & TTBBF_ISSEPARATOR) { + SetWindowLongPtr(hwnd, GWL_STYLE, curstyle | SS_BITMAP); + SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmpSeparator); + SendMessage(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmpSeparator); + } + else { + if (GetWindowLongPtr(hwnd, GWL_STYLE) & SS_ICON) + SetWindowLongPtr(hwnd, GWL_STYLE, curstyle | SS_ICON); + + TCHAR* pTooltip; + if (bPushed) { + SendMessage(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)((hIconDn) ? hIconDn : hIconUp)); + SendMessage(hwnd, BM_SETCHECK, BST_CHECKED, 0); + + pTooltip = (ptszTooltipDn) ? ptszTooltipDn : ptszTooltipUp; + } + else { + SendMessage(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIconUp); + SendMessage(hwnd, BM_SETCHECK, BST_UNCHECKED, 0); + pTooltip = ptszTooltipUp; + } + if (pTooltip) + SendMessage(hwnd, BUTTONADDTOOLTIP, (WPARAM)TranslateTH(hLangpack, pTooltip), BATF_TCHAR); + } +} diff --git a/plugins/TopToolBar/src/ttbopt.cpp b/plugins/TopToolBar/src/ttbopt.cpp new file mode 100644 index 0000000000..db7d78dcb5 --- /dev/null +++ b/plugins/TopToolBar/src/ttbopt.cpp @@ -0,0 +1,559 @@ +#include "common.h" + +static HWND OptionshWnd; + +struct OrderData +{ + int dragging; + HTREEITEM hDragItem; + HIMAGELIST himlButtonIcons; +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +static HTREEITEM AddLine(HWND hTree,TopButtonInt *b, HTREEITEM hItem, HIMAGELIST il) +{ + TVINSERTSTRUCT tvis = { 0 }; + tvis.hInsertAfter = hItem; + tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + + int index; + TCHAR* tmp; + + if (b->dwFlags & TTBBF_ISSEPARATOR) { + tvis.item.pszText = _T("------------------"); + index = -1; + } + else { + if (b->hIconHandleUp) { + HICON hIcon = Skin_GetIconByHandle(b->hIconHandleUp); + index = ImageList_AddIcon(il, hIcon); + Skin_ReleaseIcon(hIcon); + } + else index = ImageList_AddIcon(il, b->hIconUp); + + tmp = mir_a2t( b->pszName ); + tvis.item.pszText = TranslateTS(tmp); + } + tvis.item.iImage = tvis.item.iSelectedImage = index; + + tvis.item.lParam = (LPARAM)b; + HTREEITEM hti = TreeView_InsertItem(hTree, &tvis); + + if (!(b->dwFlags & TTBBF_ISSEPARATOR)) + mir_free(tmp); + + TreeView_SetCheckState(hTree, hti, b->isVisible()); + return hti; +} + +static int BuildTree(HWND hwndDlg) +{ + HWND hTree = GetDlgItem(hwndDlg, IDC_BUTTONORDERTREE); + OrderData *dat = (OrderData*)GetWindowLongPtr(hTree, GWLP_USERDATA); + + dat->himlButtonIcons = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 2, 2); + TreeView_SetImageList(hTree, dat->himlButtonIcons, TVSIL_NORMAL); + SetWindowLongPtr(hTree, GWL_STYLE, GetWindowLongPtr(hTree,GWL_STYLE)|TVS_NOHSCROLL); + TreeView_DeleteAllItems(hTree); + + if (Buttons.getCount() == 0) + return FALSE; + + for (int i = 0; i < Buttons.getCount(); i++) + AddLine(hTree, Buttons[i], TVI_LAST, dat->himlButtonIcons); + return TRUE; +} + +static void SaveTree(HWND hwndDlg) +{ + HWND hTree = GetDlgItem(hwndDlg, IDC_BUTTONORDERTREE); + + TVITEM tvi = { 0 }; + tvi.hItem = TreeView_GetRoot(hTree); + tvi.stateMask = TVIS_STATEIMAGEMASK; + tvi.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_STATE; + + LIST tmpList(8); + + while(tvi.hItem != NULL) { + TreeView_GetItem(hTree, &tvi); + + TopButtonInt* btn = (TopButtonInt*)tvi.lParam; + Buttons.remove(btn); + + if (TreeView_GetCheckState(hTree,tvi.hItem)) + btn->dwFlags |= TTBBF_VISIBLE; + else + btn->dwFlags &= ~TTBBF_VISIBLE; + btn->dwFlags &= ~TTBBF_OPTIONAL; + btn->arrangedpos = tmpList.getCount(); + + tmpList.insert(btn); + tvi.hItem = TreeView_GetNextSibling(hTree, tvi.hItem); + } + { + mir_cslock lck(csButtonsHook); + for (int i=0; i < Buttons.getCount(); i++) + delete Buttons[i]; + + Buttons = tmpList; + tmpList.destroy(); + } + SaveAllButtonsOptions(); +} + +void CancelProcess(HWND hwndDlg) +{ + HWND hTree = GetDlgItem(hwndDlg, IDC_BUTTONORDERTREE); + + TVITEM tvi = { 0 }; + tvi.hItem = TreeView_GetRoot(hTree); + + while(tvi.hItem != NULL) { + tvi.stateMask = TVIS_STATEIMAGEMASK; + tvi.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_STATE; + TreeView_GetItem(hTree, &tvi); + + TopButtonInt* btn = (TopButtonInt*)tvi.lParam; + + if (btn ->dwFlags & TTBBF_OPTIONAL) + delete btn; + + tvi.hItem = TreeView_GetNextSibling(hTree, tvi.hItem); + } +} + +static void RecreateWindows() +{ + { + mir_cslock lck(csButtonsHook); + for (int i = 0; i < Buttons.getCount(); i++) { + TopButtonInt *b = Buttons[i]; + if (b->hwnd) { + DestroyWindow(b->hwnd); + b->CreateWnd(); + } + } + } + + if (g_ctrl->hWnd) + PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, TRUE, 0); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// external functions + +void AddToOptions(TopButtonInt* b) +{ + if (OptionshWnd) { + HWND hTree = GetDlgItem(OptionshWnd, IDC_BUTTONORDERTREE); + OrderData *dat = (OrderData*)GetWindowLongPtr(hTree, GWLP_USERDATA); + AddLine(hTree, b, TVI_LAST, dat->himlButtonIcons); + } +} + +void RemoveFromOptions(int id) +{ + if (OptionshWnd) { + HWND hTree = GetDlgItem(OptionshWnd, IDC_BUTTONORDERTREE); + TVITEM tvi = { 0 }; + tvi.hItem = TreeView_GetRoot(hTree); + tvi.mask = TVIF_PARAM | TVIF_HANDLE; + + TopButtonInt* btn; + while(tvi.hItem != NULL) { + TreeView_GetItem(hTree, &tvi); + btn = (TopButtonInt*)tvi.lParam; + if (btn->id == id) { + // delete if was changed + if (btn->dwFlags & TTBBF_OPTIONAL) + delete btn; + TreeView_DeleteItem(hTree,tvi.hItem); + break; + } + + tvi.hItem = TreeView_GetNextSibling(hTree, tvi.hItem); + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Options window: main + +static INT_PTR CALLBACK ButOrderOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hTree = GetDlgItem(hwndDlg, IDC_BUTTONORDERTREE); + OrderData *dat = (OrderData*)GetWindowLongPtr(hTree, GWLP_USERDATA); + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + dat = (OrderData*)malloc( sizeof(OrderData)); + SetWindowLongPtr(hTree, GWLP_USERDATA, (LONG)dat); + dat->dragging = 0; + + SetWindowLongPtr(hTree, GWL_STYLE, GetWindowLongPtr(hTree, GWL_STYLE)|TVS_NOHSCROLL); + + SetDlgItemInt(hwndDlg, IDC_BUTTHEIGHT, g_ctrl->nButtonHeight, FALSE); + SendDlgItemMessage(hwndDlg, IDC_SPIN_HEIGHT, UDM_SETRANGE, 0, MAKELONG(50,10)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_HEIGHT, UDM_SETPOS, 0, MAKELONG(g_ctrl->nButtonHeight,0)); + + SetDlgItemInt(hwndDlg, IDC_BUTTWIDTH, g_ctrl->nButtonWidth, FALSE); + SendDlgItemMessage(hwndDlg, IDC_SPIN_WIDTH, UDM_SETRANGE, 0, MAKELONG(50,10)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_WIDTH, UDM_SETPOS, 0, MAKELONG(g_ctrl->nButtonWidth,0)); + + SetDlgItemInt(hwndDlg, IDC_BUTTGAP, g_ctrl->nButtonSpace, FALSE); + SendDlgItemMessage(hwndDlg, IDC_SPIN_GAP, UDM_SETRANGE, 0, MAKELONG(20,0)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_GAP, UDM_SETPOS, 0, MAKELONG(g_ctrl->nButtonSpace,0)); + + CheckDlgButton(hwndDlg, IDC_USEFLAT, g_ctrl->bFlatButtons); + CheckDlgButton(hwndDlg, IDC_AUTORESIZE, g_ctrl->bAutoSize); + CheckDlgButton(hwndDlg, IDC_SINGLELINE, g_ctrl->bSingleLine); + + BuildTree(hwndDlg); + EnableWindow(GetDlgItem(hwndDlg, IDC_ENAME), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EPATH), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELLBUTTON), FALSE); + + OptionshWnd = hwndDlg; + return TRUE; + + case WM_COMMAND: + if (HIWORD(wParam) == EN_CHANGE && OptionshWnd) { + switch(LOWORD(wParam)) { + case IDC_ENAME: case IDC_EPATH: + break; + default: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + } + + if ((HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DBLCLK)) { + int ctrlid = LOWORD(wParam); + + //----- Launch buttons ----- + + if (ctrlid == IDC_BROWSE) { + TCHAR str[MAX_PATH]; + OPENFILENAME ofn = {0}; + + GetDlgItemText(hwndDlg, IDC_EPATH, str, sizeof(str)); + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + ofn.hwndOwner = hwndDlg; + ofn.hInstance = NULL; + ofn.lpstrFilter = NULL; + ofn.lpstrFile = str; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER; + ofn.nMaxFile = sizeof(str); + ofn.nMaxFileTitle = MAX_PATH; + ofn.lpstrDefExt = _T("exe"); + if (!GetOpenFileName(&ofn)) + break; + + SetDlgItemText(hwndDlg, IDC_EPATH, str); + + break; + } + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + if (ctrlid == IDC_LBUTTONSET) { + TVITEM tvi ={0}; + tvi.hItem = TreeView_GetSelection(hTree); + if (tvi.hItem == NULL) + break; + + tvi.mask = TVIF_PARAM; + TreeView_GetItem(hTree, &tvi); + + TopButtonInt* btn = (TopButtonInt*)tvi.lParam; + TCHAR buf [256]; + // probably, condition not needs + if (btn->dwFlags & TTBBF_ISLBUTTON) { + if (!(btn->dwFlags & TTBBF_OPTIONAL)) { + // create button + TTBButton ttb = { 0 }; + ttb.cbSize = sizeof(ttb); + ttb.hIconDn = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISLBUTTON | TTBBF_INTERNAL | TTBBF_OPTIONAL; + ttb.name = NULL; + ttb.program = NULL; + int id = btn->id; + btn = CreateButton(&ttb); + btn->id = id; + + tvi.lParam = (LPARAM)btn; + TreeView_SetItem(hTree, &tvi); + } + + GetDlgItemText(hwndDlg, IDC_ENAME, buf, 255); + replaceStr(btn->pszName, _T2A(buf)); + + tvi.mask = TVIF_TEXT; + tvi.pszText = buf; + TreeView_SetItem(hTree, &tvi); + + GetDlgItemText(hwndDlg, IDC_EPATH, buf, 255); + replaceStrT(btn->ptszProgram, buf); + } + break; + } + + if (ctrlid == IDC_ADDLBUTTON) { + // create button + TTBButton ttb = { 0 }; + ttb.cbSize = sizeof(ttb); + ttb.hIconDn = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISLBUTTON | TTBBF_INTERNAL | TTBBF_OPTIONAL; + ttb.name = LPGEN("Default"); + ttb.program = _T("Execute Path"); + TopButtonInt* b = CreateButton(&ttb); + + // get selection for insert + TVITEM tvi = {0}; + tvi.hItem = TreeView_GetSelection(hTree); + + // insert item + AddLine(hTree, b, tvi.hItem, dat->himlButtonIcons); + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + + //----- Separators ----- + + if (ctrlid == IDC_ADDSEP) { + // create button + TTBButton ttb = { 0 }; + ttb.cbSize = sizeof(ttb); + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISSEPARATOR | TTBBF_INTERNAL | TTBBF_OPTIONAL; + TopButtonInt* b = CreateButton(&ttb); + + // get selection for insert + TVITEM tvi = {0}; + tvi.hItem = TreeView_GetSelection(hTree); + + // insert item + AddLine(hTree, b, tvi.hItem, dat->himlButtonIcons); + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + + if (ctrlid == IDC_REMOVEBUTTON) { + TVITEM tvi = {0}; + tvi.hItem = TreeView_GetSelection(hTree); + if (tvi.hItem == NULL) + break; + + tvi.mask = TVIF_PARAM; + TreeView_GetItem(hTree, &tvi); + + TopButtonInt* btn = (TopButtonInt*)tvi.lParam; + // if button enabled for separator and launch only, no need condition + // except possible service button introducing + if (btn->dwFlags & (TTBBF_ISSEPARATOR | TTBBF_ISLBUTTON)) { + // delete if was added in options + if (btn->dwFlags & TTBBF_OPTIONAL) + delete btn; + + TreeView_DeleteItem(hTree,tvi.hItem); + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + } + } + break; + + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + g_ctrl->nButtonHeight = GetDlgItemInt(hwndDlg, IDC_BUTTHEIGHT, NULL, FALSE); + g_ctrl->nButtonWidth = GetDlgItemInt(hwndDlg, IDC_BUTTWIDTH, NULL, FALSE); + g_ctrl->nButtonSpace = GetDlgItemInt(hwndDlg, IDC_BUTTGAP, NULL, FALSE); + + g_ctrl->bFlatButtons = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USEFLAT); + g_ctrl->bAutoSize = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_AUTORESIZE); + g_ctrl->bSingleLine = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SINGLELINE); + + db_set_dw(0, TTB_OPTDIR, "BUTTHEIGHT", g_ctrl->nButtonHeight); + db_set_dw(0, TTB_OPTDIR, "BUTTWIDTH", g_ctrl->nButtonWidth); + db_set_dw(0, TTB_OPTDIR, "BUTTGAP", g_ctrl->nButtonSpace); + + db_set_b(0, TTB_OPTDIR, "UseFlatButton", g_ctrl->bFlatButtons); + db_set_b(0, TTB_OPTDIR, "SingleLine", g_ctrl->bSingleLine); + db_set_b(0, TTB_OPTDIR, "AutoSize", g_ctrl->bAutoSize); + + SaveTree(hwndDlg); + RecreateWindows(); + ArrangeButtons(); + } + break; + + case IDC_BUTTONORDERTREE: + switch (((LPNMHDR)lParam)->code) { + case TVN_BEGINDRAGA: + case TVN_BEGINDRAGW: + SetCapture(hwndDlg); + dat->dragging = 1; + dat->hDragItem = ((LPNMTREEVIEW)lParam)->itemNew.hItem; + TreeView_SelectItem(hTree, dat->hDragItem); + break; + + case NM_CLICK: + { + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(GetMessagePos()); + hti.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hti.pt); + if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &hti)) + if (hti.flags & TVHT_ONITEMSTATEICON) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + TreeView_SelectItem(hTree, hti.hItem); + } + } + break; + + case TVN_SELCHANGEDA: + case TVN_SELCHANGEDW: + { + HTREEITEM hti = TreeView_GetSelection(hTree); + if (hti == NULL) + break; + + TopButtonInt *btn = (TopButtonInt*)((LPNMTREEVIEW)lParam)->itemNew.lParam; + + mir_cslock lck(csButtonsHook); + + if (btn->dwFlags & TTBBF_ISLBUTTON) { + bool enable = (btn->dwFlags & TTBBF_INTERNAL) !=0; + EnableWindow(GetDlgItem(hwndDlg, IDC_ENAME), enable); + EnableWindow(GetDlgItem(hwndDlg, IDC_EPATH), enable); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEBUTTON), enable); + EnableWindow(GetDlgItem(hwndDlg, IDC_LBUTTONSET), enable); + if (btn->pszName != NULL) + SetDlgItemTextA(hwndDlg, IDC_ENAME, btn->pszName); + else + SetDlgItemTextA(hwndDlg, IDC_ENAME, ""); + + if (btn->ptszProgram != NULL) + SetDlgItemText(hwndDlg, IDC_EPATH, btn->ptszProgram); + else + SetDlgItemTextA(hwndDlg, IDC_EPATH, ""); + } + else { + EnableWindow(GetDlgItem(hwndDlg,IDC_REMOVEBUTTON), + (btn->dwFlags & TTBBF_ISSEPARATOR)?TRUE:FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ENAME), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EPATH), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_LBUTTONSET), FALSE); + SetDlgItemTextA(hwndDlg, IDC_ENAME, ""); + SetDlgItemTextA(hwndDlg, IDC_EPATH, ""); + } + } + } + break; + } + break; + + case WM_MOUSEMOVE: + if (dat->dragging) { + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(lParam); + hti.pt.y = (short)HIWORD(lParam); + ClientToScreen(hwndDlg, &hti.pt); + ScreenToClient(hTree, &hti.pt); + TreeView_HitTest(hTree, &hti); + if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) { + HTREEITEM it=hti.hItem; + hti.pt.y -= TreeView_GetItemHeight(hTree)/2; + TreeView_HitTest(hTree, &hti); + if (!(hti.flags&TVHT_ABOVE)) + TreeView_SetInsertMark(hTree,hti.hItem,1); + else + TreeView_SetInsertMark(hTree,it,0); + } + else { + if (hti.flags & TVHT_ABOVE) SendMessage(hTree, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0); + if (hti.flags & TVHT_BELOW) SendMessage(hTree, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); + TreeView_SetInsertMark(hTree, NULL, 0); + } + } + break; + + case WM_LBUTTONUP: + if (dat->dragging) { + TreeView_SetInsertMark(hTree, NULL, 0); + dat->dragging = 0; + ReleaseCapture(); + + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(lParam); + hti.pt.y = (short)HIWORD(lParam); + ClientToScreen(hwndDlg, &hti.pt); + ScreenToClient(hTree, &hti.pt); + hti.pt.y -= TreeView_GetItemHeight(hTree)/2; + TreeView_HitTest(hTree, &hti); + if (dat->hDragItem == hti.hItem) + break; + if (hti.flags&TVHT_ABOVE) + hti.hItem=TVI_FIRST; + + TVITEM tvi; + tvi.mask = TVIF_HANDLE|TVIF_PARAM; + tvi.hItem = (HTREEITEM) dat->hDragItem; + TreeView_GetItem(hTree, &tvi); + if ( (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) || (hti.hItem==TVI_FIRST)) { + TVINSERTSTRUCT tvis; + TCHAR name[128]; + tvis.item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; + tvis.item.stateMask = 0xFFFFFFFF; + tvis.item.pszText = name; + tvis.item.cchTextMax = SIZEOF(name); + tvis.item.hItem = dat->hDragItem; + TreeView_GetItem(hTree, &tvis.item); + + TreeView_DeleteItem(hTree, dat->hDragItem); + tvis.hParent = NULL; + tvis.hInsertAfter = hti.hItem; + TreeView_SelectItem(hTree, TreeView_InsertItem(hTree, &tvis)); + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + break; + + case WM_DESTROY: + if (dat) { + ImageList_Destroy(dat->himlButtonIcons); + free(dat); + } + OptionshWnd = NULL; + break; + } + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int TTBOptInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszGroup = LPGEN("Contact List"); + + odp.position = -1000000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_BUTORDER); + odp.pszTitle = LPGEN("Toolbar"); + odp.pfnDlgProc = ButOrderOpts; + odp.flags = ODPF_BOLDGROUPS | ODPF_EXPERTONLY; + Options_AddPage(wParam, &odp); + return 0; +} diff --git a/plugins/TopToolBar/src/version.h b/plugins/TopToolBar/src/version.h new file mode 100644 index 0000000000..9a489eebee --- /dev/null +++ b/plugins/TopToolBar/src/version.h @@ -0,0 +1,46 @@ +/* + +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. +*/ + +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 8 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 1 + +// other stuff for Version resource +#define __STRINGIFY_IMPL(x) #x +#define __STRINGIFY(x) __STRINGIFY_IMPL(x) + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM +#define __VERSION_STRING __STRINGIFY(__FILEVERSION_STRING_DOTS) + +#define __PLUGIN_DESC "ToptoolBar adds buttons in top frame for fast access." +#define __PLUGIN_LONGDESC __PLUGIN_DESC +#define __PLUGIN_AUTHOR "Bethoven" +#define __PLUGIN_AUTHORWEB "http://nightly.miranda.im/" +#define __PLUGIN_EMAIL "Bethoven@mailgate.ru" +#define __PLUGIN_RIGHTS "© 2003-2008 Bethoven" +#define __PLUGIN_FILE "TopToolbar.dll" +#define __PLUGIN_SHORTNAME "TopToolBar" + +#define __PLUGIN_NAME __PLUGIN_SHORTNAME -- cgit v1.2.3