xref: /haiku/src/apps/pairs/PairsWindow.cpp (revision c6b0a589df98b29405084ccb4a1d67dddd693648)
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