#include "precomp.h" #include #include "clickwnd.h" #include #include enum { CLICKWND_LBUTTONDOWN = 0, CLICKWND_LBUTTONUP, CLICKWND_RBUTTONDOWN, CLICKWND_RBUTTONUP, }; ClickWnd::ClickWnd() { handleRight = TRUE; button = -1; mousedown = 0; mcaptured = 0; hilite = 0; down = 0; areacheck = 0; } ClickWnd::~ClickWnd() { BaseWnd::hintDestroying(); // so basewnd doesn't call onCancelCapture if (getCapture()) endCapture(); } void ClickWnd::setHandleRightClick(int tf) { handleRight=tf; } int ClickWnd::getHandleRightClick() { return handleRight; } int ClickWnd::onLeftButtonDown(int x, int y) { notifyParent(ChildNotify::CLICKWND_LEFTDOWN, x, y); CLICKWND_PARENT::onLeftButtonDown(x, y); abortTip(); #ifdef _WIN32 ifc_window *dp = getDesktopParent(); if (dp != NULL) { if (dp->wantActivation()) { SetActiveWindow(getRootParent()->gethWnd()); SetFocus(getRootParent()->gethWnd()); } else { HWND w = dp->gethWnd(); HWND owner = GetWindow(w, GW_OWNER); if (owner != NULL) { SetActiveWindow(owner); SetFocus(owner); } } } else { SetActiveWindow(getRootParent()->gethWnd()); } #else #warning port me or remove me #endif if (ptInRegion(x, y)) return onButtonDown(CLICKWND_LBUTTONDOWN, x, y); else return 1; } int ClickWnd::onRightButtonDown(int x, int y) { notifyParent(ChildNotify::CLICKWND_RIGHTDOWN, x, y); CLICKWND_PARENT::onRightButtonDown(x, y); abortTip(); if (!handleRight) return 1; if (ptInRegion(x, y)) return onButtonDown(CLICKWND_RBUTTONDOWN, x, y); else return 1; } int ClickWnd::onLeftButtonUp(int x, int y) { notifyParent(ChildNotify::CLICKWND_LEFTUP, x, y); CLICKWND_PARENT::onLeftButtonUp(x, y); //jf // if (ptInRegion()) return onButtonUp(CLICKWND_LBUTTONUP, x, y); // else // return 1; } int ClickWnd::onRightButtonUp(int x, int y) { notifyParent(ChildNotify::CLICKWND_RIGHTUP, x, y); CLICKWND_PARENT::onRightButtonUp(x, y); //jf //if (ptInRegion()) if (!handleRight) { onRightPush(x, y); return 1; } return onButtonUp(CLICKWND_RBUTTONUP, x, y); // else // return 1; } int ClickWnd::onMouseMove(int x, int y) { POINT pos, rpos={x,y}; int mouseover; CLICKWND_PARENT::onMouseMove(x, y); pos=rpos; clientToScreen(&pos); int lasthilite = hilite; mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == static_cast(this) && ptInRegion(x, y)); if (!mouseover && (!mousedown #ifdef _WIN32 || !Std::keyDown(button?MK_RBUTTON:MK_LBUTTON) #else #warning port me #endif )) { if (mcaptured || getCapture()) { endCapture(); mcaptured = 0; } mousedown = 0; down = 0; if (wantClickWndAutoInvalidate()) invalidate(); if (hilite) _onLeaveArea(); hilite = 0; return 1; } else if (!mouseover && hilite) { hilite = 0; _onLeaveArea(); } else if (mouseover && !hilite) { hilite = 1; _onEnterArea(); } if (!getCapture() && mouseover) { // capture to see when leave _enterCapture(); } int lastdown = down; hilite = mouseover; #ifdef WASABI_COMPILE_WNDMGR int m = getGuiObject() ? getGuiObject()->guiobject_getMover() : 0; #else int m = 0; #endif if (!m) { down = userDown() || (mouseover && mousedown); } else down = userDown() || mousedown; // FG> note to self now that i finally fixed this... : // there is a potential bottleneck here, if for some reason this test is always true when moving the windows around like crazy. if (down != lastdown || (hilite != lasthilite && !m)) { if (wantClickWndAutoInvalidate()) invalidate(); } //invalidate(); return 1; } void ClickWnd::_enterCapture() { //gee!! if (!hilite) _onEnterArea(); if (!getCapture()) beginCapture(); mcaptured = 1; } int ClickWnd::onButtonDown(int which, int x, int y) { if (!wantClicks()) return 1; if (!getCapture()) { _enterCapture(); } mousedown = 1; down = 1; button = -1; if (which == CLICKWND_LBUTTONDOWN) button = 0; else if (which == CLICKWND_RBUTTONDOWN) button = 1; if (wantClickWndAutoInvalidate()) invalidate(); return 1; } int ClickWnd::onButtonUp(int which, int x, int y) { // make sure same button if (button == 0 && which == CLICKWND_RBUTTONUP) return 1; if (button == 1 && which == CLICKWND_LBUTTONUP) return 1; if (!down) { if (mcaptured) { endCapture(); mcaptured = 0; } if (hilite) _onLeaveArea(); hilite = 0; mousedown = 0; return 1; } POINT pos={x,y}; clientToScreen(&pos); int mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y)); if (!mouseover) { if (mcaptured) { endCapture(); mcaptured = 0; } if (hilite) _onLeaveArea(); hilite = 0; } // it was down, process the event int a = down; down = 0; mousedown = 0; if (wantClickWndAutoInvalidate()) invalidate(); if (a) { if (button == 0) onLeftPush(x, y); else if (button == 1) onRightPush(x, y); } // we need to do this again (and get the new mouse pos) because onLeft/RightPush may have called a // message loop and let the mouse leave without us being aware of it Wasabi::Std::getMousePos(&x, &y); pos.x = x; pos.y = y; screenToClient(&x, &y); mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y)); if (!mouseover && hilite) _onLeaveArea(); else if (mouseover && !hilite) _onEnterArea(); hilite = mouseover; return 1; } void ClickWnd::onSetVisible( int show ) { CLICKWND_PARENT::onSetVisible( show ); if ( !show ) { if ( getCapture() ) { mcaptured = 0; endCapture(); } down = 0; mousedown = 0; if ( hilite ) _onLeaveArea(); hilite = 0; } } void ClickWnd::_onEnterArea() { if (areacheck == 0) { areacheck++; onEnterArea(); } else DebugString("onEnterArea check failed %08X \n", this); } void ClickWnd::_onLeaveArea() { if (areacheck == 1) { areacheck--; onLeaveArea(); } else DebugString("onLeaveArea check failed %08X\n", this); } void ClickWnd::onEnterArea() { // DebugString("onEnterArea %08X\n", this); } void ClickWnd::onLeaveArea() { // DebugString("onLeaveArea %08X\n", this); } void ClickWnd::onCancelCapture() { CLICKWND_PARENT::onCancelCapture(); mcaptured=0; down = 0; mousedown = 0; if (hilite) _onLeaveArea(); hilite = 0; }