hrev46772 adds 3 changesets to branch 'master' old head: bfdb2a493884ca720e31bbdd42bae23764bce75c new head: 97e1b053b63ba10e037388a4e21bcb93a3220210 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=97e1b05+%5Ebfdb2a4 ---------------------------------------------------------------------------- c6b0a58: Pairs: Style fixes and update copyright headers. Update long description in rdef 0933046: Pairs: update version number to 0.9-gamma 97e1b05: Pairs: store vector icons, new size menu * Search for vector icons from MIME database once at start, limit to application super-type, this fulfills a TODO in the code * Use a std::map keyed by a hash to avoid duplicate icons eliminating _HasBitmap() * Store the vector representation and then only build bitmaps when needed * Convert uses of int to int32 * Convert from using BList to BObjectList, simplified cleanup * Rename variables and methods to not abbreviate/be more clear e.g. fPosX, fPosY => fPositionX, fPositionY e.g. _GenerateCardPos() => _GenerateCardPositions() * Renamed PairsTopButton to PairsButton * Integrate Size submenu into New menu item. Size menu item goes away, you can select New to get a new game at the current difficulty, or, you can drill down in the New menu to choose from Beginner, Intermediate, or Expert. * Add new Size menu to set the icon size: Small (32x32), Medium (64x64), or Large (128x128). Default is medium * Rename MENU_SIZE message constant to MENU_DIFFICULTY for clarity * Eliminate PairsGlobal.h, distribute constants to appropriate files. [ John Scipione <jscipione@xxxxxxxxx> ] ---------------------------------------------------------------------------- 13 files changed, 678 insertions(+), 417 deletions(-) src/apps/pairs/Jamfile | 5 +- src/apps/pairs/Pairs.cpp | 115 ++++++++++- src/apps/pairs/Pairs.h | 43 +++- src/apps/pairs/Pairs.rdef | 12 +- src/apps/pairs/PairsButton.cpp | 28 +++ src/apps/pairs/PairsButton.h | 25 +++ src/apps/pairs/PairsGlobal.h | 18 -- src/apps/pairs/PairsTopButton.cpp | 26 --- src/apps/pairs/PairsTopButton.h | 18 -- src/apps/pairs/PairsView.cpp | 349 ++++++++++++++++---------------- src/apps/pairs/PairsView.h | 64 ++++-- src/apps/pairs/PairsWindow.cpp | 361 +++++++++++++++++++++------------- src/apps/pairs/PairsWindow.h | 31 +-- ############################################################################ Commit: c6b0a589df98b29405084ccb4a1d67dddd693648 URL: http://cgit.haiku-os.org/haiku/commit/?id=c6b0a58 Author: John Scipione <jscipione@xxxxxxxxx> Date: Wed Jan 22 01:11:22 2014 UTC Pairs: Style fixes and update copyright headers. Update long description in rdef ---------------------------------------------------------------------------- diff --git a/src/apps/pairs/Pairs.cpp b/src/apps/pairs/Pairs.cpp index 0857716..561f0fd 100644 --- a/src/apps/pairs/Pairs.cpp +++ b/src/apps/pairs/Pairs.cpp @@ -1,19 +1,30 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ + +#include "Pairs.h" + #include <stdlib.h> #include <Application.h> #include <Catalog.h> -#include "Pairs.h" #include "PairsWindow.h" + const char* kSignature = "application/x-vnd.Haiku-Pairs"; +// #pragma mark - Pairs + + Pairs::Pairs() : BApplication(kSignature), @@ -49,6 +60,9 @@ Pairs::MessageReceived(BMessage* message) } +// #pragma mark - main + + int main(void) { diff --git a/src/apps/pairs/Pairs.h b/src/apps/pairs/Pairs.h index 0b58ec0..58d8309 100644 --- a/src/apps/pairs/Pairs.h +++ b/src/apps/pairs/Pairs.h @@ -1,29 +1,38 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ #ifndef PAIRS_H #define PAIRS_H + #include <Application.h> #include <Catalog.h> + extern const char* kSignature; + class BMessage; class PairsWindow; class Pairs : public BApplication { public: - Pairs(); - virtual ~Pairs(); + Pairs(); + virtual ~Pairs(); - virtual void ReadyToRun(); - virtual void RefsReceived(BMessage* message); - virtual void MessageReceived(BMessage* message); + virtual void ReadyToRun(); + virtual void RefsReceived(BMessage* message); + virtual void MessageReceived(BMessage* message); private: - PairsWindow* fWindow; + PairsWindow* fWindow; }; + #endif // PAIRS_H diff --git a/src/apps/pairs/Pairs.rdef b/src/apps/pairs/Pairs.rdef index e61a448..29f7ba2 100644 --- a/src/apps/pairs/Pairs.rdef +++ b/src/apps/pairs/Pairs.rdef @@ -18,7 +18,7 @@ resource app_version { internal = 1, short_info = "Pairs", - long_info = "Pairs, ©2008-2009 Haiku Inc." + long_info = "Pairs, ©2008 Ralf Schülke, ©2010 Adam Smith, ©2014 Haiku, Inc." }; @@ -41,4 +41,3 @@ resource vector_icon { $"070108000A060107000A0001041815FF01178400040A00010418001501178600" $"040A040104000A0301090815FF" }; - diff --git a/src/apps/pairs/PairsGlobal.h b/src/apps/pairs/PairsGlobal.h index cce15ae..af97f6c 100644 --- a/src/apps/pairs/PairsGlobal.h +++ b/src/apps/pairs/PairsGlobal.h @@ -1,11 +1,16 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ - #ifndef PAIRS_GLOBAL_H #define PAIRS_GLOBAL_H + #include <SupportDefs.h> diff --git a/src/apps/pairs/PairsTopButton.cpp b/src/apps/pairs/PairsTopButton.cpp index 37ecb60..f066c0c 100644 --- a/src/apps/pairs/PairsTopButton.cpp +++ b/src/apps/pairs/PairsTopButton.cpp @@ -1,7 +1,11 @@ /* - * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. - * All rights reserved. + * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. + * Copyright 2014 Haiku, Inc. All rights reserved. + * * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ #include <stdio.h> diff --git a/src/apps/pairs/PairsTopButton.h b/src/apps/pairs/PairsTopButton.h index dea5003..32632d1 100644 --- a/src/apps/pairs/PairsTopButton.h +++ b/src/apps/pairs/PairsTopButton.h @@ -1,6 +1,11 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ #ifndef PAIRS_TOP_BUTTON_H #define PAIRS_TOP_BUTTON_H diff --git a/src/apps/pairs/PairsView.cpp b/src/apps/pairs/PairsView.cpp index 64074be..2e1ba0e 100644 --- a/src/apps/pairs/PairsView.cpp +++ b/src/apps/pairs/PairsView.cpp @@ -1,9 +1,15 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. * Copyright 2010 Adam Smith <adamd.smith@xxxxxxxxxxx> - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ + #include "PairsView.h" #include <stdio.h> diff --git a/src/apps/pairs/PairsView.h b/src/apps/pairs/PairsView.h index 624ae22..cbcef74 100644 --- a/src/apps/pairs/PairsView.h +++ b/src/apps/pairs/PairsView.h @@ -1,7 +1,12 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. * Copyright 2010 Adam Smith <adamd.smith@xxxxxxxxxxx> - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ #ifndef PAIRS_VIEW_H #define PAIRS_VIEW_H diff --git a/src/apps/pairs/PairsWindow.cpp b/src/apps/pairs/PairsWindow.cpp index 5679b71..2a11514 100644 --- a/src/apps/pairs/PairsWindow.cpp +++ b/src/apps/pairs/PairsWindow.cpp @@ -1,9 +1,15 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. * Copyright 2010 Adam Smith <adamd.smith@xxxxxxxxxxx> - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ + #include "PairsWindow.h" #include <stdio.h> @@ -25,17 +31,18 @@ #include "PairsTopButton.h" -// #pragma mark - PairsWindow - - #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "PairsWindow" + const uint32 MENU_NEW = 'MGnw'; const uint32 MENU_SIZE = 'MGsz'; const uint32 MENU_QUIT = 'MGqu'; +// #pragma mark - PairsWindow + + PairsWindow::PairsWindow() : BWindow(BRect(100, 100, 405, 423), B_TRANSLATE_SYSTEM_NAME("Pairs"), @@ -152,6 +159,7 @@ PairsWindow::MessageReceived(BMessage* message) case MENU_NEW: NewGame(); break; + case MENU_SIZE: { int32 width; @@ -162,9 +170,11 @@ PairsWindow::MessageReceived(BMessage* message) } break; } + case MENU_QUIT: be_app->PostMessage(B_QUIT_REQUESTED); break; + case kMsgCardButton: if (fIsPairsActive) { fButtonClicks++; @@ -225,7 +235,7 @@ PairsWindow::MessageReceived(BMessage* message) "\tCopyright 2008-2010, Haiku Inc.\n" "\n" "You completed the game in %num% clicks.\n"); - + strAbout.ReplaceFirst("%app%", B_TRANSLATE_SYSTEM_NAME("Pairs")); strAbout.ReplaceFirst("%num%", score); @@ -248,18 +258,14 @@ PairsWindow::MessageReceived(BMessage* message) view->ResizeToPreferred(); alert->SetShortcut(0, B_ESCAPE); - if (alert->Go() == 0) { - // New game + if (alert->Go() == 0) NewGame(); - } else { - // Quit game + else be_app->PostMessage(B_QUIT_REQUESTED); - } } break; default: BWindow::MessageReceived(message); - break; } } diff --git a/src/apps/pairs/PairsWindow.h b/src/apps/pairs/PairsWindow.h index ed7cb5f..633e0dc 100644 --- a/src/apps/pairs/PairsWindow.h +++ b/src/apps/pairs/PairsWindow.h @@ -1,14 +1,20 @@ /* * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. * Copyright 2010 Adam Smith <adamd.smith@xxxxxxxxxxx> - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx */ - #ifndef PAIRS_WINDOW_H #define PAIRS_WINDOW_H + #include <Window.h> + class PairsView; class BMessageRunner; ############################################################################ Commit: 0933046655488e1ac4ccb09867acd95255d206b3 URL: http://cgit.haiku-os.org/haiku/commit/?id=0933046 Author: John Scipione <jscipione@xxxxxxxxx> Date: Wed Jan 22 01:11:42 2014 UTC Pairs: update version number to 0.9-gamma ---------------------------------------------------------------------------- diff --git a/src/apps/pairs/Pairs.rdef b/src/apps/pairs/Pairs.rdef index 29f7ba2..be8556e 100644 --- a/src/apps/pairs/Pairs.rdef +++ b/src/apps/pairs/Pairs.rdef @@ -7,14 +7,13 @@ resource app_flags B_SINGLE_LAUNCH; resource app_version { major = 0, - middle = 1, - minor = 2, - + middle = 9, + minor = 0, + /* 0 = development 1 = alpha 2 = beta 3 = gamma 4 = golden master 5 = final */ - - variety = 2, + variety = 3, internal = 1, short_info = "Pairs", ############################################################################ Revision: hrev46772 Commit: 97e1b053b63ba10e037388a4e21bcb93a3220210 URL: http://cgit.haiku-os.org/haiku/commit/?id=97e1b05 Author: John Scipione <jscipione@xxxxxxxxx> Date: Mon Jan 27 19:01:32 2014 UTC Pairs: store vector icons, new size menu * Search for vector icons from MIME database once at start, limit to application super-type, this fulfills a TODO in the code * Use a std::map keyed by a hash to avoid duplicate icons eliminating _HasBitmap() * Store the vector representation and then only build bitmaps when needed * Convert uses of int to int32 * Convert from using BList to BObjectList, simplified cleanup * Rename variables and methods to not abbreviate/be more clear e.g. fPosX, fPosY => fPositionX, fPositionY e.g. _GenerateCardPos() => _GenerateCardPositions() * Renamed PairsTopButton to PairsButton * Integrate Size submenu into New menu item. Size menu item goes away, you can select New to get a new game at the current difficulty, or, you can drill down in the New menu to choose from Beginner, Intermediate, or Expert. * Add new Size menu to set the icon size: Small (32x32), Medium (64x64), or Large (128x128). Default is medium * Rename MENU_SIZE message constant to MENU_DIFFICULTY for clarity * Eliminate PairsGlobal.h, distribute constants to appropriate files. ---------------------------------------------------------------------------- diff --git a/src/apps/pairs/Jamfile b/src/apps/pairs/Jamfile index 21541a5..f4d8698 100644 --- a/src/apps/pairs/Jamfile +++ b/src/apps/pairs/Jamfile @@ -2,9 +2,9 @@ SubDir HAIKU_TOP src apps pairs ; Application Pairs : Pairs.cpp - PairsWindow.cpp + PairsButton.cpp PairsView.cpp - PairsTopButton.cpp + PairsWindow.cpp : be localestub $(TARGET_LIBSTDC++) : Pairs.rdef @@ -13,6 +13,7 @@ Application Pairs : DoCatalogs Pairs : x-vnd.Haiku-Pairs : + Pairs.cpp PairsView.cpp PairsWindow.cpp ; diff --git a/src/apps/pairs/Pairs.cpp b/src/apps/pairs/Pairs.cpp index 561f0fd..27cb8ce 100644 --- a/src/apps/pairs/Pairs.cpp +++ b/src/apps/pairs/Pairs.cpp @@ -13,14 +13,22 @@ #include <stdlib.h> -#include <Application.h> +#include <Alert.h> #include <Catalog.h> +#include <MimeType.h> #include "PairsWindow.h" +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "Pairs" + + const char* kSignature = "application/x-vnd.Haiku-Pairs"; +static const size_t kMinIconCount = 64; +static const size_t kMaxIconCount = 384; + // #pragma mark - Pairs @@ -30,6 +38,7 @@ Pairs::Pairs() BApplication(kSignature), fWindow(NULL) { + _GetVectorIcons(); } @@ -60,6 +69,92 @@ Pairs::MessageReceived(BMessage* message) } +bool +Pairs::QuitRequested() +{ + // delete vector icons + for (IconMap::iterator iter = fIconMap.begin(); iter != fIconMap.end(); + ++iter) { + delete fIconMap[iter->first]; + } + + return true; +} + + +// #pragma mark - Pairs private methods + + +void +Pairs::_GetVectorIcons() +{ + // Load vector icons from the MIME type database and add a pointer to them + // into a std::map keyed by a generated hash. + + BMessage types; + if (BMimeType::GetInstalledTypes("application", &types) != B_OK) + return; + + const char* type; + for (int32 i = 0; types.FindString("types", i, &type) == B_OK; i++) { + BMimeType mimeType(type); + if (mimeType.InitCheck() != B_OK) + continue; + + uint8* data; + size_t size; + + if (mimeType.GetIcon(&data, &size) != B_OK) { + // didn't find an icon + continue; + } + + size_t hash = 0xdeadbeef; + for (size_t i = 0; i < size; i++) + hash = 31 * hash + data[i]; + + if (fIconMap.find(hash) != fIconMap.end()) { + // key has already been added to the map + delete[] data; + continue; + } + + vector_icon* icon = (vector_icon*)malloc(sizeof(vector_icon)); + if (icon == NULL) { + delete[] data; + free(icon); + continue; + } + + icon->data = data; + icon->size = size; + + // found a vector icon, add it to the list + fIconMap[hash] = icon; + if (fIconMap.size() >= kMaxIconCount) { + // this is enough to choose from, stop eating memory... + return; + } + } + + if (fIconMap.size() < kMinIconCount) { + char buffer[512]; + snprintf(buffer, sizeof(buffer), + B_TRANSLATE_COMMENT("Pairs did not find enough vector icons " + "to start; it needs at least %zu, found %zu.\n", + "Don't translate \"%zu\", but make sure to keep them."), + kMinIconCount, fIconMap.size()); + BString messageString(buffer); + BAlert* alert = new BAlert("Fatal", messageString.String(), + B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_FROM_WIDEST, + B_STOP_ALERT); + alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); + alert->Go(); + exit(1); + } +} + + // #pragma mark - main diff --git a/src/apps/pairs/Pairs.h b/src/apps/pairs/Pairs.h index 58d8309..222c328 100644 --- a/src/apps/pairs/Pairs.h +++ b/src/apps/pairs/Pairs.h @@ -11,27 +11,45 @@ #define PAIRS_H +#include <map> + #include <Application.h> -#include <Catalog.h> extern const char* kSignature; +struct vector_icon { + uint8* data; + size_t size; +}; + + +class BBitmap; class BMessage; class PairsWindow; + +typedef std::map<size_t, vector_icon*> IconMap; + + class Pairs : public BApplication { public: - Pairs(); - virtual ~Pairs(); + Pairs(); + virtual ~Pairs(); - virtual void ReadyToRun(); - virtual void RefsReceived(BMessage* message); - virtual void MessageReceived(BMessage* message); + virtual void ReadyToRun(); + virtual void RefsReceived(BMessage* message); + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); + + IconMap GetIconMap() const { return fIconMap; }; private: - PairsWindow* fWindow; + void _GetVectorIcons(); + + PairsWindow* fWindow; + IconMap fIconMap; }; diff --git a/src/apps/pairs/PairsButton.cpp b/src/apps/pairs/PairsButton.cpp new file mode 100644 index 0000000..c020a7a --- /dev/null +++ b/src/apps/pairs/PairsButton.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. + * Copyright 2014 Haiku, Inc. All rights reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@xxxxxxxxx + */ + + +#include "PairsButton.h" + + +// #pragma mark - PairsButton + + +PairsButton::PairsButton(int32 x, int32 y, int32 size, BMessage* message) + : + BButton(BRect(x, y, x + size, y + size), "pairs button", "?", message) +{ + SetFontSize(size - 15); +} + + +PairsButton::~PairsButton() +{ +} diff --git a/src/apps/pairs/PairsTopButton.h b/src/apps/pairs/PairsButton.h similarity index 50% rename from src/apps/pairs/PairsTopButton.h rename to src/apps/pairs/PairsButton.h index 32632d1..eb59a58 100644 --- a/src/apps/pairs/PairsTopButton.h +++ b/src/apps/pairs/PairsButton.h @@ -7,17 +7,19 @@ * Authors: * John Scipione, jscipione@xxxxxxxxx */ -#ifndef PAIRS_TOP_BUTTON_H -#define PAIRS_TOP_BUTTON_H +#ifndef PAIRS_BUTTON_H +#define PAIRS_BUTTON_H -#include <OS.h> -class BButton; +#include <Button.h> -class TopButton : public BButton { + +class PairsButton : public BButton { public: - TopButton(int x, int y, BMessage* message); - virtual ~TopButton(); + PairsButton(int32 x, int32 y, int32 size, + BMessage* message); + virtual ~PairsButton(); }; -#endif // PAIRS_TOP_BUTTON_H + +#endif // PAIRS_BUTTON_H diff --git a/src/apps/pairs/PairsGlobal.h b/src/apps/pairs/PairsGlobal.h deleted file mode 100644 index af97f6c..0000000 --- a/src/apps/pairs/PairsGlobal.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. - * Copyright 2014 Haiku, Inc. All rights reserved. - * - * Distributed under the terms of the MIT License. - * - * Authors: - * John Scipione, jscipione@xxxxxxxxx - */ -#ifndef PAIRS_GLOBAL_H -#define PAIRS_GLOBAL_H - - -#include <SupportDefs.h> - - -const uint32 kMsgCardButton = 'card'; -const uint32 kMsgPairComparing = 'pcom'; -const int kBitmapSize = 64; -const int kSpaceSize = 10; - - -#endif // PAIRS_GLOBAL_H diff --git a/src/apps/pairs/PairsTopButton.cpp b/src/apps/pairs/PairsTopButton.cpp deleted file mode 100644 index f066c0c..0000000 --- a/src/apps/pairs/PairsTopButton.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2008 Ralf Schülke, ralf.schuelke@xxxxxxxxxxxxxx. - * Copyright 2014 Haiku, Inc. All rights reserved. - * - * Distributed under the terms of the MIT License. - * - * Authors: - * John Scipione, jscipione@xxxxxxxxx - */ - -#include <stdio.h> -#include <unistd.h> - -#include <Button.h> - -#include "PairsTopButton.h" -#include "PairsGlobal.h" - - -TopButton::TopButton(int x, int y, BMessage* message) - : BButton(BRect(x, y, x + kBitmapSize, y + kBitmapSize), "top_button", - "?", message) -{ - SetFontSize(54); -} - - -TopButton::~TopButton() -{ -} diff --git a/src/apps/pairs/PairsView.cpp b/src/apps/pairs/PairsView.cpp index 2e1ba0e..1ac37c9 100644 --- a/src/apps/pairs/PairsView.cpp +++ b/src/apps/pairs/PairsView.cpp @@ -12,39 +12,44 @@ #include "PairsView.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <Alert.h> #include <Application.h> #include <Bitmap.h> #include <Button.h> +#include <ControlLook.h> #include <Catalog.h> -#include <Directory.h> -#include <Entry.h> -#include <FindDirectory.h> #include <IconUtils.h> -#include <List.h> -#include <Node.h> -#include <NodeInfo.h> -#include <Path.h> +#include <InterfaceDefs.h> +#include <Window.h> #include "Pairs.h" -#include "PairsGlobal.h" -#include "PairsTopButton.h" +#include "PairsButton.h" + + +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "PairsView" -PairsView::PairsView(BRect frame, const char* name, int width, int height, - uint32 resizingMode) + +// #pragma mark - PairsView + + +PairsView::PairsView(BRect frame, const char* name, uint8 rows, uint8 cols, + uint8 iconSize) : - BView(frame, name, resizingMode, B_WILL_DRAW), - fWidth(width), - fHeight(height), - fNumOfCards(width * height), - fRandPos(new int[fNumOfCards]), - fPosX(new int[fNumOfCards]), - fPosY(new int[fNumOfCards]) + BView(frame, name, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS), + fRows(rows), + fCols(cols), + fIconSize(iconSize), + fButtonsCount(rows * cols), + fCardsCount(fButtonsCount / 2), + fPairsButtonList(new BObjectList<PairsButton>(fButtonsCount)), + fSmallBitmapsList(new BObjectList<BBitmap>(fCardsCount)), + fMediumBitmapsList(new BObjectList<BBitmap>(fCardsCount)), + fLargeBitmapsList(new BObjectList<BBitmap>(fCardsCount)), + fRandomPosition(new int32[fButtonsCount]), + fPositionX(new int32[fButtonsCount]), + fPositionY(new int32[fButtonsCount]) { + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); CreateGameBoard(); _SetPairsBoard(); } @@ -54,209 +59,211 @@ void PairsView::CreateGameBoard() { // Show hidden buttons - for (int32 i = 0; i < CountChildren(); i++) { + int32 childrenCount = CountChildren(); + for (int32 i = 0; i < childrenCount; i++) { BView* child = ChildAt(i); if (child->IsHidden()) child->Show(); } - _GenerateCardPos(); + _GenerateCardPositions(); } PairsView::~PairsView() { - for (int i = 0; i < fCardBitmaps.CountItems(); i++) - delete ((BBitmap*)fCardBitmaps.ItemAt(i)); - - for (int i = 0; i < fDeckCard.CountItems(); i++) - delete ((TopButton*)fDeckCard.ItemAt(i)); - - delete fRandPos; - delete fPosX; - delete fPosY; + delete fSmallBitmapsList; + delete fMediumBitmapsList; + delete fLargeBitmapsList; + delete fPairsButtonList; + delete fRandomPosition; + delete fPositionX; + delete fPositionY; } void PairsView::AttachedToWindow() { - MakeFocus(true); -} - - -bool -PairsView::_HasBitmap(BList& bitmaps, BBitmap* bitmap) -{ - // TODO: if this takes too long, we could build a hash value for each - // bitmap in a separate list - for (int32 i = bitmaps.CountItems(); i-- > 0;) { - BBitmap* item = (BBitmap*)bitmaps.ItemAtFast(i); - if (!memcmp(item->Bits(), bitmap->Bits(), item->BitsLength())) - return true; + for (int32 i = 0; i < fButtonsCount; i++) { + PairsButton* button = fPairsButtonList->ItemAt(i); + if (button != NULL) + button->SetTarget(Window()); } - return false; + MakeFocus(true); + BView::AttachedToWindow(); } -#undef B_TRANSLATION_CONTEXT -#define B_TRANSLATION_CONTEXT "PairsView" void -PairsView::_ReadRandomIcons() +PairsView::Draw(BRect updateRect) { - // TODO: maybe read the icons only once at startup - - // clean out any previous icons - for (int i = 0; i < fCardBitmaps.CountItems(); i++) - delete ((BBitmap*)fCardBitmaps.ItemAt(i)); - - fCardBitmaps.MakeEmpty(); - - BDirectory appsDirectory; - BDirectory prefsDirectory; - - BPath path; - if (find_directory(B_BEOS_APPS_DIRECTORY, &path) == B_OK) - appsDirectory.SetTo(path.Path()); - if (find_directory(B_BEOS_PREFERENCES_DIRECTORY, &path) == B_OK) - prefsDirectory.SetTo(path.Path()); - - // read vector icons from apps and prefs folder and put them - // into a BList as BBitmaps - BList bitmaps; - - BEntry entry; - while (appsDirectory.GetNextEntry(&entry) == B_OK - || prefsDirectory.GetNextEntry(&entry) == B_OK) { - - BNode node(&entry); - BNodeInfo nodeInfo(&node); - - if (nodeInfo.InitCheck() < B_OK) - continue; - - uint8* data; - size_t size; - type_code type; - - if (nodeInfo.GetIcon(&data, &size, &type) < B_OK) - continue; - - if (type != B_VECTOR_ICON_TYPE) { - delete[] data; - continue; - } + BObjectList<BBitmap>* bitmapsList; + switch (fIconSize) { + case kSmallIconSize: + bitmapsList = fSmallBitmapsList; + break; - BBitmap* bitmap = new BBitmap( - BRect(0, 0, kBitmapSize - 1, kBitmapSize - 1), 0, B_RGBA32); - if (BIconUtils::GetVectorIcon(data, size, bitmap) < B_OK) { - delete[] data; - delete bitmap; - continue; - } + case kLargeIconSize: + bitmapsList = fLargeBitmapsList; + break; - delete[] data; + case kMediumIconSize: + default: + bitmapsList = fMediumBitmapsList; + } - if (_HasBitmap(bitmaps, bitmap) || !bitmaps.AddItem(bitmap)) - delete bitmap; - else if (bitmaps.CountItems() >= 128) { - // this is enough to choose from, stop eating memory... - break; - } + for (int32 i = 0; i < fButtonsCount; i++) { + SetDrawingMode(B_OP_ALPHA); + DrawBitmap(bitmapsList->ItemAt(i % (fButtonsCount / 2)), + BPoint(fPositionX[i], fPositionY[i])); + SetDrawingMode(B_OP_COPY); } +} - // pick random bitmaps from the ones we got in the list - srand((unsigned)time(0)); - for (int i = 0; i < fNumOfCards / 2; i++) { - int32 index = rand() % bitmaps.CountItems(); - BBitmap* bitmap = ((BBitmap*)bitmaps.RemoveItem(index)); - if (bitmap == NULL) { - char buffer[512]; - snprintf(buffer, sizeof(buffer), B_TRANSLATE("Pairs did not find " - "enough vector icons in the system; it needs at least %d."), - fNumOfCards / 2); - BString msgStr(buffer); - msgStr << "\n"; - BAlert* alert = new BAlert("Fatal", msgStr.String(), - B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_FROM_WIDEST, - B_STOP_ALERT); - alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); - alert->Go(); - exit(1); +void +PairsView::FrameResized(float newWidth, float newHeight) +{ + int32 spacing = Spacing(); + for (int32 i = 0; i < fButtonsCount; i++) { + PairsButton* button = fPairsButtonList->ItemAt(i); + if (button != NULL) { + button->ResizeTo(fIconSize, fIconSize); + int32 x = i % fRows * (fIconSize + spacing) + spacing; + int32 y = i / fCols * (fIconSize + spacing) + spacing; + button->MoveTo(x, y); + button->SetFontSize(fIconSize - 15); } - fCardBitmaps.AddItem(bitmap); } - // delete the remaining bitmaps from the list - while (BBitmap* bitmap = (BBitmap*)bitmaps.RemoveItem((int32)0)) - delete bitmap; + _SetPositions(); + Invalidate(BRect(0, 0, newWidth, newHeight)); + BView::FrameResized(newWidth, newHeight); } -void -PairsView::_SetPairsBoard() +int32 +PairsView::GetIconPosition(int32 index) { - for (int i = 0; i < fNumOfCards; i++) { - fButtonMessage = new BMessage(kMsgCardButton); - fButtonMessage->AddInt32("ButtonNum", i); + return fRandomPosition[index]; +} - int x = i % fWidth * (kBitmapSize + kSpaceSize) + kSpaceSize; - int y = i / fHeight * (kBitmapSize + kSpaceSize) + kSpaceSize; - TopButton* button = new TopButton(x, y, fButtonMessage); - fDeckCard.AddItem(button); - AddChild(button); - } -} +// #pragma mark - PairsView private methods void -PairsView::_GenerateCardPos() +PairsView::_GenerateCardPositions() { - _ReadRandomIcons(); - + // seed the random number generator based on the current timestamp srand((unsigned)time(0)); - int* positions = new int[fNumOfCards]; - for (int i = 0; i < fNumOfCards; i++) - positions[i] = i; - - for (int i = fNumOfCards; i >= 1; i--) { - int index = rand() % i; + _ReadRandomIcons(); - fRandPos[fNumOfCards - i] = positions[index]; + int32* positions = new int32[fButtonsCount]; + for (int32 i = 0; i < fButtonsCount; i++) + positions[i] = i; - for (int j = index; j < i - 1; j++) + for (int32 i = fButtonsCount; i > 0; i--) { + int32 index = rand() % i; + fRandomPosition[fButtonsCount - i] = positions[index]; + for (int32 j = index; j < i - 1; j++) positions[j] = positions[j + 1]; } + delete[] positions; + + _SetPositions(); +} - for (int i = 0; i < fNumOfCards; i++) { - fPosX[i] = (fRandPos[i]) % fWidth * (kBitmapSize + kSpaceSize) - + kSpaceSize; - fPosY[i] = (fRandPos[i]) / fHeight * (kBitmapSize + kSpaceSize) - + kSpaceSize; + +void +PairsView::_ReadRandomIcons() +{ + Pairs* app = dynamic_cast<Pairs*>(be_app); + if (app == NULL) // check if NULL to make Coverity happy + return; + + // Create a copy of the icon map so we can erase elements from it as we + // add them to the list eliminating repeated icons without altering the + // orginal IconMap. + IconMap tmpIconMap(app->GetIconMap()); + size_t mapSize = tmpIconMap.size(); + if (mapSize < (size_t)fCardsCount) { + // not enough icons, we're screwed + return; } - delete [] positions; + // clean out any previous icons + fSmallBitmapsList->MakeEmpty(); + fMediumBitmapsList->MakeEmpty(); + fLargeBitmapsList->MakeEmpty(); + + // pick bitmaps at random from the icon map + for (int32 i = 0; i < fCardsCount; i++) { + IconMap::iterator iter = tmpIconMap.begin(); + if (mapSize < (size_t)fCardsCount) { + // not enough valid icons, we're really screwed + return; + } + std::advance(iter, rand() % mapSize); + size_t key = iter->first; + vector_icon* icon = iter->second; + + BBitmap* smallBitmap = new BBitmap( + BRect(0, 0, kSmallIconSize - 1, kSmallIconSize - 1), B_RGBA32); + status_t smallResult = BIconUtils::GetVectorIcon(icon->data, + icon->size, smallBitmap); + BBitmap* mediumBitmap = new BBitmap( + BRect(0, 0, kMediumIconSize - 1, kMediumIconSize - 1), B_RGBA32); + status_t mediumResult = BIconUtils::GetVectorIcon(icon->data, + icon->size, mediumBitmap); + BBitmap* largeBitmap = new BBitmap( + BRect(0, 0, kLargeIconSize - 1, kLargeIconSize - 1), B_RGBA32); + status_t largeResult = BIconUtils::GetVectorIcon(icon->data, + icon->size, largeBitmap); + + if (smallResult + mediumResult + largeResult == B_OK) { + fSmallBitmapsList->AddItem(smallBitmap); + fMediumBitmapsList->AddItem(mediumBitmap); + fLargeBitmapsList->AddItem(largeBitmap); + } else { + delete smallBitmap; + delete mediumBitmap; + delete largeBitmap; + i--; + } + + mapSize -= tmpIconMap.erase(key); + // remove the element from the map so we don't read it again + } } void -PairsView::Draw(BRect updateRect) +PairsView::_SetPairsBoard() { - SetDrawingMode(B_OP_ALPHA); + int32 spacing = Spacing(); + for (int32 i = 0; i < fButtonsCount; i++) { + BMessage* buttonMessage = new BMessage(kMsgCardButton); + buttonMessage->AddInt32("button number", i); - // draw rand pair 1 & 2 - for (int i = 0; i < fNumOfCards; i++) { - BBitmap* bitmap = ((BBitmap*)fCardBitmaps.ItemAt(i % fNumOfCards / 2)); - DrawBitmap(bitmap, BPoint(fPosX[i], fPosY[i])); + int32 x = i % fRows * (fIconSize + spacing) + spacing; + int32 y = i / fCols * (fIconSize + spacing) + spacing; + + PairsButton* button = new PairsButton(x, y, fIconSize, buttonMessage); + fPairsButtonList->AddItem(button); + AddChild(button); } } -int -PairsView::GetIconFromPos(int pos) +void +PairsView::_SetPositions() { - return fRandPos[pos]; + int32 spacing = Spacing(); + for (int32 i = 0; i < fButtonsCount; i++) { + fPositionX[i] = fRandomPosition[i] % fRows * (fIconSize + spacing) + spacing; + fPositionY[i] = fRandomPosition[i] / fCols * (fIconSize + spacing) + spacing; + } } diff --git a/src/apps/pairs/PairsView.h b/src/apps/pairs/PairsView.h index cbcef74..c374872 100644 --- a/src/apps/pairs/PairsView.h +++ b/src/apps/pairs/PairsView.h @@ -12,40 +12,63 @@ #define PAIRS_VIEW_H +#include <ObjectList.h> #include <View.h> -class TopButton; +const uint8 kSmallIconSize = 32; +const uint8 kMediumIconSize = 64; +const uint8 kLargeIconSize = 128; + +const uint32 kMsgCardButton = 'card'; + + +class BBitmap; +class PairsButton; + class PairsView : public BView { public: PairsView(BRect frame, const char* name, - int width, int height, - uint32 resizingMode); + uint8 rows, uint8 cols, uint8 iconSize); virtual ~PairsView(); virtual void AttachedToWindow(); virtual void Draw(BRect updateRect); + virtual void FrameResized(float newWidth, float newHeight); + virtual void CreateGameBoard(); - int fWidth; - int fHeight; - int fNumOfCards; + int32 Rows() const { return fRows; }; + int32 Cols() const { return fCols; }; + BObjectList<PairsButton>* PairsButtonList() const + { return fPairsButtonList; }; - BList fDeckCard; - int GetIconFromPos(int pos); + int32 GetIconPosition(int32 index); + + int32 IconSize() const { return fIconSize; }; + void SetIconSize(int32 size) { fIconSize = size; }; + + int32 Spacing() const { return fIconSize / 6; }; private: - void _SetPairsBoard(); + void _GenerateCardPositions(); void _ReadRandomIcons(); - void _GenerateCardPos(); - bool _HasBitmap(BList& bitmaps, BBitmap* bitmap); - - BMessage* fButtonMessage; - BList fCardBitmaps; - int* fRandPos; - int* fPosX; - int* fPosY; + void _SetPairsBoard(); + void _SetPositions(); + + uint8 fRows; + uint8 fCols; + uint8 fIconSize; + int32 fButtonsCount; + int32 fCardsCount; + BObjectList<PairsButton>* fPairsButtonList; + BObjectList<BBitmap>* fSmallBitmapsList; + BObjectList<BBitmap>* fMediumBitmapsList; + BObjectList<BBitmap>* fLargeBitmapsList; + int32* fRandomPosition; + int32* fPositionX; + int32* fPositionY; }; diff --git a/src/apps/pairs/PairsWindow.cpp b/src/apps/pairs/PairsWindow.cpp index 2a11514..3d09164 100644 --- a/src/apps/pairs/PairsWindow.cpp +++ b/src/apps/pairs/PairsWindow.cpp @@ -12,12 +12,11 @@ #include "PairsWindow.h" -#include <stdio.h> - #include <Application.h> #include <Alert.h> #include <Button.h> #include <Catalog.h> +#include <ObjectList.h> #include <Menu.h> #include <MenuBar.h> #include <MenuItem.h> @@ -26,9 +25,8 @@ #include <TextView.h> #include "Pairs.h" -#include "PairsGlobal.h" +#include "PairsButton.h" #include "PairsView.h" -#include "PairsTopButton.h" #undef B_TRANSLATION_CONTEXT @@ -36,8 +34,11 @@ const uint32 MENU_NEW = 'MGnw'; -const uint32 MENU_SIZE = 'MGsz'; +const uint32 MENU_DIFFICULTY = 'MGdf'; const uint32 MENU_QUIT = 'MGqu'; +const uint32 MENU_ICON_SIZE = 'MSIs'; + +const uint32 kMsgPairComparing = 'pcom'; // #pragma mark - PairsWindow @@ -45,18 +46,19 @@ const uint32 MENU_QUIT = 'MGqu'; PairsWindow::PairsWindow() : - BWindow(BRect(100, 100, 405, 423), B_TRANSLATE_SYSTEM_NAME("Pairs"), + BWindow(BRect(0, 0, 0, 0), B_TRANSLATE_SYSTEM_NAME("Pairs"), B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE - | B_NOT_RESIZABLE | B_NOT_ZOOMABLE), + | B_NOT_RESIZABLE | B_NOT_ZOOMABLE), fPairComparing(NULL), fIsFirstClick(true), fIsPairsActive(true), - fPairCard(0), - fPairCardTmp(0), - fButtonTmp(0), - fButton(0), + fPairCardPosition(0), + fPairCardTmpPosition(0), + fButtonTmpPosition(0), + fButtonPosition(0), fButtonClicks(0), - fFinishPairs(0) + fFinishPairs(0), + fIconSizeMenu(NULL) { _MakeMenuBar(); _MakeGameView(4, 4); @@ -77,56 +79,94 @@ PairsWindow::_MakeMenuBar() fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar"); AddChild(fMenuBar); - BMenu* menu = new BMenu(B_TRANSLATE("Game")); - fMenuBar->AddItem(menu); + BMenu* gameMenu = new BMenu(B_TRANSLATE("Game")); + fMenuBar->AddItem(gameMenu); BMenuItem* menuItem; - menu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("New"), - new BMessage(MENU_NEW), 'N')); - menu->AddSeparatorItem(); + BMenu* newMenu = new BMenu(B_TRANSLATE("New")); + newMenu->SetRadioMode(true); - BMenu* sizeMenu = new BMenu(B_TRANSLATE("Size")); - sizeMenu->SetRadioMode(true); - - BMessage* sizeMessage = new BMessage(MENU_SIZE); - sizeMessage->AddInt32("width", 4); - sizeMessage->AddInt32("height", 4); - sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Beginner (4x4)"), - sizeMessage)); + BMessage* difficultyMessage = new BMessage(MENU_DIFFICULTY); + difficultyMessage->AddInt32("rows", 4); + difficultyMessage->AddInt32("cols", 4); + newMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Beginner (4x4)"), + difficultyMessage)); menuItem->SetMarked(true); - sizeMessage = new BMessage(MENU_SIZE); - sizeMessage->AddInt32("width", 6); - sizeMessage->AddInt32("height", 6); - sizeMenu->AddItem(menuItem = new BMenuItem( - B_TRANSLATE("Intermediate (6x6)"), sizeMessage)); + difficultyMessage = new BMessage(MENU_DIFFICULTY); + difficultyMessage->AddInt32("rows", 6); + difficultyMessage->AddInt32("cols", 6); + newMenu->AddItem(menuItem = new BMenuItem( + B_TRANSLATE("Intermediate (6x6)"), difficultyMessage)); - sizeMessage = new BMessage(MENU_SIZE); - sizeMessage->AddInt32("width", 8); - sizeMessage->AddInt32("height", 8); - sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Expert (8x8)"), - sizeMessage)); + difficultyMessage = new BMessage(MENU_DIFFICULTY); + difficultyMessage->AddInt32("rows", 8); + difficultyMessage->AddInt32("cols", 8); + newMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Expert (8x8)"), + difficultyMessage)); - menu->AddItem(sizeMenu); + menuItem = new BMenuItem(newMenu, new BMessage(MENU_NEW)); + menuItem->SetShortcut('N', B_COMMAND_KEY); + gameMenu->AddItem(menuItem); - menu->AddSeparatorItem(); + gameMenu->AddSeparatorItem(); - menu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Quit"), + gameMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Quit"), new BMessage(MENU_QUIT), 'Q')); + + fIconSizeMenu = new BMenu(B_TRANSLATE("Size")); + fIconSizeMenu->SetRadioMode(true); + fMenuBar->AddItem(fIconSizeMenu); + + BMessage* iconSizeMessage = new BMessage(MENU_ICON_SIZE); + iconSizeMessage->AddInt32("size", kSmallIconSize); + fIconSizeMenu->AddItem(menuItem = new BMenuItem( + B_TRANSLATE("Small"), iconSizeMessage), 0); + + iconSizeMessage = new BMessage(MENU_ICON_SIZE); + iconSizeMessage->AddInt32("size", kMediumIconSize); + fIconSizeMenu->AddItem(menuItem = new BMenuItem( + B_TRANSLATE("Medium"), iconSizeMessage), 1); + menuItem->SetMarked(true); + + iconSizeMessage = new BMessage(MENU_ICON_SIZE); + iconSizeMessage->AddInt32("size", kLargeIconSize); + fIconSizeMenu->AddItem(menuItem = new BMenuItem( + B_TRANSLATE("Large"), iconSizeMessage), 2); } void -PairsWindow::_MakeGameView(int width, int height) +PairsWindow::_MakeGameView(uint8 rows, uint8 cols) { BRect viewBounds = Bounds(); viewBounds.top = fMenuBar->Bounds().Height() + 1; - fPairsView = new PairsView(viewBounds, "PairsView", width, height, - B_FOLLOW_NONE); - fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + uint8 iconSize; + BMenuItem* marked = fIconSizeMenu->FindMarked(); + if (marked != NULL) { + switch (fIconSizeMenu->IndexOf(marked)) { + case 0: + iconSize = kSmallIconSize; + break; + + case 2: + iconSize = kLargeIconSize; + break; + + case 1: + default: + iconSize = kMediumIconSize; + } + } else { + iconSize = kMediumIconSize; + fIconSizeMenu->ItemAt(1)->SetMarked(true); + } + + fPairsView = new PairsView(viewBounds, "PairsView", rows, cols, iconSize); AddChild(fPairsView); + _ResizeWindow(rows, cols); } @@ -140,14 +180,12 @@ PairsWindow::NewGame() void -PairsWindow::SetGameSize(int width, int height) +PairsWindow::SetGameSize(uint8 rows, uint8 cols) { - ResizeTo((kBitmapSize + kSpaceSize) * width + kSpaceSize, - (kBitmapSize + kSpaceSize) * height + kSpaceSize - + fMenuBar->Bounds().Height()); RemoveChild(fPairsView); delete fPairsView; - _MakeGameView(width, height); + + _MakeGameView(rows, cols); NewGame(); } @@ -160,112 +198,153 @@ PairsWindow::MessageReceived(BMessage* message) NewGame(); break; - case MENU_SIZE: + case MENU_DIFFICULTY: { - int32 width; - int32 height; - if (message->FindInt32("width", &width) == B_OK - && message->FindInt32("height", &height) == B_OK) { - SetGameSize(width, height); + int32 rows; + int32 cols; + if (message->FindInt32("rows", &rows) == B_OK + && message->FindInt32("cols", &cols) == B_OK) { + SetGameSize(rows, cols); } break; } + case MENU_ICON_SIZE: + { + int32 size; + if (message->FindInt32("size", &size) == B_OK) { + fPairsView->SetIconSize(size); + _ResizeWindow(fPairsView->Rows(), fPairsView->Cols()); + } + + break; + } + case MENU_QUIT: be_app->PostMessage(B_QUIT_REQUESTED); break; case kMsgCardButton: - if (fIsPairsActive) { - fButtonClicks++; + { + if (!fIsPairsActive) + break; - int32 num; - if (message->FindInt32("ButtonNum", &num) < B_OK) - break; + int32 buttonNumber; + if (message->FindInt32("button number", &buttonNumber) != B_OK) + break; - // look what Icon is behind a button - for (int h = 0; h < fPairsView->fNumOfCards; h++) { - if (fPairsView->GetIconFromPos(h) == num) { - fPairCard = (h % fPairsView->fNumOfCards / 2); - fButton = fPairsView->GetIconFromPos(h); - break; - } - } + BObjectList<PairsButton>* pairsButtonList + = fPairsView->PairsButtonList(); + if (pairsButtonList == NULL) + break; - // gameplay - ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Hide(); - - if (fIsFirstClick) { - fPairCardTmp = fPairCard; - fButtonTmp = fButton; - } else { - delete fPairComparing; - // message of message runner might not have arrived - // yet, so it is deleted here to prevent any leaking - // just in case - BMessage message(kMsgPairComparing); - fPairComparing = new BMessageRunner(BMessenger(this), - &message, 5 * 100000L, 1); - fIsPairsActive = false; + // look at what icon is behind a button + int32 buttonCount = pairsButtonList->CountItems(); + for (int32 i = 0; i < buttonCount; i++) { + int32 iconPosition = fPairsView->GetIconPosition(i); + if (iconPosition == buttonNumber) { + fPairCardPosition = i % (buttonCount / 2); + fButtonPosition = iconPosition; + break; } + } + + // gameplay + fButtonClicks++; + pairsButtonList->ItemAt(fButtonPosition)->Hide(); - fIsFirstClick = !fIsFirstClick; + if (fIsFirstClick) { + fPairCardTmpPosition = fPairCardPosition; + fButtonTmpPosition = fButtonPosition; + } else { + delete fPairComparing; + // message of message runner might not have arrived + // yet, so it is deleted here to prevent any leaking + // just in case + BMessage message(kMsgPairComparing); + fPairComparing = new BMessageRunner(BMessenger(this), + &message, 5 * 100000L, 1); + fIsPairsActive = false; } + + fIsFirstClick = !fIsFirstClick; break; + } - case kMsgPairComparing: - delete fPairComparing; - fPairComparing = NULL; + case kMsgPairComparing: + { + BObjectList<PairsButton>* pairsButtonList + = fPairsView->PairsButtonList(); + if (pairsButtonList == NULL) + break; - fIsPairsActive = true; + delete fPairComparing; + fPairComparing = NULL; - if (fPairCard == fPairCardTmp) - fFinishPairs++; - else { - ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Show(); - ((TopButton*)fPairsView->fDeckCard.ItemAt(fButtonTmp))->Show(); - } + fIsPairsActive = true; - // game end and results - if (fFinishPairs == fPairsView->fNumOfCards / 2) { - BString score; - score << fButtonClicks; - BString strAbout = B_TRANSLATE("%app%\n" - "\twritten by Ralf Schülke\n" - "\tCopyright 2008-2010, Haiku Inc.\n" - "\n" - "You completed the game in %num% clicks.\n"); - - strAbout.ReplaceFirst("%app%", - B_TRANSLATE_SYSTEM_NAME("Pairs")); - strAbout.ReplaceFirst("%num%", score); - - BAlert* alert = new BAlert("about", - strAbout.String(), - B_TRANSLATE("New game"), - B_TRANSLATE("Quit game")); - - BTextView* view = alert->TextView(); - BFont font; - - view->SetStylable(true); - - view->GetFont(&font); - font.SetSize(18); - font.SetFace(B_BOLD_FACE); - view->SetFontAndColor(0, - strlen(B_TRANSLATE_SYSTEM_NAME("Pairs")), &font); - view->ResizeToPreferred(); - alert->SetShortcut(0, B_ESCAPE); - - if (alert->Go() == 0) - NewGame(); - else - be_app->PostMessage(B_QUIT_REQUESTED); - } - break; + if (fPairCardPosition == fPairCardTmpPosition) + fFinishPairs++; + else { + pairsButtonList->ItemAt(fButtonPosition)->Show(); + pairsButtonList->ItemAt(fButtonTmpPosition)->Show(); + } + + // game end and results + if (fFinishPairs == pairsButtonList->CountItems() / 2) { + BString score; + score << fButtonClicks; + BString strAbout = B_TRANSLATE("%app%\n" + "\twritten by Ralf Schülke\n" + "\tCopyright 2008-2010, Haiku Inc.\n" + "\n" + "You completed the game in %num% clicks.\n"); + + strAbout.ReplaceFirst("%app%", + B_TRANSLATE_SYSTEM_NAME("Pairs")); + strAbout.ReplaceFirst("%num%", score); + + BAlert* alert = new BAlert("about", + strAbout.String(), + B_TRANSLATE("New game"), + B_TRANSLATE("Quit game")); + + BTextView* view = alert->TextView(); + BFont font; + + view->SetStylable(true); + + view->GetFont(&font); + font.SetSize(18); + font.SetFace(B_BOLD_FACE); + view->SetFontAndColor(0, + strlen(B_TRANSLATE_SYSTEM_NAME("Pairs")), &font); + view->ResizeToPreferred(); + alert->SetShortcut(0, B_ESCAPE); + + if (alert->Go() == 0) + NewGame(); + else + be_app->PostMessage(B_QUIT_REQUESTED); + } + break; + } default: BWindow::MessageReceived(message); } } + + +// #pragma mark - PairsWindow private methods + + +void +PairsWindow::_ResizeWindow(uint8 rows, uint8 cols) +{ + int32 iconSize = fPairsView->IconSize(); + int32 spacing = fPairsView->Spacing(); + + ResizeTo((iconSize + spacing) * rows + spacing, + (iconSize + spacing) * cols + spacing + fMenuBar->Bounds().Height()); +} diff --git a/src/apps/pairs/PairsWindow.h b/src/apps/pairs/PairsWindow.h index 633e0dc..a063d7c 100644 --- a/src/apps/pairs/PairsWindow.h +++ b/src/apps/pairs/PairsWindow.h @@ -15,8 +15,9 @@ #include <Window.h> -class PairsView; +class BMenu; class BMessageRunner; +class PairsView; class PairsWindow : public BWindow { @@ -27,11 +28,12 @@ public: virtual void MessageReceived(BMessage* message); void NewGame(); - void SetGameSize(int width, int height); + void SetGameSize(uint8 rows, uint8 cols); private: - void _MakeGameView(int width, int height); + void _MakeGameView(uint8 rows, uint8 cols); void _MakeMenuBar(); + void _ResizeWindow(uint8 rows, uint8 cols); BView* fBackgroundView; PairsView* fPairsView; @@ -39,12 +41,13 @@ private: BMessageRunner* fPairComparing; bool fIsFirstClick; bool fIsPairsActive; - int fPairCard; - int fPairCardTmp; - int fButtonTmp; - int fButton; - int fButtonClicks; - int fFinishPairs; + int32 fPairCardPosition; + int32 fPairCardTmpPosition; + int32 fButtonTmpPosition; + int32 fButtonPosition; + int32 fButtonClicks; + int32 fFinishPairs; + BMenu* fIconSizeMenu; }; #endif // PAIRS_WINDOW_H