diff options
Diffstat (limited to 'plugins/MagneticWindows/src/MagneticWindowsCore.cpp')
-rw-r--r-- | plugins/MagneticWindows/src/MagneticWindowsCore.cpp | 464 |
1 files changed, 464 insertions, 0 deletions
diff --git a/plugins/MagneticWindows/src/MagneticWindowsCore.cpp b/plugins/MagneticWindows/src/MagneticWindowsCore.cpp new file mode 100644 index 0000000000..5af05dcd76 --- /dev/null +++ b/plugins/MagneticWindows/src/MagneticWindowsCore.cpp @@ -0,0 +1,464 @@ +#include "MagneticWindowsCore.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Variables
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+TWorkingVariables Globals = {
+ NULL,
+ NULL,
+ 0,0,
+ false,false
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Functions
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+int Abs(int a) {
+ if (a < 0) return (-a);
+ return a;
+}
+
+
+PDockingWindow FindDockingWindow(HWND hWnd) {
+ PDockingWindow i;
+
+ i = Globals.WindowList;
+
+ while (i != NULL) {
+
+ if (i->hWnd == hWnd) return i;
+
+ i = i->Next;
+ };
+
+ return NULL;
+}
+
+
+void DockWindowRect(HWND hWnd, bool Sizing, RECT& GivenRect, int SizingEdge, int MouseX = 0, int MouseY = 0) {
+ POINT p;
+ int diffX, diffY;
+ RECT tmpRect, frmRect;
+ int W, H;
+ int XPos, YPos;
+ int tmpXPos, tmpYPos;
+ int tmpMouseX, tmpMouseY;
+ bool FoundX, FoundY;
+
+ PRectList ActRect;
+
+ diffX = Options.SnapWidth;
+ diffY = Options.SnapWidth;
+
+ tmpRect = GivenRect;
+ frmRect = GivenRect;
+
+ FoundX = false;
+ FoundY = false;
+
+ if (!Sizing) {
+ GetCursorPos(&p);
+ if (Globals.SnappedX) {
+ tmpMouseX = p.x - tmpRect.left;
+ OffsetRect(&tmpRect, tmpMouseX - MouseX, 0);
+ OffsetRect(&GivenRect, tmpMouseX - MouseX, 0);
+ } else {
+ MouseX = p.x - tmpRect.left;
+ }
+ if (Globals.SnappedY) {
+ tmpMouseY = p.y - tmpRect.top;
+ OffsetRect(&tmpRect, 0, tmpMouseY - MouseY);
+ OffsetRect(&GivenRect, 0, tmpMouseY - MouseY);
+ } else {
+ MouseY = p.y - tmpRect.top;
+ }
+ }
+
+ W = tmpRect.right - tmpRect.left;
+ H = tmpRect.bottom - tmpRect.top;
+
+ if (!Sizing) {
+ ActRect = Globals.Rects;
+ while (ActRect != NULL) {
+ if ((tmpRect.left >= (ActRect->Rect.left - Options.SnapWidth)) &&
+ (tmpRect.left <= (ActRect->Rect.left + Options.SnapWidth)) &&
+ ((tmpRect.top - Options.SnapWidth) < ActRect->Rect.bottom) &
+ ((tmpRect.bottom + Options.SnapWidth) > ActRect->Rect.top) &&
+ (Abs(tmpRect.left - ActRect->Rect.left) < diffX))
+ {
+ GivenRect.left = ActRect->Rect.left;
+ GivenRect.right = GivenRect.left + W;
+
+ diffX = Abs(tmpRect.left - ActRect->Rect.left);
+
+ FoundX = true;
+ } else
+ if ((ActRect != Globals.Rects) &&
+ (tmpRect.left >= (ActRect->Rect.right - Options.SnapWidth)) &&
+ (tmpRect.left <= (ActRect->Rect.right + Options.SnapWidth)) &&
+ ((tmpRect.top - Options.SnapWidth) < ActRect->Rect.bottom) &&
+ ((tmpRect.bottom + Options.SnapWidth) > ActRect->Rect.top) &&
+ (Abs(tmpRect.left - ActRect->Rect.right) < diffX))
+ {
+ GivenRect.left = ActRect->Rect.right;
+ GivenRect.right = GivenRect.left + W;
+
+ diffX = Abs(tmpRect.left - ActRect->Rect.right);
+
+ FoundX = true;
+ } else
+ if ((ActRect != Globals.Rects) &&
+ (tmpRect.right >= (ActRect->Rect.left - Options.SnapWidth)) &&
+ (tmpRect.right <= (ActRect->Rect.left + Options.SnapWidth)) &&
+ ((tmpRect.top - Options.SnapWidth) < ActRect->Rect.bottom) &&
+ ((tmpRect.bottom + Options.SnapWidth) > ActRect->Rect.top) &&
+ (Abs(tmpRect.right - ActRect->Rect.left) < diffX))
+ {
+ GivenRect.right = ActRect->Rect.left;
+ GivenRect.left = GivenRect.right - W;
+
+ diffX = Abs(tmpRect.right - ActRect->Rect.left);
+
+ FoundX = true;
+ } else
+ if ((tmpRect.right >= (ActRect->Rect.right - Options.SnapWidth)) &&
+ (tmpRect.right <= (ActRect->Rect.right + Options.SnapWidth)) &&
+ ((tmpRect.top - Options.SnapWidth) < ActRect->Rect.bottom) &&
+ ((tmpRect.bottom + Options.SnapWidth) > ActRect->Rect.top) &&
+ (Abs(tmpRect.right - ActRect->Rect.right) < diffX))
+ {
+ GivenRect.right = ActRect->Rect.right;
+ GivenRect.left = GivenRect.right - W;
+
+ diffX = Abs(tmpRect.right - ActRect->Rect.right);
+
+ FoundX = true;
+ }
+
+
+ if ((tmpRect.top >= (ActRect->Rect.top - Options.SnapWidth)) &&
+ (tmpRect.top <= (ActRect->Rect.top + Options.SnapWidth)) &&
+ ((tmpRect.left - Options.SnapWidth) < ActRect->Rect.right) &&
+ ((tmpRect.right + Options.SnapWidth) > ActRect->Rect.left) &&
+ (Abs(tmpRect.top - ActRect->Rect.top) < diffY))
+ {
+ GivenRect.top = ActRect->Rect.top;
+ GivenRect.bottom = GivenRect.top + H;
+
+ diffY = Abs(tmpRect.top - ActRect->Rect.top);
+
+ FoundY = true;
+ } else
+ if ((ActRect != Globals.Rects) &&
+ (tmpRect.top >= (ActRect->Rect.bottom - Options.SnapWidth)) &&
+ (tmpRect.top <= (ActRect->Rect.bottom + Options.SnapWidth)) &&
+ ((tmpRect.left - Options.SnapWidth) < ActRect->Rect.right) &&
+ ((tmpRect.right + Options.SnapWidth) > ActRect->Rect.left) &&
+ (Abs(tmpRect.top - ActRect->Rect.bottom) < diffY))
+ {
+ GivenRect.top = ActRect->Rect.bottom;
+ GivenRect.bottom = GivenRect.top + H;
+
+ diffY = Abs(tmpRect.top - ActRect->Rect.bottom);
+
+ FoundY = true;
+ } else
+ if ((ActRect != Globals.Rects) &&
+ (tmpRect.bottom >= (ActRect->Rect.top - Options.SnapWidth)) &&
+ (tmpRect.bottom <= (ActRect->Rect.top + Options.SnapWidth)) &&
+ ((tmpRect.left - Options.SnapWidth) < ActRect->Rect.right) &&
+ ((tmpRect.right + Options.SnapWidth) > ActRect->Rect.left) &&
+ (Abs(tmpRect.bottom - ActRect->Rect.top) < diffY))
+ {
+ GivenRect.bottom = ActRect->Rect.top;
+ GivenRect.top = GivenRect.bottom - H;
+
+ diffY = Abs(tmpRect.bottom - ActRect->Rect.top);
+
+ FoundY = true;
+ } else
+ if ((tmpRect.bottom >= (ActRect->Rect.bottom - Options.SnapWidth)) &&
+ (tmpRect.bottom <= (ActRect->Rect.bottom + Options.SnapWidth)) &&
+ ((tmpRect.left - Options.SnapWidth) < ActRect->Rect.right) &&
+ ((tmpRect.right + Options.SnapWidth) > ActRect->Rect.left) &&
+ (Abs(tmpRect.bottom - ActRect->Rect.bottom) < diffY))
+ {
+ GivenRect.bottom = ActRect->Rect.bottom;
+ GivenRect.top = GivenRect.bottom - H;
+
+ diffY = Abs(tmpRect.bottom - ActRect->Rect.bottom);
+
+ FoundY = true;
+ }
+
+ ActRect = ActRect->Next;
+ } //next rect
+
+ Globals.SnappedX = FoundX;
+ Globals.SnappedY = FoundY;
+ }
+ else //Sizing
+ {
+ if ((SizingEdge == WMSZ_LEFT) ||
+ (SizingEdge == WMSZ_TOPLEFT) ||
+ (SizingEdge == WMSZ_BOTTOMLEFT))
+ {
+ XPos = GivenRect.left;
+ } else {
+ XPos = GivenRect.right;
+ }
+
+ if ((SizingEdge == WMSZ_TOP) ||
+ (SizingEdge == WMSZ_TOPLEFT) ||
+ (SizingEdge == WMSZ_TOPRIGHT))
+ {
+ YPos = GivenRect.top;
+ } else {
+ YPos = GivenRect.bottom;
+ }
+
+ tmpXPos = XPos;
+ tmpYPos = YPos;
+
+ ActRect = Globals.Rects;
+ while (ActRect != NULL) {
+ if ((tmpXPos >= (ActRect->Rect.left - Options.SnapWidth)) &&
+ (tmpXPos <= (ActRect->Rect.left + Options.SnapWidth)) &&
+ ((tmpRect.top - Options.SnapWidth) < ActRect->Rect.bottom) &&
+ ((tmpRect.bottom + Options.SnapWidth) > ActRect->Rect.top) &&
+ (Abs(tmpXPos - ActRect->Rect.left) < diffX))
+ {
+ XPos = ActRect->Rect.left;
+
+ diffX = Abs(tmpXPos - ActRect->Rect.left);
+ } else
+ if ((tmpXPos >= (ActRect->Rect.right - Options.SnapWidth)) &&
+ (tmpXPos <= (ActRect->Rect.right + Options.SnapWidth)) &&
+ ((tmpRect.top - Options.SnapWidth) < ActRect->Rect.bottom) &&
+ ((tmpRect.bottom + Options.SnapWidth) > ActRect->Rect.top) &&
+ (Abs(tmpXPos - ActRect->Rect.right) < diffX))
+ {
+ XPos = ActRect->Rect.right;
+
+ diffX = Abs(tmpXPos - ActRect->Rect.right);
+ }
+
+ if ((tmpYPos >= (ActRect->Rect.top - Options.SnapWidth)) &&
+ (tmpYPos <= (ActRect->Rect.top + Options.SnapWidth)) &&
+ ((tmpRect.left - Options.SnapWidth) < ActRect->Rect.right) &&
+ ((tmpRect.right + Options.SnapWidth) > ActRect->Rect.left) &&
+ (Abs(tmpYPos - ActRect->Rect.top) < diffY))
+ {
+ YPos = ActRect->Rect.top;
+
+ diffY = Abs(tmpYPos - ActRect->Rect.top);
+ } else
+ if ((tmpYPos >= (ActRect->Rect.bottom - Options.SnapWidth)) &&
+ (tmpYPos <= (ActRect->Rect.bottom + Options.SnapWidth)) &&
+ ((tmpRect.left - Options.SnapWidth) < ActRect->Rect.right) &&
+ ((tmpRect.right + Options.SnapWidth) > ActRect->Rect.left) &&
+ (Abs(tmpYPos - ActRect->Rect.bottom) < diffY))
+ {
+ YPos = ActRect->Rect.bottom;
+
+ diffY = Abs(tmpYPos - ActRect->Rect.bottom);
+ }
+
+ ActRect = ActRect->Next;
+ } //Next rect
+
+ if ((SizingEdge == WMSZ_LEFT) ||
+ (SizingEdge == WMSZ_TOPLEFT) ||
+ (SizingEdge == WMSZ_BOTTOMLEFT))
+ {
+ GivenRect.left = XPos;
+ } else {
+ GivenRect.right = XPos;
+ }
+ if ((SizingEdge == WMSZ_TOP) ||
+ (SizingEdge == WMSZ_TOPLEFT) ||
+ (SizingEdge == WMSZ_TOPRIGHT))
+ {
+ GivenRect.top = YPos;
+ } else {
+ GivenRect.bottom = YPos;
+ }
+ }
+}
+
+
+void GetFrmRects(HWND ForWindow) {
+PDockingWindow i;
+PRectList Rect, l;
+
+ Rect = Globals.Rects;
+ while (Rect != NULL) {
+ l = Rect;
+ Rect = Rect->Next;
+ free(l);
+ }
+
+ Rect = (PRectList)malloc(sizeof(TRectList));
+ Rect->Next = NULL;
+ Globals.Rects = Rect;
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &(Rect->Rect), 0);
+ i = Globals.WindowList;
+
+ while (i != NULL) {
+ if ((i->hWnd != ForWindow) && IsWindowVisible(i->hWnd)) {
+ l = Rect;
+ Rect = (PRectList)malloc(sizeof(TRectList));
+ Rect->Next = NULL;
+ l->Next = Rect;
+
+ GetWindowRect(i->hWnd, &(Rect->Rect));
+ }
+
+ i = i->Next;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Subclass Window Proc
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
+ PDockingWindow i;
+
+ RECT r;
+ POINT p;
+
+ WNDPROC OldRun;
+
+ i = FindDockingWindow(hWnd);
+
+ OldRun = NULL;
+
+ if (i != NULL) { //else we have a problem
+ OldRun = i->OldWindowProc;
+
+ if (Options.DoSnap) {
+ switch (Msg) {
+ case WM_ENTERSIZEMOVE: {
+ if (Options.ScriverWorkAround)
+ keybd_event(VK_CONTROL, 0, 0, 0);
+
+ GetWindowRect(hWnd, &r);
+ GetCursorPos(&p);
+ Globals.MouseX = p.x - r.left;
+ Globals.MouseY = p.y - r.top;
+
+ GetFrmRects(hWnd);
+
+ break;
+ }
+ case WM_EXITSIZEMOVE: {
+ if (Options.ScriverWorkAround)
+ keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
+
+ break;
+ }
+ case WM_SIZING:
+ case WM_MOVING: {
+ r = *((PRECT)lParam);
+ if (Msg == WM_SIZING) {
+ DockWindowRect(hWnd, true, r, wParam);
+ } else {
+ DockWindowRect(hWnd, false, r, wParam, Globals.MouseX, Globals.MouseY);
+ }
+
+ (*(PRECT)lParam) = r;
+
+ if (Msg == WM_SIZING) {
+ return 1;
+ }
+
+ break;
+ }
+ } //switch
+ } //if dosnap
+
+ if (OldRun != NULL) {
+ if (IsWindowUnicode(hWnd)) {
+ return CallWindowProcW(OldRun, hWnd, Msg, wParam, lParam);
+ } else {
+ return CallWindowProcA(OldRun, hWnd, Msg, wParam, lParam);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// exportet Functions
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool WindowOpen(HWND hWnd) {
+ PDockingWindow i;
+
+ if ((hWnd != 0) && (FindDockingWindow(hWnd) == NULL)) {
+ i = (PDockingWindow)mir_alloc(sizeof(TDockingWindow));
+ i->Next = Globals.WindowList;
+ i->hWnd = hWnd;
+ Globals.WindowList = i;
+
+ if (IsWindowUnicode(hWnd)) {
+ i->OldWindowProc = (WNDPROC) GetWindowLongW(hWnd, GWL_WNDPROC);
+ SetWindowLongW(hWnd, GWL_WNDPROC, (LONG)(&WindowProc));
+ } else {
+ i->OldWindowProc = (WNDPROC) GetWindowLongA(hWnd, GWL_WNDPROC);
+ SetWindowLongA(hWnd, GWL_WNDPROC, (LONG)(&WindowProc));
+ }
+
+ return true;
+ }
+ return false;
+}
+
+bool WindowClose(HWND hWnd) {
+ PDockingWindow i, l;
+
+ l = NULL;
+ i = Globals.WindowList;
+
+ while ((i != NULL) && (i->hWnd != hWnd)) {
+ l = i;
+ i = i->Next;
+ }
+
+ if (i != NULL) {
+ if (l == NULL) {
+ Globals.WindowList = i->Next;
+ } else {
+ l->Next = i->Next;
+ }
+
+ if (IsWindowUnicode(hWnd)) {
+ SetWindowLongW(hWnd, GWL_WNDPROC, (LONG) (i->OldWindowProc));
+ } else {
+ SetWindowLongA(hWnd, GWL_WNDPROC, (LONG) (i->OldWindowProc));
+ }
+
+ mir_free(i);
+
+ return true;
+ }
+
+ return false;
+}
+bool WindowCloseAll() {
+ PDockingWindow i, l;
+ i = Globals.WindowList;
+ while (i != NULL) {
+ l = i;
+ WindowClose(i->hWnd);
+ i = i->Next;
+ mir_free(l);
+ }
+ return true;
+}
\ No newline at end of file |