cardrgnmouse.cpp
来自「一个类似windows」· C++ 代码 · 共 643 行 · 第 1/2 页
CPP
643 行
//
// CardLib - CardRegion mouse-related stuff
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include "cardlib.h"
#include "cardwindow.h"
#include "cardregion.h"
#if 1
#define TRACE(s)
#else
#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)
#endif
double __CARDZOOMSPEED = 32;
int ClipCard(HDC hdc, int x, int y, int width, int height);
void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height);
#ifdef _DEBUG
static pDebugClickProc DebugStackClickProc = 0;
void CardLib_SetStackClickProc(pDebugClickProc proc)
{
DebugStackClickProc = proc;
}
#endif
CardRegion *CardWindow::GetBestStack(int x, int y, int w, int h)
{
int maxoverlap = 0;
int maxoverlapidx = -1;
//find the stack which is most covered by the dropped
//cards. Only include those which allow drops.
//
for(int i = 0; i < nNumCardRegions; i++)
{
int percent = Regions[i]->GetOverlapRatio(x, y, w, h);
//if this stack has the biggest coverage yet
if(percent > maxoverlap && Regions[i]->IsVisible())
{
maxoverlap = percent;
maxoverlapidx = i;
}
}
//if we found a stack to drop onto
if(maxoverlapidx != -1)
{
return Regions[maxoverlapidx];
}
else
{
return 0;
}
}
bool CardRegion::IsPointInStack(int x, int y)
{
int axpos = xoffset < 0 ? xpos + (nNumApparentCards-1)*xoffset : xpos;
int aypos = yoffset < 0 ? ypos + (nNumApparentCards-1)*yoffset : ypos;
if(x >= axpos && x < axpos + width && y >= aypos && y < aypos + height && fVisible)
return true;
else
return false;
}
int CardRegion::GetNumDragCards(int x, int y)
{
int cardindex = 0; //index from stack start
int maxidx;
//make x,y relative to the stack's upper left corner
x -= xpos + (xoffset < 0 ? (nNumApparentCards/*cardstack.NumCards()*/ - 1) * xoffset : 0);
y -= ypos + (yoffset < 0 ? (nNumApparentCards/*cardstack.NumCards()*/ - 1) * yoffset : 0);
//if stack is empty, cannot drag any cards from it
if(cardstack.NumCards() <= 0)
return 0;
//see which card in the stack has been clicked on
//top-bottom ordering
if(yoffset > 0)
{
if(y < height - __cardheight)
cardindex = y / yoffset;
else
cardindex = cardstack.NumCards() - 1;
}
else if(yoffset < 0)
{
if(y < __cardheight)
cardindex = cardstack.NumCards() - 1;
else
cardindex = cardstack.NumCards() - ((y - __cardheight) / -yoffset) - 2;
}
else //yoffset == 0
{
cardindex = cardstack.NumCards() - 1;
}
maxidx = cardindex;
//if left-right
if(xoffset > 0)
{
if(x < width - __cardwidth)
cardindex = x / xoffset;
else
cardindex = cardstack.NumCards() - 1;
}
else if(xoffset < 0)
{
if(x < __cardwidth)
cardindex = cardstack.NumCards() - 1;
else
cardindex = cardstack.NumCards() - ((x - __cardwidth) / -xoffset) - 2;
}
else
{
cardindex = cardstack.NumCards() - 1;
}
if(cardindex > maxidx) cardindex = maxidx;
if(cardindex > cardstack.NumCards())
cardindex = 1;
//if are trying to drag too many cards at once
return cardstack.NumCards() - cardindex;
}
bool CardRegion::CanDragCards(int iNumCards)
{
if(iNumCards <= 0) return false;
if(nThreedCount > 1 && iNumCards > 1) return false;
if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
{
// TRACE("Failed to gain access to card stack\n");
return false;
}
ReleaseMutex(mxlock);
switch(uDragRule)
{
case CS_DRAG_ALL:
return true;
case CS_DRAG_TOP:
if(iNumCards == 1)
return true;
else
return false;
case CS_DRAG_NONE:
return false;
case CS_DRAG_CALLBACK:
if(CanDragCallback)
{
return CanDragCallback(*this, iNumCards);
}
else
{
return false;
}
default:
return false;
}
}
bool CardRegion::CanDropCards(CardStack &cards)
{
if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
{
return false;
}
ReleaseMutex(mxlock);
switch(uDropRule)
{
case CS_DROP_ALL:
return true;
case CS_DROP_NONE:
return false;
case CS_DROP_CALLBACK:
if(CanDropCallback)
{
return CanDropCallback(*this, cards);
}
else
{
return false;
}
default:
return false;
}
}
bool CardRegion::OnLButtonDblClk(int x, int y)
{
iNumDragCards = GetNumDragCards(x, y);
if(DblClickCallback)
DblClickCallback(*this, iNumDragCards);
return true;
}
bool CardRegion::OnLButtonDown(int x, int y)
{
iNumDragCards = GetNumDragCards(x, y);
#ifdef _DEBUG
if(DebugStackClickProc)
{
if(!DebugStackClickProc(*this))
return false;
}
#endif
if(ClickCallback)
ClickCallback(*this, iNumDragCards);
if(CanDragCards(iNumDragCards) != false)
{
//offset of the mouse cursor relative to the top-left corner
//of the cards that are being dragged
mousexoffset = x - xpos - xoffset * (nNumApparentCards - iNumDragCards);
mouseyoffset = y - ypos - yoffset * (nNumApparentCards - iNumDragCards);
if(xoffset < 0)
mousexoffset += -xoffset * (iNumDragCards - 1);
if(yoffset < 0)
mouseyoffset += -yoffset * (iNumDragCards - 1);
//remove the cards from the source stack
dragstack = cardstack.Pop(iNumDragCards);
//prepare the back buffer, and the drag image
PrepareDragBitmaps(iNumDragCards);
oldx = x - mousexoffset;
oldy = y - mouseyoffset;
Update(); //Update this stack's card count + size
SetCapture((HWND)parentWnd);
//set AFTER settings the dragstack...
fMouseDragging = true;
return true;
}
return false;
}
bool CardRegion::OnLButtonUp(int x, int y)
{
CardRegion *pDestStack = 0;
HDC hdc;
int dropstackid = CS_DROPZONE_NODROP;
RECT dragrect;
DropZone *dropzone;
fMouseDragging = false;
//first of all, see if any drop zones have been registered
SetRect(&dragrect, x-mousexoffset, y-mouseyoffset, x-mousexoffset+nDragCardWidth, y-mouseyoffset+nDragCardHeight);
dropzone = parentWnd.GetDropZoneFromRect(&dragrect);
if(dropzone)
{
dropstackid = dropzone->DropCards(dragstack);
if(dropstackid != CS_DROPZONE_NODROP)
pDestStack = parentWnd.CardRegionFromId(dropstackid);
else
pDestStack = 0;
}
else
{
pDestStack = parentWnd.GetBestStack(x - mousexoffset, y - mouseyoffset, nDragCardWidth, nDragCardHeight);
}
// If have found a stack to drop onto
//
TRACE ( "can I drop card?\n" );
if(pDestStack && pDestStack->CanDropCards(dragstack))
{
TRACE ( "yes, dropping card\n" );
hdc = GetDC((HWND)parentWnd);
// UseNicePalette(hdc);
ZoomCard(hdc, x - mousexoffset, y - mouseyoffset, pDestStack);
ReleaseDC((HWND)parentWnd, hdc);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?