384 lines
9.2 KiB
C++
384 lines
9.2 KiB
C++
#include <precomp.h>
|
|
#ifdef WIN32
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include <bfc/assert.h>
|
|
#include <api/wndmgr/resize.h>
|
|
#include <api/wnd/wndtrack.h>
|
|
#include <api/wnd/basewnd.h>
|
|
#include <api/wndmgr/layout.h>
|
|
|
|
#define tag L"wa3_resizerclass"
|
|
|
|
extern HINSTANCE hInstance;
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
resizeClass::resizeClass(ifc_window *wnd, int minx, int miny, int maxx, int maxy, int sugx, int sugy)
|
|
{
|
|
screenWidth = Wasabi::Std::getScreenWidth();
|
|
screenHeight = Wasabi::Std::getScreenHeight();
|
|
|
|
#if defined (_WIN32) || defined(_WIN64)
|
|
WNDCLASSW wc;
|
|
if (!GetClassInfoW(hInstance, tag, &wc))
|
|
{
|
|
MEMSET(&wc, 0, sizeof(wc));
|
|
wc.lpfnWndProc = resizeWndProc;
|
|
wc.hInstance = hInstance; // hInstance of DLL
|
|
wc.lpszClassName = tag; // our window class name
|
|
wc.style = 0;
|
|
|
|
int _r = RegisterClassW(&wc);
|
|
ASSERTPR(_r, "cannot create resizer wndclass");
|
|
}
|
|
|
|
hWnd = CreateWindowExW(0, tag, L"", 0, 0, 0, 1, 1, NULL, NULL, hInstance, NULL);
|
|
|
|
ASSERT(hWnd);
|
|
|
|
SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this);
|
|
|
|
if (minx > maxx && maxx != -1) minx = maxx;
|
|
if (miny > maxy && maxy != -1) miny = maxy;
|
|
#endif
|
|
|
|
minWinWidth = minx;
|
|
minWinHeight = miny;
|
|
maxWinWidth = maxx;
|
|
maxWinHeight = maxy;
|
|
sugWinWidth = sugx;
|
|
sugWinHeight = sugy;
|
|
|
|
if (wnd->getInterface(layoutGuid))
|
|
{
|
|
static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
|
|
if (minWinWidth != -1) minWinWidth -= snapAdjust.left + snapAdjust.right;
|
|
if (minWinHeight != -1) minWinHeight -= snapAdjust.bottom + snapAdjust.top;
|
|
if (maxWinWidth != -1) maxWinWidth -= snapAdjust.left + snapAdjust.right;
|
|
if (maxWinHeight != -1) maxWinHeight -= snapAdjust.bottom + snapAdjust.top;
|
|
if (sugWinWidth != -1) sugWinWidth -= snapAdjust.left + snapAdjust.right;
|
|
if (sugWinHeight != -1) sugWinHeight -= snapAdjust.bottom + snapAdjust.top;
|
|
}
|
|
|
|
dc = NULL;
|
|
#ifdef WIN32
|
|
oldB = NULL;
|
|
brush = NULL;
|
|
oldP = NULL;
|
|
pen = NULL;
|
|
#endif
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
resizeClass::~resizeClass()
|
|
{
|
|
#ifdef WIN32
|
|
if (dc)
|
|
{
|
|
SelectObject(dc, oldB);
|
|
SelectObject(dc, oldP);
|
|
SetROP2(dc, mix);
|
|
DeleteObject(pen);
|
|
DeleteObject(brush);
|
|
ReleaseDC(NULL, dc);
|
|
}
|
|
|
|
if (IsWindow(hWnd))
|
|
DestroyWindow(hWnd);
|
|
//BU win98 sucks UnregisterClass(tag, Main::gethInstance());
|
|
#else
|
|
if (dc)
|
|
{
|
|
XFreeGC(Linux::getDisplay(), dc->gc);
|
|
FREE(dc);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
BOOL CALLBACK invalidateChildren(HWND hwnd, LPARAM lParam)
|
|
{
|
|
InvalidateRect(hwnd, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
BOOL CALLBACK invalidateAll(HWND hwnd, LPARAM lParam)
|
|
{
|
|
EnumChildWindows(hwnd, invalidateChildren, 0);
|
|
InvalidateRect(hwnd, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
int resizeClass::resizeWindow(ifc_window *wnd, int way)
|
|
{
|
|
|
|
// paintHookStart();
|
|
|
|
wnd->getWindowRect(&originalRect);
|
|
|
|
snapAdjust.left = 0;
|
|
snapAdjust.top = 0;
|
|
snapAdjust.right = 0;
|
|
snapAdjust.bottom = 0;
|
|
|
|
if (wnd->getInterface(layoutGuid))
|
|
{
|
|
static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
|
|
if (wnd->getRenderRatio() != 1.0)
|
|
{
|
|
double rr = wnd->getRenderRatio();
|
|
snapAdjust.left = (int)((double)(snapAdjust.left) * rr);
|
|
snapAdjust.top = (int)((double)(snapAdjust.top) * rr);
|
|
snapAdjust.right = (int)((double)(snapAdjust.right) * rr);
|
|
snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr);
|
|
}
|
|
originalRect.left += snapAdjust.left;
|
|
originalRect.top += snapAdjust.top;
|
|
originalRect.right -= snapAdjust.right;
|
|
originalRect.bottom -= snapAdjust.bottom;
|
|
}
|
|
|
|
curRect = originalRect;
|
|
resizeWay = way;
|
|
resizedWindow = wnd->gethWnd();
|
|
resizedWindowR = wnd;
|
|
|
|
POINT pt;
|
|
Wasabi::Std::getMousePos(&pt);
|
|
cX = pt.x;
|
|
cY = pt.y;
|
|
|
|
#ifdef WIN32
|
|
SetCapture(hWnd);
|
|
#endif
|
|
SetTimer(hWnd, 1, 100, NULL); // this timer will make sure that we never get interlock
|
|
|
|
drawFrame();
|
|
|
|
MSG msg;
|
|
cancelit = 1;
|
|
while (GetCapture() == hWnd && GetMessage( &msg, hWnd, 0, 0 ))
|
|
{
|
|
TranslateMessage( &msg );
|
|
#ifdef LINUX
|
|
if ( msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE )
|
|
wndProc( msg.hwnd, msg.message, msg.wParam, msg.lParam );
|
|
else
|
|
#endif
|
|
DispatchMessage( &msg );
|
|
}
|
|
|
|
drawFrame();
|
|
|
|
// paintHookStop();
|
|
|
|
if (GetCapture() == hWnd) ReleaseCapture();
|
|
KillTimer(hWnd, 1);
|
|
|
|
if (!cancelit)
|
|
{
|
|
curRect.left -= snapAdjust.left;
|
|
curRect.top -= snapAdjust.top;
|
|
curRect.right += snapAdjust.right;
|
|
curRect.bottom += snapAdjust.bottom;
|
|
}
|
|
else
|
|
{
|
|
curRect = originalRect;
|
|
// evil, but less evil than InvalidateRect(NULL, NULL, FALSE);
|
|
EnumWindows(invalidateAll, 0);
|
|
}
|
|
|
|
return !cancelit;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
RECT resizeClass::getRect(void)
|
|
{
|
|
return curRect;
|
|
}
|
|
|
|
//#define nifty
|
|
|
|
//----------------------------------------------------------------------
|
|
void resizeClass::drawFrame(void)
|
|
{
|
|
RECT outRect;
|
|
|
|
#ifdef WIN32
|
|
if (!dc)
|
|
{
|
|
dc = GetDC(NULL);
|
|
brush = CreateSolidBrush(0xFFFFFF);
|
|
pen = CreatePen(PS_SOLID, 0, 0xFFFFFF);
|
|
oldB = (HBRUSH)SelectObject(dc, brush);
|
|
oldP = (HPEN)SelectObject(dc, pen);
|
|
mix = SetROP2(dc, R2_XORPEN);
|
|
}
|
|
|
|
outRect = curRect;
|
|
|
|
#ifndef nifty
|
|
|
|
DrawFocusRect(dc, &outRect);
|
|
|
|
#else
|
|
|
|
RECT inRect;
|
|
|
|
inRect = outRect;
|
|
inRect.left += 10;
|
|
inRect.right -= 10;
|
|
inRect.top += 24;
|
|
inRect.bottom -= 10;
|
|
|
|
MoveToEx(dc, inRect.left, inRect.top, NULL);
|
|
LineTo(dc, inRect.right, inRect.top);
|
|
LineTo(dc, inRect.right, inRect.bottom);
|
|
LineTo(dc, inRect.left, inRect.bottom);
|
|
LineTo(dc, inRect.left, inRect.top);
|
|
MoveToEx(dc, outRect.left, 0, NULL);
|
|
LineTo(dc, outRect.left, screenHeight);
|
|
MoveToEx(dc, outRect.right, 0, NULL);
|
|
LineTo(dc, outRect.right, screenHeight);
|
|
MoveToEx(dc, 0, outRect.top, NULL);
|
|
LineTo(dc, screenWidth, outRect.top);
|
|
MoveToEx(dc, 0, outRect.bottom, NULL);
|
|
LineTo(dc, screenWidth, outRect.bottom);
|
|
|
|
#endif
|
|
#endif//WIN32
|
|
#ifdef LINUX
|
|
outRect = curRect;
|
|
|
|
if ( ! dc )
|
|
{
|
|
dc = (HDC)MALLOC( sizeof( hdc_typ ) );
|
|
XGCValues gcv;
|
|
gcv.function = GXxor;
|
|
gcv.subwindow_mode = IncludeInferiors;
|
|
gcv.foreground = 0xffffff;
|
|
gcv.line_style = LineOnOffDash;
|
|
gcv.dashes = 1;
|
|
dc->gc = XCreateGC( Linux::getDisplay(), Linux::RootWin(), GCFunction | GCForeground | GCSubwindowMode, &gcv );
|
|
}
|
|
|
|
XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
|
|
outRect.left, outRect.top, outRect.right - outRect.left,
|
|
outRect.bottom - outRect.top );
|
|
#endif
|
|
//PORTME
|
|
}
|
|
|
|
LRESULT resizeClass::wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_LBUTTONUP:
|
|
cancelit = 0;
|
|
ReleaseCapture();
|
|
return 0;
|
|
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
POINT pt;
|
|
int iX, iY;
|
|
Wasabi::Std::getMousePos(&pt);
|
|
iX = pt.x - cX;
|
|
iY = pt.y - cY;
|
|
drawFrame();
|
|
|
|
if (resizeWay & TOP)
|
|
curRect.top = originalRect.top + iY;
|
|
if (resizeWay & BOTTOM)
|
|
curRect.bottom = originalRect.bottom + iY;
|
|
if (resizeWay & LEFT)
|
|
curRect.left = originalRect.left + iX;
|
|
if (resizeWay & RIGHT)
|
|
curRect.right = originalRect.right + iX;
|
|
|
|
if (abs((curRect.right - curRect.left) - sugWinWidth) < 10)
|
|
if (resizeWay & RIGHT)
|
|
curRect.right = curRect.left + sugWinWidth;
|
|
else if (resizeWay & LEFT)
|
|
curRect.left = curRect.right - sugWinWidth;
|
|
|
|
if (abs((curRect.bottom - curRect.top) - sugWinHeight) < 10)
|
|
if (resizeWay & BOTTOM)
|
|
curRect.bottom = curRect.top + sugWinHeight;
|
|
else if (resizeWay & TOP)
|
|
curRect.top = curRect.bottom - sugWinHeight;
|
|
|
|
curRect.left -= snapAdjust.left;
|
|
curRect.top -= snapAdjust.top;
|
|
curRect.right += snapAdjust.right;
|
|
curRect.bottom += snapAdjust.bottom;
|
|
|
|
windowTracker->autoDock(resizedWindowR, &curRect, resizeWay);
|
|
|
|
curRect.left += snapAdjust.left;
|
|
curRect.top += snapAdjust.top;
|
|
curRect.right -= snapAdjust.right;
|
|
curRect.bottom -= snapAdjust.bottom;
|
|
|
|
if ((curRect.right - curRect.left) < minWinWidth)
|
|
if (resizeWay & RIGHT)
|
|
curRect.right = curRect.left + minWinWidth;
|
|
else if (resizeWay & LEFT)
|
|
curRect.left = curRect.right - minWinWidth;
|
|
|
|
if ((curRect.bottom - curRect.top) < minWinHeight)
|
|
if (resizeWay & BOTTOM)
|
|
curRect.bottom = curRect.top + minWinHeight;
|
|
else if (resizeWay & TOP)
|
|
curRect.top = curRect.bottom - minWinHeight;
|
|
|
|
if (maxWinWidth != -1 && (curRect.right - curRect.left) > maxWinWidth)
|
|
if (resizeWay & RIGHT)
|
|
curRect.right = curRect.left + maxWinWidth;
|
|
else if (resizeWay & LEFT)
|
|
curRect.left = curRect.right - maxWinWidth;
|
|
|
|
if (maxWinHeight != -1 && (curRect.bottom - curRect.top) > maxWinHeight)
|
|
if (resizeWay & BOTTOM)
|
|
curRect.bottom = curRect.top + maxWinHeight;
|
|
else if (resizeWay & TOP)
|
|
curRect.top = curRect.bottom - maxWinHeight;
|
|
|
|
drawFrame();
|
|
}
|
|
return 0;
|
|
}
|
|
#ifdef WIN32
|
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
// Window Procedure
|
|
//
|
|
LRESULT CALLBACK resizeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
#ifdef WIN32
|
|
resizeClass *gThis = (resizeClass *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
|
|
if (!gThis)
|
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
|
else
|
|
return gThis->wndProc(hwnd, uMsg, wParam, lParam);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
void resizeClass::setResizeCursor(int action)
|
|
{}
|
|
|
|
|