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