winamp/Src/Wasabi/api/wnd/wndclass/clickwnd.cpp
2024-09-24 14:54:57 +02:00

320 lines
6.6 KiB
C++

#include "precomp.h"
#include <api/wnd/api_wnd.h>
#include "clickwnd.h"
#include <api/wnd/notifmsg.h>
#include <api/wnd/wndclass/guiobjwnd.h>
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<ifc_window *>(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;
}