Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cardregion.cpp

Go to the documentation of this file.
00001 //
00002 //    CardLib - CardRegion class
00003 //
00004 //    Freeware
00005 //    Copyright J Brown 2001
00006 //
00007 #include <windows.h>
00008 
00009 #include "cardlib.h"
00010 #include "cardregion.h"
00011 #include "cardwindow.h"
00012 #include "cardcolor.h"
00013 
00014 HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, int width, int height);
00015 
00016 void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
00017 
00018 CardRegion::CardRegion(CardWindow &parent, int Id, bool visible, int x, int y, int xOffset, int yOffset)
00019 : id(Id), parentWnd(parent), xpos(x), ypos(y), xoffset(xOffset), yoffset(yOffset), fVisible(visible)
00020 {
00021     width  = __cardwidth;
00022     height = __cardheight;
00023 
00024     crBackgnd  = RGB(0, 64, 100);
00025 
00026     uFaceDirType   = CS_FACE_UP;
00027     nFaceDirOption = 0;
00028     uEmptyImage  = CS_EI_SUNK;
00029 
00030     fVisible     = visible;
00031 
00032     nThreedCount = 1;
00033 
00034     Update();                //Update this stack's size+card count
00035 
00036     hdcBackGnd = 0;
00037     hbmBackGnd = 0;
00038     hdcDragCard = 0;
00039     hbmDragCard = 0;
00040 
00041     nDragCardWidth = 0;
00042     nDragCardHeight = 0;
00043 
00044     CanDragCallback  = 0;
00045     CanDropCallback  = 0;
00046     AddCallback      = 0;
00047     RemoveCallback   = 0;
00048     ClickCallback    = 0;
00049     ClickReleaseCallback = 0;
00050     DblClickCallback = 0;
00051 
00052     uDragRule = CS_DRAG_ALL;
00053     uDropRule = CS_DROP_ALL;
00054 
00055     xjustify = yjustify = xadjust = yadjust = 0;
00056 
00057     nFlashCount        = 0;
00058     fFlashVisible    = false;
00059     uFlashTimer        = (UINT)-1;
00060 
00061     fMouseDragging = false;
00062 
00063     mxlock = CreateMutex(0, FALSE, 0);
00064 }
00065 
00066 CardRegion::~CardRegion()
00067 {
00068     CloseHandle(mxlock);
00069 }
00070 
00071 void CardRegion::SetBackColor(COLORREF cr)
00072 {
00073     crBackgnd = cr;
00074 }
00075 
00076 int CardRegion::CalcApparentCards(int realnum)
00077 {
00078     return ((realnum + nThreedCount - 1) - (realnum + nThreedCount - 1) % nThreedCount) / nThreedCount;
00079 }
00080 
00081 void CardRegion::CalcApparentCards()
00082 {
00083     nNumApparentCards = CalcApparentCards(cardstack.NumCards());
00084 }
00085 
00086 
00087 void CardRegion::UpdateSize(void)
00088 {
00089     if(cardstack.NumCards() > 0)
00090     {
00091         if(xoffset > 0)
00092             width  = (nNumApparentCards - 1) * xoffset + __cardwidth;
00093         else
00094             width  = (nNumApparentCards - 1) * -xoffset + __cardwidth;
00095 
00096         if(yoffset > 0)
00097             height = (nNumApparentCards - 1) * yoffset + __cardheight;
00098         else
00099             height = (nNumApparentCards - 1) * -yoffset + __cardheight;
00100     }
00101     else
00102     {
00103         width = __cardwidth;
00104         height = __cardheight;
00105     }
00106 }
00107 
00108 CardRegion *CardWindow::CreateRegion(int id, bool fVisible, int x, int y, int xoffset, int yoffset)
00109 {
00110     CardRegion *cr;
00111 
00112     if(nNumCardRegions == MAXCARDSTACKS)
00113         return FALSE;
00114 
00115     cr = new CardRegion(*this, id, fVisible, x, y, xoffset, yoffset);
00116     cr->SetBackColor(crBackgnd);
00117     cr->SetBackCardIdx(nBackCardIdx);
00118 
00119     Regions[nNumCardRegions++] = cr;
00120 
00121     return cr;
00122 }
00123 
00124 int CardRegion::GetOverlapRatio(int x, int y, int w, int h)
00125 {
00126     RECT me, him;
00127     RECT inter;
00128     SetRect(&him, x, y, x+w, y+h);
00129     SetRect(&me,  xpos, ypos, xpos+width, ypos+height);
00130 
00131     //see if the specified rectangle overlaps us
00132     if(IntersectRect(&inter, &me, &him))
00133     {
00134         int wi = inter.right  - inter.left;
00135         int hi = inter.bottom - inter.top;
00136 
00137         int overlap = wi * hi;
00138         int total   = width * height;
00139 
00140         int percent = (overlap << 16) / total;
00141         return (percent * 100) >> 16;
00142     }
00143     //do not overlap
00144     else
00145     {
00146         return 0;
00147     }
00148 }
00149 
00150 bool CardRegion::SetDragRule(UINT uDragType, pCanDragProc proc)
00151 {
00152     switch(uDragType)
00153     {
00154     case CS_DRAG_NONE: case CS_DRAG_ALL: case CS_DRAG_TOP:
00155         uDragRule = uDragType;
00156         return true;
00157 
00158     case CS_DRAG_CALLBACK:
00159         uDragRule = uDragType;
00160         CanDragCallback = proc;
00161         return true;
00162 
00163     default:
00164         return false;
00165     }
00166 }
00167 
00168 bool CardRegion::SetDropRule(UINT uDropType, pCanDropProc proc)
00169 {
00170     switch(uDropType)
00171     {
00172     case CS_DROP_NONE: case CS_DROP_ALL:
00173         uDropRule = uDropType;
00174         return true;
00175 
00176     case CS_DROP_CALLBACK:
00177         uDropRule = uDropType;
00178         CanDropCallback = proc;
00179         return true;
00180 
00181     default:
00182         return false;
00183     }
00184 }
00185 
00186 void CardRegion::SetClickProc(pClickProc proc)
00187 {
00188     ClickCallback = proc;
00189 }
00190 
00191 void CardRegion::SetClickReleaseProc(pClickProc proc)
00192 {
00193     ClickReleaseCallback = proc;
00194 }
00195 
00196 void CardRegion::SetDblClickProc(pClickProc proc)
00197 {
00198     DblClickCallback = proc;
00199 }
00200 
00201 void CardRegion::SetAddCardProc(pAddProc proc)
00202 {
00203     AddCallback = proc;
00204 }
00205 
00206 void CardRegion::SetRemoveCardProc(pRemoveProc proc)
00207 {
00208     RemoveCallback = proc;
00209 }
00210 
00211 void CardRegion::Update()
00212 {
00213     CalcApparentCards();
00214     UpdateSize();
00215     UpdateFaceDir(cardstack);
00216 }
00217 
00218 
00219 bool CardRegion::SetThreedCount(int count)
00220 {
00221     if(count < 1)
00222     {
00223         return false;
00224     }
00225     else
00226     {
00227         nThreedCount = count;
00228         return true;
00229     }
00230 }
00231 
00232 void CardRegion::SetOffsets(int x, int y)
00233 {
00234     xoffset = x;
00235     yoffset = y;
00236 }
00237 
00238 void CardRegion::SetPos(int x, int y)
00239 {
00240     xpos = x;
00241     ypos = y;
00242 }
00243 
00244 void CardRegion::Show(bool fShow)
00245 {
00246     fVisible = fShow;
00247 }
00248 
00249 bool CardRegion::IsVisible()
00250 {
00251     return fVisible;
00252 }
00253 
00254 void CardRegion::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)
00255 {
00256     xjustify = xJustify;
00257     yjustify = yJustify;
00258     xadjust  = xAdjust;
00259     yadjust  = yAdjust;
00260 }
00261 
00262 void CardRegion::SetFaceDirection(UINT uDirType, int nOption)
00263 {
00264     switch(uDirType)
00265     {
00266     case CS_FACE_UP:     case CS_FACE_DOWN: case CS_FACE_DOWNUP:
00267     case CS_FACE_UPDOWN: case CS_FACE_ANY:
00268         uFaceDirType    = uDirType;
00269         nFaceDirOption  = nOption;
00270 
00271         UpdateFaceDir(cardstack);
00272 
00273         break;
00274     }
00275 }
00276 
00277 UINT CardRegion::GetFaceDirection(int *pnOption)
00278 {
00279     if(pnOption)
00280         *pnOption = nFaceDirOption;
00281 
00282     return uFaceDirType;
00283 }
00284 
00285 void CardRegion::AdjustPosition(int winwidth, int winheight)
00286 {
00287     Update();            //Update this stack's card count + size
00288 
00289     switch(xjustify)
00290     {
00291     default: case CS_XJUST_NONE: break;
00292 
00293     case CS_XJUST_CENTER:        //centered
00294         xpos = (winwidth - (width & ~0x1)) / 2;
00295         xpos += xadjust;
00296 
00297         if(xoffset < 0)    xpos += (width - __cardwidth);
00298 
00299         break;
00300 
00301     case CS_XJUST_RIGHT:        //right-aligned
00302         xpos = winwidth - __cardwidth;//width - 20;
00303         xpos += xadjust;
00304         break;
00305     }
00306 
00307     switch(yjustify)
00308     {
00309     default: case CS_YJUST_NONE: break;
00310 
00311     case CS_YJUST_CENTER:        //centered
00312         ypos = (winheight - height) / 2;
00313         ypos += yadjust;
00314         if(yoffset < 0)    ypos += (height - __cardheight);
00315         break;
00316 
00317     case CS_YJUST_BOTTOM:        //bottom-aligned
00318         ypos = winheight - __cardheight;//height - 20;
00319         ypos += yadjust;
00320         break;
00321     }
00322 
00323 }
00324 
00325 
00326 void CardRegion::Flash(int count, int milliseconds)
00327 {
00328     if(count <= 0) return;
00329 
00330     nFlashCount        = count;
00331     fFlashVisible   = false;
00332     uFlashTimer        = SetTimer((HWND)parentWnd, (WPARAM)this, milliseconds, 0);
00333 
00334     parentWnd.Redraw();
00335 }
00336 
00337 void CardRegion::StopFlash()
00338 {
00339     if(uFlashTimer != (UINT)-1)
00340     {
00341         KillTimer((HWND)parentWnd, uFlashTimer);
00342         nFlashCount        = 0;
00343         uFlashTimer        = (UINT)-1;
00344         fFlashVisible    = true;
00345     }
00346 }
00347 
00348 void CardRegion::DoFlash()
00349 {
00350     if(uFlashTimer != (UINT)-1)
00351     {
00352         fFlashVisible = !fFlashVisible;
00353 
00354         if(--nFlashCount == 0)
00355         {
00356             KillTimer((HWND)parentWnd, uFlashTimer);
00357             uFlashTimer = (UINT)-1;
00358             fFlashVisible = true;
00359         }
00360 
00361         parentWnd.Redraw();
00362     }
00363 }
00364 
00365 int CardRegion::Id()
00366 {
00367     return id;
00368 }
00369 
00370 void CardRegion::SetEmptyImage(UINT uImage)
00371 {
00372     switch(uImage)
00373     {
00374     case CS_EI_NONE:
00375     case CS_EI_SUNK:
00376     case CS_EI_CIRC:
00377     case CS_EI_X:
00378         uEmptyImage = uImage;
00379         break;
00380 
00381     default:
00382         uEmptyImage = CS_EI_NONE;
00383         break;
00384     }
00385 
00386 }
00387 
00388 void CardRegion::SetBackCardIdx(UINT uBackIdx)
00389 {
00390     if(uBackIdx >= 52 && uBackIdx <= 68)
00391         nBackCardIdx = uBackIdx;
00392 }
00393 
00394 void CardRegion::SetCardStack(const CardStack &cs)
00395 {
00396     //make a complete copy of the specified stack..
00397     cardstack = cs;
00398 
00399     // Update the face-direction and stack-size
00400     Update();
00401 }
00402 
00403 const CardStack & CardRegion::GetCardStack()
00404 {
00405     //return reference to our internal stack
00406     return cardstack;
00407 }
00408 
00409 //
00410 //    Update specified card-stack using THIS stack's
00411 //  face direction rules!
00412 //
00413 void CardRegion::UpdateFaceDir(CardStack &cards)
00414 {
00415     int i, n, num;
00416 
00417     num = cards.NumCards();
00418 
00419     //Now apply the face direction rules..
00420     switch(uFaceDirType)
00421     {
00422     case CS_FACE_UP:
00423 
00424         for(i = 0; i < num; i++)
00425         {
00426             cards[i].SetFaceUp(true);
00427         }
00428 
00429         break;
00430 
00431     case CS_FACE_DOWN:
00432 
00433         for(i = 0; i < num; i++)
00434         {
00435             cards[i].SetFaceUp(false);
00436         }
00437 
00438         break;
00439 
00440     case CS_FACE_DOWNUP:
00441 
00442         num = cardstack.NumCards();
00443         n = min(nFaceDirOption, num);
00444 
00445         //bottom n cards..
00446         for(i = 0; i < n; i++)
00447         {
00448             cards[num - i - 1].SetFaceUp(false);
00449         }
00450 
00451         for(i = n; i < num; i++)
00452         {
00453             cards[num - i - 1].SetFaceUp(true);
00454         }
00455 
00456         break;
00457 
00458     case CS_FACE_UPDOWN:
00459 
00460         num = cardstack.NumCards();
00461         n = min(nFaceDirOption, num);
00462 
00463         for(i = 0; i < n; i++)
00464         {
00465             cards[num - i - 1].SetFaceUp(true);
00466         }
00467 
00468         for(i = n; i < num; i++)
00469         {
00470             cards[num - i - 1].SetFaceUp(false);
00471         }
00472 
00473         break;
00474 
00475     case CS_FACE_ANY:    //cards can be any orientation
00476     default:
00477         break;
00478     }
00479 }
00480 
00481 bool CardRegion::MoveCard(CardRegion *pDestStack, int nNumCards, bool fAnimate)
00482 {
00483     HDC hdc;
00484 
00485     int x, y;
00486 
00487     if(pDestStack == 0) return false; //{ forcedfacedir = -1 ;return 0; }
00488 
00489     if(nNumCards < 0 || nNumCards > cardstack.NumCards())
00490         return false;
00491 
00492     x = xpos + xoffset * (nNumApparentCards - nNumCards);
00493     y = ypos + yoffset * (nNumApparentCards - nNumCards);
00494 
00495     oldx = x;
00496     oldy = y;
00497 
00498     dragstack = cardstack.Pop(nNumCards);
00499 
00500     //Alter the drag-stack so that it's cards are the same way up
00501     //as the destination. Use the destination's drag-rules
00502     //instead of this ones!!
00503     CardStack temp;
00504     temp.Push(pDestStack->GetCardStack());
00505     temp.Push(dragstack);
00506 
00507     pDestStack->UpdateFaceDir(temp);
00508 
00509     dragstack = temp.Pop(nNumCards);
00510 
00511     if(fAnimate)
00512     {
00513         iNumDragCards = nNumCards;
00514         PrepareDragBitmaps(nNumCards);
00515     }
00516 
00517     Update();        //Update this stack's size+card count
00518 
00519     if(fAnimate)
00520     {
00521         hdc = GetDC((HWND)parentWnd);
00522 
00523         ZoomCard(hdc, x, y, pDestStack);
00524 
00525         ReleaseDC((HWND)parentWnd, hdc);
00526         ReleaseDragBitmaps();
00527     }
00528 
00529     // Get a copy of the cardstack
00530     CardStack cs = pDestStack->GetCardStack();
00531     cs.Push(dragstack);
00532 
00533     pDestStack->SetCardStack(cs);
00534 
00535     //cs = pDestStack->GetCardStack();
00536     //pDestStack->Update();
00537     //pDestStack->UpdateFaceDir(cs);
00538 
00539     RedrawIfNotDim(pDestStack, false);
00540 
00541     //forcedfacedir = -1;
00542     return true;
00543 }
00544 
00545 //
00546 //    Simple wrappers
00547 //
00548 int CardRegion::NumCards() const
00549 {
00550     if(fMouseDragging)
00551         return cardstack.NumCards() + dragstack.NumCards();
00552     else
00553         return cardstack.NumCards();
00554 }
00555 
00556 bool CardRegion::Lock()
00557 {
00558     DWORD dw = WaitForSingleObject(mxlock, 0);
00559 
00560     if(dw == WAIT_OBJECT_0)
00561     {
00562         //TRACE("LockStack succeeded\n");
00563         return true;
00564     }
00565     else
00566     {
00567         //TRACE("LockStack failed\n");
00568         return false;
00569     }
00570     return false;
00571 }
00572 
00573 bool CardRegion::UnLock()
00574 {
00575     if(ReleaseMutex(mxlock))
00576     {
00577         //TRACE("Unlocking stack\n");
00578         return true;
00579     }
00580     else
00581     {
00582         //TRACE("Unlocking stack failed\n");
00583         return false;
00584     }
00585 }
00586 
00587 bool CardRegion::PlayCard(CardRegion *pDestStack, int value, int num)
00588 {
00589     //search the stack for the specified card value...
00590     while(num--)
00591     {
00592         for(int i = 0; i < cardstack.NumCards(); i++)
00593         {
00594             if(cardstack[i].HiVal() == value)
00595             {
00596                 //swap the card with one at top pos...
00597                 Card card = cardstack.RemoveCard(i);
00598                 cardstack.Push(card);
00599 
00600                 Redraw();
00601 
00602                 MoveCard(pDestStack, 1, true);
00603                 break;
00604             }
00605         }
00606     }
00607 
00608     return true;
00609 }
00610 
00611 //
00612 //    Redraw the current stack if it has a different
00613 //    layout than the comparison stack.
00614 //
00615 void CardRegion::RedrawIfNotDim(CardRegion *pCompare, bool fFullRedraw)
00616 {
00617     //
00618     //
00619     //
00620     if( pCompare->xoffset != xoffset ||
00621         pCompare->yoffset != yoffset ||
00622         pCompare->nThreedCount != nThreedCount ||
00623         pCompare->uFaceDirType != uFaceDirType ||
00624         pCompare->uFaceDirType != CS_FACE_ANY
00625         )
00626     {
00627         if(fFullRedraw)
00628             parentWnd.Redraw();
00629         else
00630             pCompare->Redraw();
00631     }
00632 
00633 }
00634 
00635 //
00636 //    SimulateDrag mimicks the complete drag+drop process.
00637 //  It basically just a MoveCard(..), but it calls the
00638 //  event callbacks as well.
00639 //
00640 bool CardRegion::SimulateDrag(CardRegion *pDestStack, int iNumDragCards, bool fAnimate)
00641 {
00642     if(pDestStack == 0)
00643         return false;
00644 
00645     if(CanDragCards(iNumDragCards) != false)
00646     {
00647         if(pDestStack->CanDropCards(cardstack))
00648         {
00649             MoveCard(pDestStack, iNumDragCards, fAnimate);
00650 
00651             if(RemoveCallback)
00652                 RemoveCallback(*this, iNumDragCards);
00653 
00654             if(pDestStack->AddCallback)
00655                 pDestStack->AddCallback(*pDestStack, pDestStack->cardstack);
00656 
00657             RedrawIfNotDim(pDestStack, true);
00658         }
00659 
00660     }
00661 
00662     return true;
00663 }

Generated on Thu Feb 9 04:59:25 2012 for ReactOS by doxygen 1.6.3

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.