169e62e48SStephan Aßmus /* 24c587adeSStephan Aßmus * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. 34c587adeSStephan Aßmus * Copyright 2010 Adam Smith <adamd.smith@utoronto.ca> 44c587adeSStephan Aßmus * All rights reserved. Distributed under the terms of the MIT License. 569e62e48SStephan Aßmus */ 669e62e48SStephan Aßmus 70eb592d7SAxel Dörfler #include "PairsWindow.h" 80eb592d7SAxel Dörfler 969e62e48SStephan Aßmus #include <stdio.h> 1069e62e48SStephan Aßmus 1169e62e48SStephan Aßmus #include <Application.h> 1269e62e48SStephan Aßmus #include <Alert.h> 1384df7867SAdrien Destugues #include <Button.h> 1484df7867SAdrien Destugues #include <Catalog.h> 1584df7867SAdrien Destugues #include <Locale.h> 164c587adeSStephan Aßmus #include <Menu.h> 174c587adeSStephan Aßmus #include <MenuBar.h> 184c587adeSStephan Aßmus #include <MenuItem.h> 1984df7867SAdrien Destugues #include <MessageRunner.h> 2069e62e48SStephan Aßmus #include <String.h> 2184df7867SAdrien Destugues #include <TextView.h> 2269e62e48SStephan Aßmus 2369e62e48SStephan Aßmus #include "Pairs.h" 2469e62e48SStephan Aßmus #include "PairsGlobal.h" 2569e62e48SStephan Aßmus #include "PairsView.h" 2669e62e48SStephan Aßmus #include "PairsTopButton.h" 2769e62e48SStephan Aßmus 284c587adeSStephan Aßmus 2984df7867SAdrien Destugues // #pragma mark - PairsWindow 304c587adeSStephan Aßmus 314c587adeSStephan Aßmus 32*4eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT 33*4eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "PairsWindow" 3469e62e48SStephan Aßmus 354c587adeSStephan Aßmus const uint32 MENU_NEW = 'MGnw'; 364c587adeSStephan Aßmus const uint32 MENU_SIZE = 'MGsz'; 374c587adeSStephan Aßmus const uint32 MENU_QUIT = 'MGqu'; 384c587adeSStephan Aßmus 394c587adeSStephan Aßmus 4069e62e48SStephan Aßmus PairsWindow::PairsWindow() 414c587adeSStephan Aßmus : 4299d126bdSMatt Madia BWindow(BRect(100, 100, 405, 423), B_TRANSLATE("Pairs"), B_TITLED_WINDOW, 4369e62e48SStephan Aßmus B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE 4469e62e48SStephan Aßmus | B_NOT_RESIZABLE | B_NOT_ZOOMABLE), 4569e62e48SStephan Aßmus fPairComparing(NULL), 4669e62e48SStephan Aßmus fIsFirstClick(true), 4769e62e48SStephan Aßmus fIsPairsActive(true), 4869e62e48SStephan Aßmus fPairCard(0), 4969e62e48SStephan Aßmus fPairCardTmp(0), 5069e62e48SStephan Aßmus fButtonTmp(0), 5169e62e48SStephan Aßmus fButton(0), 5269e62e48SStephan Aßmus fButtonClicks(0), 5369e62e48SStephan Aßmus fFinishPairs(0) 5469e62e48SStephan Aßmus { 554c587adeSStephan Aßmus _MakeMenuBar(); 564c587adeSStephan Aßmus _MakeGameView(4, 4); 5795087bc5SAxel Dörfler 5895087bc5SAxel Dörfler CenterOnScreen(); 5969e62e48SStephan Aßmus } 6069e62e48SStephan Aßmus 6169e62e48SStephan Aßmus 6269e62e48SStephan Aßmus PairsWindow::~PairsWindow() 6369e62e48SStephan Aßmus { 6469e62e48SStephan Aßmus delete fPairComparing; 6569e62e48SStephan Aßmus } 6669e62e48SStephan Aßmus 6769e62e48SStephan Aßmus 6869e62e48SStephan Aßmus void 694c587adeSStephan Aßmus PairsWindow::_MakeMenuBar() 704c587adeSStephan Aßmus { 714c587adeSStephan Aßmus fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar"); 724c587adeSStephan Aßmus AddChild(fMenuBar); 734c587adeSStephan Aßmus 7499d126bdSMatt Madia BMenu* menu = new BMenu(B_TRANSLATE("Game")); 754c587adeSStephan Aßmus fMenuBar->AddItem(menu); 764c587adeSStephan Aßmus 774c587adeSStephan Aßmus BMenuItem* menuItem; 7899d126bdSMatt Madia menu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("New"), 794c587adeSStephan Aßmus new BMessage(MENU_NEW), 'N')); 804c587adeSStephan Aßmus 814c587adeSStephan Aßmus menu->AddSeparatorItem(); 824c587adeSStephan Aßmus 8399d126bdSMatt Madia BMenu* sizeMenu = new BMenu(B_TRANSLATE("Size")); 844c587adeSStephan Aßmus sizeMenu->SetRadioMode(true); 854c587adeSStephan Aßmus 864c587adeSStephan Aßmus BMessage* sizeMessage = new BMessage(MENU_SIZE); 874c587adeSStephan Aßmus sizeMessage->AddInt32("width", 4); 884c587adeSStephan Aßmus sizeMessage->AddInt32("height", 4); 8999d126bdSMatt Madia sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Beginner (4x4)"), 904c587adeSStephan Aßmus sizeMessage)); 914c587adeSStephan Aßmus menuItem->SetMarked(true); 924c587adeSStephan Aßmus 934c587adeSStephan Aßmus sizeMessage = new BMessage(MENU_SIZE); 944c587adeSStephan Aßmus sizeMessage->AddInt32("width", 6); 954c587adeSStephan Aßmus sizeMessage->AddInt32("height", 6); 9699d126bdSMatt Madia sizeMenu->AddItem(menuItem = new BMenuItem( 9799d126bdSMatt Madia B_TRANSLATE("Intermediate (6x6)"), sizeMessage)); 984c587adeSStephan Aßmus 994c587adeSStephan Aßmus sizeMessage = new BMessage(MENU_SIZE); 1004c587adeSStephan Aßmus sizeMessage->AddInt32("width", 8); 1014c587adeSStephan Aßmus sizeMessage->AddInt32("height", 8); 10299d126bdSMatt Madia sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Expert (8x8)"), 1034c587adeSStephan Aßmus sizeMessage)); 1044c587adeSStephan Aßmus 1054c587adeSStephan Aßmus menu->AddItem(sizeMenu); 1064c587adeSStephan Aßmus 1074c587adeSStephan Aßmus menu->AddSeparatorItem(); 1084c587adeSStephan Aßmus 10999d126bdSMatt Madia menu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Quit"), 1104c587adeSStephan Aßmus new BMessage(MENU_QUIT), 'Q')); 1114c587adeSStephan Aßmus } 1124c587adeSStephan Aßmus 1134c587adeSStephan Aßmus 1144c587adeSStephan Aßmus void 1154c587adeSStephan Aßmus PairsWindow::_MakeGameView(int width, int height) 1164c587adeSStephan Aßmus { 1174c587adeSStephan Aßmus BRect viewBounds = Bounds(); 1184c587adeSStephan Aßmus viewBounds.top = fMenuBar->Bounds().Height() + 1; 1194c587adeSStephan Aßmus 1204c587adeSStephan Aßmus fPairsView = new PairsView(viewBounds, "PairsView", width, height, 1214c587adeSStephan Aßmus B_FOLLOW_NONE); 1224c587adeSStephan Aßmus fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 1234c587adeSStephan Aßmus AddChild(fPairsView); 1244c587adeSStephan Aßmus } 1254c587adeSStephan Aßmus 1264c587adeSStephan Aßmus 1274c587adeSStephan Aßmus void 1284c587adeSStephan Aßmus PairsWindow::NewGame() 1294c587adeSStephan Aßmus { 1304c587adeSStephan Aßmus fButtonClicks = 0; 1314c587adeSStephan Aßmus fFinishPairs = 0; 1324c587adeSStephan Aßmus fPairsView->CreateGameBoard(); 1334c587adeSStephan Aßmus } 1344c587adeSStephan Aßmus 1354c587adeSStephan Aßmus 1364c587adeSStephan Aßmus void 1374c587adeSStephan Aßmus PairsWindow::SetGameSize(int width, int height) 1384c587adeSStephan Aßmus { 1394c587adeSStephan Aßmus ResizeTo((kBitmapSize + kSpaceSize) * width + kSpaceSize, 1404c587adeSStephan Aßmus (kBitmapSize + kSpaceSize) * height + kSpaceSize 1414c587adeSStephan Aßmus + fMenuBar->Bounds().Height()); 1424c587adeSStephan Aßmus RemoveChild(fPairsView); 1434c587adeSStephan Aßmus delete fPairsView; 1444c587adeSStephan Aßmus _MakeGameView(width, height); 1454c587adeSStephan Aßmus NewGame(); 1464c587adeSStephan Aßmus } 1474c587adeSStephan Aßmus 1484c587adeSStephan Aßmus 1494c587adeSStephan Aßmus void 15069e62e48SStephan Aßmus PairsWindow::MessageReceived(BMessage* message) 15169e62e48SStephan Aßmus { 15269e62e48SStephan Aßmus switch (message->what) { 1534c587adeSStephan Aßmus case MENU_NEW: 1544c587adeSStephan Aßmus NewGame(); 1554c587adeSStephan Aßmus break; 1564c587adeSStephan Aßmus case MENU_SIZE: 1574c587adeSStephan Aßmus { 1584c587adeSStephan Aßmus int32 width; 1594c587adeSStephan Aßmus int32 height; 1604c587adeSStephan Aßmus if (message->FindInt32("width", &width) == B_OK 1614c587adeSStephan Aßmus && message->FindInt32("height", &height) == B_OK) { 1624c587adeSStephan Aßmus SetGameSize(width, height); 1634c587adeSStephan Aßmus } 1644c587adeSStephan Aßmus break; 1654c587adeSStephan Aßmus } 1664c587adeSStephan Aßmus case MENU_QUIT: 1674c587adeSStephan Aßmus be_app->PostMessage(B_QUIT_REQUESTED); 1684c587adeSStephan Aßmus break; 16969e62e48SStephan Aßmus case kMsgCardButton: 17069e62e48SStephan Aßmus if (fIsPairsActive) { 1710eb592d7SAxel Dörfler fButtonClicks++; 17269e62e48SStephan Aßmus 17369e62e48SStephan Aßmus int32 num; 17469e62e48SStephan Aßmus if (message->FindInt32("ButtonNum", &num) < B_OK) 17569e62e48SStephan Aßmus break; 17669e62e48SStephan Aßmus 17769e62e48SStephan Aßmus // look what Icon is behind a button 1784c587adeSStephan Aßmus for (int h = 0; h < fPairsView->fNumOfCards; h++) { 17969e62e48SStephan Aßmus if (fPairsView->GetIconFromPos(h) == num) { 1804c587adeSStephan Aßmus fPairCard = (h % fPairsView->fNumOfCards / 2); 18169e62e48SStephan Aßmus fButton = fPairsView->GetIconFromPos(h); 18269e62e48SStephan Aßmus break; 18369e62e48SStephan Aßmus } 18469e62e48SStephan Aßmus } 18569e62e48SStephan Aßmus 18669e62e48SStephan Aßmus // gameplay 1874c587adeSStephan Aßmus ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Hide(); 18869e62e48SStephan Aßmus 18969e62e48SStephan Aßmus if (fIsFirstClick) { 19069e62e48SStephan Aßmus fPairCardTmp = fPairCard; 19169e62e48SStephan Aßmus fButtonTmp = fButton; 19269e62e48SStephan Aßmus } else { 19369e62e48SStephan Aßmus delete fPairComparing; 19469e62e48SStephan Aßmus // message of message runner might not have arrived 19569e62e48SStephan Aßmus // yet, so it is deleted here to prevent any leaking 19669e62e48SStephan Aßmus // just in case 1974a89dc95SAlexandre Deckner BMessage message(kMsgPairComparing); 19869e62e48SStephan Aßmus fPairComparing = new BMessageRunner(BMessenger(this), 1994a89dc95SAlexandre Deckner &message, 5 * 100000L, 1); 20069e62e48SStephan Aßmus fIsPairsActive = false; 20169e62e48SStephan Aßmus } 20269e62e48SStephan Aßmus 20369e62e48SStephan Aßmus fIsFirstClick = !fIsFirstClick; 20469e62e48SStephan Aßmus } 20569e62e48SStephan Aßmus break; 20669e62e48SStephan Aßmus 20769e62e48SStephan Aßmus case kMsgPairComparing: 20869e62e48SStephan Aßmus delete fPairComparing; 20969e62e48SStephan Aßmus fPairComparing = NULL; 21069e62e48SStephan Aßmus 21169e62e48SStephan Aßmus fIsPairsActive = true; 21269e62e48SStephan Aßmus 2134c587adeSStephan Aßmus if (fPairCard == fPairCardTmp) 21469e62e48SStephan Aßmus fFinishPairs++; 2154c587adeSStephan Aßmus else { 2164c587adeSStephan Aßmus ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Show(); 2174c587adeSStephan Aßmus ((TopButton*)fPairsView->fDeckCard.ItemAt(fButtonTmp))->Show(); 21869e62e48SStephan Aßmus } 21969e62e48SStephan Aßmus 22069e62e48SStephan Aßmus // game end and results 2214c587adeSStephan Aßmus if (fFinishPairs == fPairsView->fNumOfCards / 2) { 22269e62e48SStephan Aßmus BString strAbout; 2230b9dd3b0SAdrien Destugues BString score; 2240b9dd3b0SAdrien Destugues score << fButtonClicks; 22569e62e48SStephan Aßmus strAbout 22699d126bdSMatt Madia << B_TRANSLATE("Pairs\n" 2270b9dd3b0SAdrien Destugues "\twritten by Ralf Schülke\n" 2280b9dd3b0SAdrien Destugues "\tCopyright 2008-2010, Haiku Inc.\n" 2290b9dd3b0SAdrien Destugues "\n" 230420557d0SStephan Aßmus "You completed the game in %s clicks.\n"); 2310b9dd3b0SAdrien Destugues 2320b9dd3b0SAdrien Destugues strAbout.Replace("%s", score.String(), 1); 23369e62e48SStephan Aßmus 23499d126bdSMatt Madia BAlert* alert = new BAlert("about", 23599d126bdSMatt Madia B_TRANSLATE(strAbout.String()), 23699d126bdSMatt Madia B_TRANSLATE("New game"), 23799d126bdSMatt Madia B_TRANSLATE("Quit game")); 23869e62e48SStephan Aßmus 23969e62e48SStephan Aßmus BTextView* view = alert->TextView(); 24069e62e48SStephan Aßmus BFont font; 24169e62e48SStephan Aßmus 24269e62e48SStephan Aßmus view->SetStylable(true); 24369e62e48SStephan Aßmus 24469e62e48SStephan Aßmus view->GetFont(&font); 24569e62e48SStephan Aßmus font.SetSize(18); 24669e62e48SStephan Aßmus font.SetFace(B_BOLD_FACE); 24769e62e48SStephan Aßmus view->SetFontAndColor(0, 6, &font); 24869e62e48SStephan Aßmus view->ResizeToPreferred(); 24969e62e48SStephan Aßmus 25069e62e48SStephan Aßmus if (alert->Go() == 0) { 25169e62e48SStephan Aßmus // New game 2524c587adeSStephan Aßmus NewGame(); 25369e62e48SStephan Aßmus } else { 25469e62e48SStephan Aßmus // Quit game 25569e62e48SStephan Aßmus be_app->PostMessage(B_QUIT_REQUESTED); 25669e62e48SStephan Aßmus } 25769e62e48SStephan Aßmus } 25869e62e48SStephan Aßmus break; 25969e62e48SStephan Aßmus 26069e62e48SStephan Aßmus default: 26169e62e48SStephan Aßmus BWindow::MessageReceived(message); 26269e62e48SStephan Aßmus break; 26369e62e48SStephan Aßmus } 26469e62e48SStephan Aßmus } 265