[haiku-commits] haiku: hrev46772 - src/apps/pairs

  • From: jscipione@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 27 Jan 2014 20:18:22 +0100 (CET)

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


Other related posts:

  • » [haiku-commits] haiku: hrev46772 - src/apps/pairs - jscipione