summaryrefslogtreecommitdiff
path: root/plugins/Clist_modern/modern_docking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Clist_modern/modern_docking.cpp')
-rw-r--r--plugins/Clist_modern/modern_docking.cpp372
1 files changed, 372 insertions, 0 deletions
diff --git a/plugins/Clist_modern/modern_docking.cpp b/plugins/Clist_modern/modern_docking.cpp
new file mode 100644
index 0000000000..a7ffe8e506
--- /dev/null
+++ b/plugins/Clist_modern/modern_docking.cpp
@@ -0,0 +1,372 @@
+/*
+
+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.
+*/
+#include "hdr/modern_commonheaders.h"
+#include "hdr/modern_clist.h"
+#include "m_api/m_skin_eng.h"
+#include "m_api/m_skinbutton.h"
+#include "hdr/modern_commonprototypes.h"
+#include "hdr/modern_sync.h"
+
+#define WM_DOCKCALLBACK (WM_USER+121)
+#define WM_CREATEDOCKED (WM_USER+122)
+#define EDGESENSITIVITY 3
+
+#define DOCKED_NONE 0
+#define DOCKED_LEFT 1
+#define DOCKED_RIGHT 2
+
+BOOL LockSubframeMoving=0;
+static int TempDock=0;
+static int dock_drag_dx=0;
+static int dock_drag_dy=0;
+
+static void Docking_GetMonitorRectFromPoint(POINT pt,RECT *rc)
+{
+ HMODULE hUserInstance = GetModuleHandle(TEXT("user32"));
+
+ if ( MyMonitorFromPoint )
+ {
+ MONITORINFO monitorInfo;
+ HMONITOR hMonitor = MyMonitorFromPoint(pt,MONITOR_DEFAULTTONEAREST); // always returns a valid value
+ monitorInfo.cbSize = sizeof(MONITORINFO);
+
+ if ( MyGetMonitorInfo(hMonitor,&monitorInfo))
+ {
+ CopyMemory(rc,&monitorInfo.rcMonitor,sizeof(RECT));
+ return;
+ }
+ }
+
+ // "generic" win95/NT support, also serves as failsafe
+ rc->left = 0;
+ rc->top = 0;
+ rc->bottom = GetSystemMetrics(SM_CYSCREEN);
+ rc->right = GetSystemMetrics(SM_CXSCREEN);
+}
+
+void Docking_GetMonitorRectFromWindow(HWND hWnd,RECT *rc)
+{
+ POINT ptWindow;
+ GetWindowRect(hWnd,rc);
+ ptWindow.x = rc->left;
+ ptWindow.y = rc->top;
+ Docking_GetMonitorRectFromPoint(ptWindow,rc);
+}
+
+static void Docking_AdjustPosition(HWND hwnd,RECT *rcDisplay,RECT *rc)
+{
+ APPBARDATA abd;
+
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=hwnd;
+ abd.uEdge=g_CluiData.fDocked==DOCKED_LEFT?ABE_LEFT:ABE_RIGHT;
+ abd.rc=*rc;
+ abd.rc.top=rcDisplay->top;
+ abd.rc.bottom=rcDisplay->bottom;
+ if(g_CluiData.fDocked==DOCKED_LEFT) {
+ abd.rc.right=rcDisplay->left+abd.rc.right-abd.rc.left;
+ abd.rc.left=rcDisplay->left;
+ }
+ else {
+ abd.rc.left=rcDisplay->right-(abd.rc.right-abd.rc.left);
+ abd.rc.right=rcDisplay->right;
+
+ }
+ SHAppBarMessage(ABM_SETPOS,&abd);
+ *rc=abd.rc;
+}
+
+int Docking_IsDocked(WPARAM wParam,LPARAM lParam)
+{
+ return g_CluiData.fDocked;
+}
+
+int Docking_ProcessWindowMessage(WPARAM wParam,LPARAM lParam)
+{
+ APPBARDATA abd;
+ static int draggingTitle;
+ MSG *msg=(MSG*)wParam;
+
+ if(msg->message==WM_DESTROY)
+ ModernWriteSettingByte(NULL,"CList","Docked",(BYTE)g_CluiData.fDocked);
+
+ if (!g_CluiData.fDocked && msg->message!=WM_CREATE && msg->message!=WM_MOVING && msg->message!=WM_CREATEDOCKED && msg->message != WM_MOVE && msg->message != WM_SIZE) return 0;
+ switch(msg->message) {
+ case WM_CREATE:
+ //if(GetSystemMetrics(SM_CMONITORS)>1) return 0;
+ if(ModernGetSettingByte(NULL,"CList","Docked",0) && ModernGetSettingByte(NULL,"CLUI","DockToSides",SETTING_DOCKTOSIDES_DEFAULT))
+ {
+ PostMessage(msg->hwnd,WM_CREATEDOCKED,0,0);
+ }
+ draggingTitle=0;
+ return 0;
+
+ case WM_CREATEDOCKED:
+ //we need to post a message just after creation to let main message function do some work
+ g_CluiData.fDocked=(BOOL)ModernGetSettingByte(NULL,"CList","Docked",0);
+ if(IsWindowVisible(msg->hwnd) && !IsIconic(msg->hwnd)) {
+ RECT rc, rcMonitor;
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=msg->hwnd;
+ abd.lParam=0;
+ abd.uCallbackMessage=WM_DOCKCALLBACK;
+ SHAppBarMessage(ABM_NEW,&abd);
+ GetWindowRect(msg->hwnd,&rc);
+ Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor);
+ Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc);
+ MoveWindow(msg->hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,TRUE);
+ g_CluiData.mutexPreventDockMoving=0;
+ Sync(CLUIFrames_OnMoving,msg->hwnd,&rc);
+ g_CluiData.mutexPreventDockMoving=1;
+ ModernSkinButton_ReposButtons( msg->hwnd, SBRF_DO_NOT_DRAW, NULL );
+ }
+ break;
+ case WM_CAPTURECHANGED:
+ ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_NOT_DRAW,NULL);
+ return 0;
+ case WM_ACTIVATE:
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=msg->hwnd;
+ SHAppBarMessage(ABM_ACTIVATE,&abd);
+ return 0;
+ case WM_SIZE:
+ ModernSkinButton_ReposButtons( msg->hwnd, SBRF_DO_REDRAW_ALL, NULL );
+ return 0;
+
+ case WM_WINDOWPOSCHANGED:
+ {
+ if (g_CluiData.fDocked) ModernSkinButton_ReposButtons( msg->hwnd,SBRF_DO_NOT_DRAW, NULL );
+ return 0;
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=msg->hwnd;
+ SHAppBarMessage(ABM_WINDOWPOSCHANGED,&abd);
+ ModernSkinButton_ReposButtons( msg->hwnd, SBRF_DO_NOT_DRAW, NULL );
+ return 0;
+ }
+ case WM_MOVING:
+ {
+ RECT rcMonitor;
+ RECT rcWindow;
+ RECT *rc;
+ int dx=0;
+ POINT ptCursor;
+ if (g_CluiData.fDocked) return 0;
+ // stop early
+ BOOL bControlled = (BOOL)(GetAsyncKeyState(VK_CONTROL)&0x8000);
+
+ // GetMessagePos() is no good, position is always unsigned
+ GetCursorPos(&ptCursor);
+ GetWindowRect(msg->hwnd,&rcWindow);
+ dock_drag_dx=rcWindow.left-ptCursor.x;
+ dock_drag_dy=rcWindow.top-ptCursor.y;
+ Docking_GetMonitorRectFromPoint(ptCursor,&rcMonitor);
+
+ if (((ptCursor.x<rcMonitor.left+EDGESENSITIVITY)
+ || (ptCursor.x>=rcMonitor.right-EDGESENSITIVITY))
+ && ModernGetSettingByte(NULL,"CLUI","DockToSides",SETTING_DOCKTOSIDES_DEFAULT))
+ {
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=msg->hwnd;
+ abd.lParam=0;
+ abd.uCallbackMessage=WM_DOCKCALLBACK;
+ SHAppBarMessage(ABM_NEW,&abd);
+ if(ptCursor.x<rcMonitor.left+EDGESENSITIVITY) g_CluiData.fDocked=DOCKED_LEFT;
+ else g_CluiData.fDocked=DOCKED_RIGHT;
+ // TempDock=1;
+ GetWindowRect(msg->hwnd,(LPRECT)msg->lParam);
+ rc=(RECT*)msg->lParam;
+ if (g_CluiData.fDocked==DOCKED_RIGHT)
+ dx=(rc->right>rcMonitor.right)?rc->right-rcMonitor.right:0;
+ else
+ dx=(rc->left<rcMonitor.left)?rc->left-rcMonitor.left:0;
+ OffsetRect(rc,-dx,0);
+ Docking_AdjustPosition(msg->hwnd,(LPRECT)&rcMonitor,(LPRECT)msg->lParam);
+ SendMessage(msg->hwnd,WM_SIZE,0,0);
+ g_CluiData.mutexPreventDockMoving=0;
+ Sync(CLUIFrames_OnMoving,msg->hwnd,(LPRECT)msg->lParam);
+ g_CluiData.mutexPreventDockMoving=1;
+ mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
+ ModernWriteSettingByte(NULL,"CList","Docked",(BYTE)g_CluiData.fDocked);
+ ModernSkinButton_ReposButtons( msg->hwnd, SBRF_DO_NOT_DRAW, NULL );
+ return TRUE;
+ }
+ return 0;
+ }
+ case WM_EXITSIZEMOVE:
+ {
+ RECT rcMonitor;
+ RECT rcWindow;
+ if (TempDock) TempDock=0;
+ GetWindowRect(msg->hwnd,&rcWindow);
+ Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor);
+ Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rcWindow);
+ *((LRESULT*)lParam)=TRUE;
+ g_CluiData.mutexPreventDockMoving=0;
+ SetWindowPos(msg->hwnd,0,rcWindow.left,rcWindow.top,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOSENDCHANGING);
+ Sync(CLUIFrames_OnMoving,msg->hwnd,&rcWindow);
+ ModernSkinButton_ReposButtons( msg->hwnd, SBRF_DO_NOT_DRAW, NULL );//-=-=-=
+ g_CluiData.mutexPreventDockMoving=1;
+ return 1;
+ }
+
+ case WM_MOVE:
+ {
+
+ if(g_CluiData.fDocked && 0) {
+ RECT rc, rcMonitor;
+ Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor);
+ GetWindowRect(msg->hwnd,&rc);
+ Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc);
+ MoveWindow(msg->hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,TRUE);
+ Sync(CLUIFrames_OnMoving,msg->hwnd,&rc);
+ ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_NOT_DRAW, NULL);//-=-=-=
+
+ return 1;
+ }
+ ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_ALT_DRAW, NULL);
+ return 0;
+ }
+ case WM_SIZING:
+ {
+
+ /*RECT rcMonitor;
+ Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor);
+ Docking_AdjustPosition(msg->hwnd,&rcMonitor,(LPRECT)msg->lParam);
+ *((LRESULT*)lParam)=TRUE;
+ */
+ RECT rc;
+ if (g_CluiData.fDocked) ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_NOT_DRAW,NULL);
+ return FALSE;
+ rc=*(RECT*)(msg->lParam);
+ g_CluiData.mutexPreventDockMoving=0;
+ Sync(CLUIFrames_OnMoving,msg->hwnd,&rc);
+ //-=-=-=
+ return TRUE;
+ }
+ case WM_SHOWWINDOW:
+ {
+ if(msg->lParam) return 0;
+ BOOL toBeDocked = (BOOL) ModernGetSettingByte(NULL,"CLUI","DockToSides",SETTING_DOCKTOSIDES_DEFAULT);
+ if ((msg->wParam && g_CluiData.fDocked<0) || (!msg->wParam && g_CluiData.fDocked>0)) g_CluiData.fDocked=-g_CluiData.fDocked;
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=msg->hwnd;
+ if(msg->wParam) {
+ RECT rc, rcMonitor;
+ Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor);
+ abd.lParam=0;
+ abd.uCallbackMessage=WM_DOCKCALLBACK;
+ SHAppBarMessage(ABM_NEW,&abd);
+ GetWindowRect(msg->hwnd,&rc);
+ Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc);
+ MoveWindow(msg->hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,FALSE);
+ Sync(CLUIFrames_OnMoving,msg->hwnd,&rc);
+ ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_NOT_DRAW,NULL);//-=-=-=
+ }
+ else {
+ SHAppBarMessage(ABM_REMOVE,&abd);
+ }
+ }
+ return 0;
+ case WM_NCHITTEST:
+ { LONG result;
+ result=DefWindowProc(msg->hwnd,WM_NCHITTEST,msg->wParam,msg->lParam);
+ if(result==HTSIZE || result==HTTOP || result==HTTOPLEFT || result==HTTOPRIGHT ||
+ result==HTBOTTOM || result==HTBOTTOMRIGHT || result==HTBOTTOMLEFT) {*((LRESULT*)lParam)=HTCLIENT; return TRUE;}
+ if(g_CluiData.fDocked==DOCKED_LEFT && result==HTLEFT) {*((LRESULT*)lParam)=HTCLIENT; return TRUE;}
+ if(g_CluiData.fDocked==DOCKED_RIGHT && result==HTRIGHT) {*((LRESULT*)lParam)=HTCLIENT; return TRUE;}
+
+
+ return 0;
+ }
+ case WM_SYSCOMMAND:
+ if ((msg->wParam&0xFFF0)!=SC_MOVE) return 0;
+ SetActiveWindow(msg->hwnd);
+ SetCapture(msg->hwnd);
+ draggingTitle=1;
+ *((LRESULT*)lParam)=0;
+ return TRUE;
+ case WM_MOUSEMOVE:
+
+ if (!draggingTitle) return 0;
+ { RECT rc;
+ POINT pt;
+ GetClientRect(msg->hwnd,&rc);
+ if (((g_CluiData.fDocked==DOCKED_LEFT || g_CluiData.fDocked==-DOCKED_LEFT) && (short)LOWORD(msg->lParam)>rc.right) ||
+ ((g_CluiData.fDocked==DOCKED_RIGHT || g_CluiData.fDocked==-DOCKED_RIGHT) && (short)LOWORD(msg->lParam)<0)) {
+ ReleaseCapture();
+ draggingTitle=0;
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=msg->hwnd;
+ SHAppBarMessage(ABM_REMOVE,&abd);
+ g_CluiData.fDocked=0;
+ GetCursorPos(&pt);
+ PostMessage(msg->hwnd,WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(pt.x,pt.y));
+ SetWindowPos(msg->hwnd,0,pt.x-rc.right/2,pt.y-GetSystemMetrics(SM_CYFRAME)-GetSystemMetrics(SM_CYSMCAPTION)/2,ModernGetSettingDword(NULL,"CList","Width",0),ModernGetSettingDword(NULL,"CList","Height",0),SWP_NOZORDER);
+ ModernWriteSettingByte(NULL,"CList","Docked",(BYTE)g_CluiData.fDocked);
+ // ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_NOT_DRAW, NULL);
+ }
+ return 1;
+ }
+ case WM_LBUTTONUP:
+ if(draggingTitle) {
+ ReleaseCapture();
+ draggingTitle=0;
+ }
+ return 0;
+ case WM_DOCKCALLBACK:
+ switch(msg->wParam) {
+ case ABN_WINDOWARRANGE:
+ CLUI_ShowWindowMod(msg->hwnd,msg->lParam?SW_HIDE:SW_SHOW);
+ {
+
+ RECT rc, rcMonitor;
+ Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor);
+ GetWindowRect(msg->hwnd,&rc);
+ Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc);
+ Sync(CLUIFrames_OnMoving,msg->hwnd,&rc); //-=-=-=
+ ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_NOT_DRAW, NULL);
+
+ g_CluiData.mutexPreventDockMoving=1;
+ }
+ break;
+ }
+ return TRUE;
+ case WM_DESTROY:
+ if(g_CluiData.fDocked>0) {
+ ZeroMemory(&abd,sizeof(abd));
+ abd.cbSize=sizeof(abd);
+ abd.hWnd=msg->hwnd;
+ SHAppBarMessage(ABM_REMOVE,&abd);
+ ModernSkinButton_ReposButtons(msg->hwnd, SBRF_DO_NOT_DRAW, NULL);
+ }
+ return 0;
+ }
+ return 0;
+}