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> 4*c6b0a589SJohn Scipione * Copyright 2014 Haiku, Inc. All rights reserved. 5*c6b0a589SJohn Scipione * 6*c6b0a589SJohn Scipione * Distributed under the terms of the MIT License. 7*c6b0a589SJohn Scipione * 8*c6b0a589SJohn Scipione * Authors: 9*c6b0a589SJohn Scipione * John Scipione, jscipione@gmail.com 1069e62e48SStephan Aßmus */ 1169e62e48SStephan Aßmus 12*c6b0a589SJohn Scipione 130eb592d7SAxel Dörfler #include "PairsWindow.h" 140eb592d7SAxel Dörfler 1569e62e48SStephan Aßmus #include <stdio.h> 1669e62e48SStephan Aßmus 1769e62e48SStephan Aßmus #include <Application.h> 1869e62e48SStephan Aßmus #include <Alert.h> 1984df7867SAdrien Destugues #include <Button.h> 2084df7867SAdrien Destugues #include <Catalog.h> 214c587adeSStephan Aßmus #include <Menu.h> 224c587adeSStephan Aßmus #include <MenuBar.h> 234c587adeSStephan Aßmus #include <MenuItem.h> 2484df7867SAdrien Destugues #include <MessageRunner.h> 2569e62e48SStephan Aßmus #include <String.h> 2684df7867SAdrien Destugues #include <TextView.h> 2769e62e48SStephan Aßmus 2869e62e48SStephan Aßmus #include "Pairs.h" 2969e62e48SStephan Aßmus #include "PairsGlobal.h" 3069e62e48SStephan Aßmus #include "PairsView.h" 3169e62e48SStephan Aßmus #include "PairsTopButton.h" 3269e62e48SStephan Aßmus 334c587adeSStephan Aßmus 34546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 35546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "PairsWindow" 3669e62e48SStephan Aßmus 37*c6b0a589SJohn Scipione 384c587adeSStephan Aßmus const uint32 MENU_NEW = 'MGnw'; 394c587adeSStephan Aßmus const uint32 MENU_SIZE = 'MGsz'; 404c587adeSStephan Aßmus const uint32 MENU_QUIT = 'MGqu'; 414c587adeSStephan Aßmus 424c587adeSStephan Aßmus 43*c6b0a589SJohn Scipione // #pragma mark - PairsWindow 44*c6b0a589SJohn Scipione 45*c6b0a589SJohn Scipione 4669e62e48SStephan Aßmus PairsWindow::PairsWindow() 474c587adeSStephan Aßmus : 48560ff447SJonas Sundström BWindow(BRect(100, 100, 405, 423), B_TRANSLATE_SYSTEM_NAME("Pairs"), 49b97c5149SJonas Sundström B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE 5069e62e48SStephan Aßmus | B_NOT_RESIZABLE | B_NOT_ZOOMABLE), 5169e62e48SStephan Aßmus fPairComparing(NULL), 5269e62e48SStephan Aßmus fIsFirstClick(true), 5369e62e48SStephan Aßmus fIsPairsActive(true), 5469e62e48SStephan Aßmus fPairCard(0), 5569e62e48SStephan Aßmus fPairCardTmp(0), 5669e62e48SStephan Aßmus fButtonTmp(0), 5769e62e48SStephan Aßmus fButton(0), 5869e62e48SStephan Aßmus fButtonClicks(0), 5969e62e48SStephan Aßmus fFinishPairs(0) 6069e62e48SStephan Aßmus { 614c587adeSStephan Aßmus _MakeMenuBar(); 624c587adeSStephan Aßmus _MakeGameView(4, 4); 6395087bc5SAxel Dörfler 6495087bc5SAxel Dörfler CenterOnScreen(); 6569e62e48SStephan Aßmus } 6669e62e48SStephan Aßmus 6769e62e48SStephan Aßmus 6869e62e48SStephan Aßmus PairsWindow::~PairsWindow() 6969e62e48SStephan Aßmus { 7069e62e48SStephan Aßmus delete fPairComparing; 7169e62e48SStephan Aßmus } 7269e62e48SStephan Aßmus 7369e62e48SStephan Aßmus 7469e62e48SStephan Aßmus void 754c587adeSStephan Aßmus PairsWindow::_MakeMenuBar() 764c587adeSStephan Aßmus { 774c587adeSStephan Aßmus fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar"); 784c587adeSStephan Aßmus AddChild(fMenuBar); 794c587adeSStephan Aßmus 8099d126bdSMatt Madia BMenu* menu = new BMenu(B_TRANSLATE("Game")); 814c587adeSStephan Aßmus fMenuBar->AddItem(menu); 824c587adeSStephan Aßmus 834c587adeSStephan Aßmus BMenuItem* menuItem; 8499d126bdSMatt Madia menu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("New"), 854c587adeSStephan Aßmus new BMessage(MENU_NEW), 'N')); 864c587adeSStephan Aßmus 874c587adeSStephan Aßmus menu->AddSeparatorItem(); 884c587adeSStephan Aßmus 8999d126bdSMatt Madia BMenu* sizeMenu = new BMenu(B_TRANSLATE("Size")); 904c587adeSStephan Aßmus sizeMenu->SetRadioMode(true); 914c587adeSStephan Aßmus 924c587adeSStephan Aßmus BMessage* sizeMessage = new BMessage(MENU_SIZE); 934c587adeSStephan Aßmus sizeMessage->AddInt32("width", 4); 944c587adeSStephan Aßmus sizeMessage->AddInt32("height", 4); 9599d126bdSMatt Madia sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Beginner (4x4)"), 964c587adeSStephan Aßmus sizeMessage)); 974c587adeSStephan Aßmus menuItem->SetMarked(true); 984c587adeSStephan Aßmus 994c587adeSStephan Aßmus sizeMessage = new BMessage(MENU_SIZE); 1004c587adeSStephan Aßmus sizeMessage->AddInt32("width", 6); 1014c587adeSStephan Aßmus sizeMessage->AddInt32("height", 6); 10299d126bdSMatt Madia sizeMenu->AddItem(menuItem = new BMenuItem( 10399d126bdSMatt Madia B_TRANSLATE("Intermediate (6x6)"), sizeMessage)); 1044c587adeSStephan Aßmus 1054c587adeSStephan Aßmus sizeMessage = new BMessage(MENU_SIZE); 1064c587adeSStephan Aßmus sizeMessage->AddInt32("width", 8); 1074c587adeSStephan Aßmus sizeMessage->AddInt32("height", 8); 10899d126bdSMatt Madia sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Expert (8x8)"), 1094c587adeSStephan Aßmus sizeMessage)); 1104c587adeSStephan Aßmus 1114c587adeSStephan Aßmus menu->AddItem(sizeMenu); 1124c587adeSStephan Aßmus 1134c587adeSStephan Aßmus menu->AddSeparatorItem(); 1144c587adeSStephan Aßmus 11599d126bdSMatt Madia menu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Quit"), 1164c587adeSStephan Aßmus new BMessage(MENU_QUIT), 'Q')); 1174c587adeSStephan Aßmus } 1184c587adeSStephan Aßmus 1194c587adeSStephan Aßmus 1204c587adeSStephan Aßmus void 1214c587adeSStephan Aßmus PairsWindow::_MakeGameView(int width, int height) 1224c587adeSStephan Aßmus { 1234c587adeSStephan Aßmus BRect viewBounds = Bounds(); 1244c587adeSStephan Aßmus viewBounds.top = fMenuBar->Bounds().Height() + 1; 1254c587adeSStephan Aßmus 1264c587adeSStephan Aßmus fPairsView = new PairsView(viewBounds, "PairsView", width, height, 1274c587adeSStephan Aßmus B_FOLLOW_NONE); 1284c587adeSStephan Aßmus fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 1294c587adeSStephan Aßmus AddChild(fPairsView); 1304c587adeSStephan Aßmus } 1314c587adeSStephan Aßmus 1324c587adeSStephan Aßmus 1334c587adeSStephan Aßmus void 1344c587adeSStephan Aßmus PairsWindow::NewGame() 1354c587adeSStephan Aßmus { 1364c587adeSStephan Aßmus fButtonClicks = 0; 1374c587adeSStephan Aßmus fFinishPairs = 0; 1384c587adeSStephan Aßmus fPairsView->CreateGameBoard(); 1394c587adeSStephan Aßmus } 1404c587adeSStephan Aßmus 1414c587adeSStephan Aßmus 1424c587adeSStephan Aßmus void 1434c587adeSStephan Aßmus PairsWindow::SetGameSize(int width, int height) 1444c587adeSStephan Aßmus { 1454c587adeSStephan Aßmus ResizeTo((kBitmapSize + kSpaceSize) * width + kSpaceSize, 1464c587adeSStephan Aßmus (kBitmapSize + kSpaceSize) * height + kSpaceSize 1474c587adeSStephan Aßmus + fMenuBar->Bounds().Height()); 1484c587adeSStephan Aßmus RemoveChild(fPairsView); 1494c587adeSStephan Aßmus delete fPairsView; 1504c587adeSStephan Aßmus _MakeGameView(width, height); 1514c587adeSStephan Aßmus NewGame(); 1524c587adeSStephan Aßmus } 1534c587adeSStephan Aßmus 1544c587adeSStephan Aßmus 1554c587adeSStephan Aßmus void 15669e62e48SStephan Aßmus PairsWindow::MessageReceived(BMessage* message) 15769e62e48SStephan Aßmus { 15869e62e48SStephan Aßmus switch (message->what) { 1594c587adeSStephan Aßmus case MENU_NEW: 1604c587adeSStephan Aßmus NewGame(); 1614c587adeSStephan Aßmus break; 162*c6b0a589SJohn Scipione 1634c587adeSStephan Aßmus case MENU_SIZE: 1644c587adeSStephan Aßmus { 1654c587adeSStephan Aßmus int32 width; 1664c587adeSStephan Aßmus int32 height; 1674c587adeSStephan Aßmus if (message->FindInt32("width", &width) == B_OK 1684c587adeSStephan Aßmus && message->FindInt32("height", &height) == B_OK) { 1694c587adeSStephan Aßmus SetGameSize(width, height); 1704c587adeSStephan Aßmus } 1714c587adeSStephan Aßmus break; 1724c587adeSStephan Aßmus } 173*c6b0a589SJohn Scipione 1744c587adeSStephan Aßmus case MENU_QUIT: 1754c587adeSStephan Aßmus be_app->PostMessage(B_QUIT_REQUESTED); 1764c587adeSStephan Aßmus break; 177*c6b0a589SJohn Scipione 17869e62e48SStephan Aßmus case kMsgCardButton: 17969e62e48SStephan Aßmus if (fIsPairsActive) { 1800eb592d7SAxel Dörfler fButtonClicks++; 18169e62e48SStephan Aßmus 18269e62e48SStephan Aßmus int32 num; 18369e62e48SStephan Aßmus if (message->FindInt32("ButtonNum", &num) < B_OK) 18469e62e48SStephan Aßmus break; 18569e62e48SStephan Aßmus 18669e62e48SStephan Aßmus // look what Icon is behind a button 1874c587adeSStephan Aßmus for (int h = 0; h < fPairsView->fNumOfCards; h++) { 18869e62e48SStephan Aßmus if (fPairsView->GetIconFromPos(h) == num) { 1894c587adeSStephan Aßmus fPairCard = (h % fPairsView->fNumOfCards / 2); 19069e62e48SStephan Aßmus fButton = fPairsView->GetIconFromPos(h); 19169e62e48SStephan Aßmus break; 19269e62e48SStephan Aßmus } 19369e62e48SStephan Aßmus } 19469e62e48SStephan Aßmus 19569e62e48SStephan Aßmus // gameplay 1964c587adeSStephan Aßmus ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Hide(); 19769e62e48SStephan Aßmus 19869e62e48SStephan Aßmus if (fIsFirstClick) { 19969e62e48SStephan Aßmus fPairCardTmp = fPairCard; 20069e62e48SStephan Aßmus fButtonTmp = fButton; 20169e62e48SStephan Aßmus } else { 20269e62e48SStephan Aßmus delete fPairComparing; 20369e62e48SStephan Aßmus // message of message runner might not have arrived 20469e62e48SStephan Aßmus // yet, so it is deleted here to prevent any leaking 20569e62e48SStephan Aßmus // just in case 2064a89dc95SAlexandre Deckner BMessage message(kMsgPairComparing); 20769e62e48SStephan Aßmus fPairComparing = new BMessageRunner(BMessenger(this), 2084a89dc95SAlexandre Deckner &message, 5 * 100000L, 1); 20969e62e48SStephan Aßmus fIsPairsActive = false; 21069e62e48SStephan Aßmus } 21169e62e48SStephan Aßmus 21269e62e48SStephan Aßmus fIsFirstClick = !fIsFirstClick; 21369e62e48SStephan Aßmus } 21469e62e48SStephan Aßmus break; 21569e62e48SStephan Aßmus 21669e62e48SStephan Aßmus case kMsgPairComparing: 21769e62e48SStephan Aßmus delete fPairComparing; 21869e62e48SStephan Aßmus fPairComparing = NULL; 21969e62e48SStephan Aßmus 22069e62e48SStephan Aßmus fIsPairsActive = true; 22169e62e48SStephan Aßmus 2224c587adeSStephan Aßmus if (fPairCard == fPairCardTmp) 22369e62e48SStephan Aßmus fFinishPairs++; 2244c587adeSStephan Aßmus else { 2254c587adeSStephan Aßmus ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Show(); 2264c587adeSStephan Aßmus ((TopButton*)fPairsView->fDeckCard.ItemAt(fButtonTmp))->Show(); 22769e62e48SStephan Aßmus } 22869e62e48SStephan Aßmus 22969e62e48SStephan Aßmus // game end and results 2304c587adeSStephan Aßmus if (fFinishPairs == fPairsView->fNumOfCards / 2) { 2310b9dd3b0SAdrien Destugues BString score; 2320b9dd3b0SAdrien Destugues score << fButtonClicks; 23371302e7cSJonas Sundström BString strAbout = B_TRANSLATE("%app%\n" 2340b9dd3b0SAdrien Destugues "\twritten by Ralf Schülke\n" 2350b9dd3b0SAdrien Destugues "\tCopyright 2008-2010, Haiku Inc.\n" 2360b9dd3b0SAdrien Destugues "\n" 23771302e7cSJonas Sundström "You completed the game in %num% clicks.\n"); 2380b9dd3b0SAdrien Destugues 23971302e7cSJonas Sundström strAbout.ReplaceFirst("%app%", 240560ff447SJonas Sundström B_TRANSLATE_SYSTEM_NAME("Pairs")); 24171302e7cSJonas Sundström strAbout.ReplaceFirst("%num%", score); 24269e62e48SStephan Aßmus 24399d126bdSMatt Madia BAlert* alert = new BAlert("about", 2448eff03f5SOliver Tappe strAbout.String(), 24599d126bdSMatt Madia B_TRANSLATE("New game"), 24699d126bdSMatt Madia B_TRANSLATE("Quit game")); 24769e62e48SStephan Aßmus 24869e62e48SStephan Aßmus BTextView* view = alert->TextView(); 24969e62e48SStephan Aßmus BFont font; 25069e62e48SStephan Aßmus 25169e62e48SStephan Aßmus view->SetStylable(true); 25269e62e48SStephan Aßmus 25369e62e48SStephan Aßmus view->GetFont(&font); 25469e62e48SStephan Aßmus font.SetSize(18); 25569e62e48SStephan Aßmus font.SetFace(B_BOLD_FACE); 25671302e7cSJonas Sundström view->SetFontAndColor(0, 257560ff447SJonas Sundström strlen(B_TRANSLATE_SYSTEM_NAME("Pairs")), &font); 25869e62e48SStephan Aßmus view->ResizeToPreferred(); 2595b264395SAdrien Destugues alert->SetShortcut(0, B_ESCAPE); 26069e62e48SStephan Aßmus 261*c6b0a589SJohn Scipione if (alert->Go() == 0) 2624c587adeSStephan Aßmus NewGame(); 263*c6b0a589SJohn Scipione else 26469e62e48SStephan Aßmus be_app->PostMessage(B_QUIT_REQUESTED); 26569e62e48SStephan Aßmus } 26669e62e48SStephan Aßmus break; 26769e62e48SStephan Aßmus 26869e62e48SStephan Aßmus default: 26969e62e48SStephan Aßmus BWindow::MessageReceived(message); 27069e62e48SStephan Aßmus } 27169e62e48SStephan Aßmus } 272