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.
This commit is contained in:
@@ -2,9 +2,9 @@ SubDir HAIKU_TOP src apps pairs ;
|
|||||||
|
|
||||||
Application Pairs :
|
Application Pairs :
|
||||||
Pairs.cpp
|
Pairs.cpp
|
||||||
PairsWindow.cpp
|
PairsButton.cpp
|
||||||
PairsView.cpp
|
PairsView.cpp
|
||||||
PairsTopButton.cpp
|
PairsWindow.cpp
|
||||||
|
|
||||||
: be localestub $(TARGET_LIBSTDC++)
|
: be localestub $(TARGET_LIBSTDC++)
|
||||||
: Pairs.rdef
|
: Pairs.rdef
|
||||||
@@ -13,6 +13,7 @@ Application Pairs :
|
|||||||
DoCatalogs Pairs :
|
DoCatalogs Pairs :
|
||||||
x-vnd.Haiku-Pairs
|
x-vnd.Haiku-Pairs
|
||||||
:
|
:
|
||||||
|
Pairs.cpp
|
||||||
PairsView.cpp
|
PairsView.cpp
|
||||||
PairsWindow.cpp
|
PairsWindow.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -13,14 +13,22 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Alert.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <MimeType.h>
|
||||||
|
|
||||||
#include "PairsWindow.h"
|
#include "PairsWindow.h"
|
||||||
|
|
||||||
|
|
||||||
|
#undef B_TRANSLATION_CONTEXT
|
||||||
|
#define B_TRANSLATION_CONTEXT "Pairs"
|
||||||
|
|
||||||
|
|
||||||
const char* kSignature = "application/x-vnd.Haiku-Pairs";
|
const char* kSignature = "application/x-vnd.Haiku-Pairs";
|
||||||
|
|
||||||
|
static const size_t kMinIconCount = 64;
|
||||||
|
static const size_t kMaxIconCount = 384;
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Pairs
|
// #pragma mark - Pairs
|
||||||
|
|
||||||
@@ -30,6 +38,7 @@ Pairs::Pairs()
|
|||||||
BApplication(kSignature),
|
BApplication(kSignature),
|
||||||
fWindow(NULL)
|
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
|
// #pragma mark - main
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+19
-1
@@ -11,16 +11,28 @@
|
|||||||
#define PAIRS_H
|
#define PAIRS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Catalog.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern const char* kSignature;
|
extern const char* kSignature;
|
||||||
|
|
||||||
|
|
||||||
|
struct vector_icon {
|
||||||
|
uint8* data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BBitmap;
|
||||||
class BMessage;
|
class BMessage;
|
||||||
class PairsWindow;
|
class PairsWindow;
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::map<size_t, vector_icon*> IconMap;
|
||||||
|
|
||||||
|
|
||||||
class Pairs : public BApplication {
|
class Pairs : public BApplication {
|
||||||
public:
|
public:
|
||||||
Pairs();
|
Pairs();
|
||||||
@@ -29,9 +41,15 @@ public:
|
|||||||
virtual void ReadyToRun();
|
virtual void ReadyToRun();
|
||||||
virtual void RefsReceived(BMessage* message);
|
virtual void RefsReceived(BMessage* message);
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual bool QuitRequested();
|
||||||
|
|
||||||
|
IconMap GetIconMap() const { return fIconMap; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _GetVectorIcons();
|
||||||
|
|
||||||
PairsWindow* fWindow;
|
PairsWindow* fWindow;
|
||||||
|
IconMap fIconMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Ralf Schülke, [email protected].
|
||||||
|
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* John Scipione, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -7,17 +7,19 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
* John Scipione, jscipione@gmail.com
|
* John Scipione, jscipione@gmail.com
|
||||||
*/
|
*/
|
||||||
#ifndef PAIRS_TOP_BUTTON_H
|
#ifndef PAIRS_BUTTON_H
|
||||||
#define PAIRS_TOP_BUTTON_H
|
#define PAIRS_BUTTON_H
|
||||||
|
|
||||||
#include <OS.h>
|
|
||||||
|
|
||||||
class BButton;
|
#include <Button.h>
|
||||||
|
|
||||||
class TopButton : public BButton {
|
|
||||||
|
class PairsButton : public BButton {
|
||||||
public:
|
public:
|
||||||
TopButton(int x, int y, BMessage* message);
|
PairsButton(int32 x, int32 y, int32 size,
|
||||||
virtual ~TopButton();
|
BMessage* message);
|
||||||
|
virtual ~PairsButton();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PAIRS_TOP_BUTTON_H
|
|
||||||
|
#endif // PAIRS_BUTTON_H
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2008 Ralf Schülke, [email protected].
|
|
||||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* John Scipione, [email protected]
|
|
||||||
*/
|
|
||||||
#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
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2008 Ralf Schülke, [email protected].
|
|
||||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* John Scipione, [email protected]
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
+207
-200
@@ -12,39 +12,44 @@
|
|||||||
|
|
||||||
#include "PairsView.h"
|
#include "PairsView.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <Alert.h>
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
|
#include <ControlLook.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <Directory.h>
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <IconUtils.h>
|
#include <IconUtils.h>
|
||||||
#include <List.h>
|
#include <InterfaceDefs.h>
|
||||||
#include <Node.h>
|
#include <Window.h>
|
||||||
#include <NodeInfo.h>
|
|
||||||
#include <Path.h>
|
|
||||||
|
|
||||||
#include "Pairs.h"
|
#include "Pairs.h"
|
||||||
#include "PairsGlobal.h"
|
#include "PairsButton.h"
|
||||||
#include "PairsTopButton.h"
|
|
||||||
|
|
||||||
PairsView::PairsView(BRect frame, const char* name, int width, int height,
|
|
||||||
uint32 resizingMode)
|
#undef B_TRANSLATION_CONTEXT
|
||||||
|
#define B_TRANSLATION_CONTEXT "PairsView"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - PairsView
|
||||||
|
|
||||||
|
|
||||||
|
PairsView::PairsView(BRect frame, const char* name, uint8 rows, uint8 cols,
|
||||||
|
uint8 iconSize)
|
||||||
:
|
:
|
||||||
BView(frame, name, resizingMode, B_WILL_DRAW),
|
BView(frame, name, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS),
|
||||||
fWidth(width),
|
fRows(rows),
|
||||||
fHeight(height),
|
fCols(cols),
|
||||||
fNumOfCards(width * height),
|
fIconSize(iconSize),
|
||||||
fRandPos(new int[fNumOfCards]),
|
fButtonsCount(rows * cols),
|
||||||
fPosX(new int[fNumOfCards]),
|
fCardsCount(fButtonsCount / 2),
|
||||||
fPosY(new int[fNumOfCards])
|
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();
|
CreateGameBoard();
|
||||||
_SetPairsBoard();
|
_SetPairsBoard();
|
||||||
}
|
}
|
||||||
@@ -54,209 +59,211 @@ void
|
|||||||
PairsView::CreateGameBoard()
|
PairsView::CreateGameBoard()
|
||||||
{
|
{
|
||||||
// Show hidden buttons
|
// Show hidden buttons
|
||||||
for (int32 i = 0; i < CountChildren(); i++) {
|
int32 childrenCount = CountChildren();
|
||||||
|
for (int32 i = 0; i < childrenCount; i++) {
|
||||||
BView* child = ChildAt(i);
|
BView* child = ChildAt(i);
|
||||||
if (child->IsHidden())
|
if (child->IsHidden())
|
||||||
child->Show();
|
child->Show();
|
||||||
}
|
}
|
||||||
_GenerateCardPos();
|
_GenerateCardPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PairsView::~PairsView()
|
PairsView::~PairsView()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fCardBitmaps.CountItems(); i++)
|
delete fSmallBitmapsList;
|
||||||
delete ((BBitmap*)fCardBitmaps.ItemAt(i));
|
delete fMediumBitmapsList;
|
||||||
|
delete fLargeBitmapsList;
|
||||||
for (int i = 0; i < fDeckCard.CountItems(); i++)
|
delete fPairsButtonList;
|
||||||
delete ((TopButton*)fDeckCard.ItemAt(i));
|
delete fRandomPosition;
|
||||||
|
delete fPositionX;
|
||||||
delete fRandPos;
|
delete fPositionY;
|
||||||
delete fPosX;
|
|
||||||
delete fPosY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PairsView::AttachedToWindow()
|
PairsView::AttachedToWindow()
|
||||||
{
|
{
|
||||||
|
for (int32 i = 0; i < fButtonsCount; i++) {
|
||||||
|
PairsButton* button = fPairsButtonList->ItemAt(i);
|
||||||
|
if (button != NULL)
|
||||||
|
button->SetTarget(Window());
|
||||||
|
}
|
||||||
|
|
||||||
MakeFocus(true);
|
MakeFocus(true);
|
||||||
}
|
BView::AttachedToWindow();
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
|
||||||
#define B_TRANSLATION_CONTEXT "PairsView"
|
|
||||||
|
|
||||||
void
|
|
||||||
PairsView::_ReadRandomIcons()
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] data;
|
|
||||||
|
|
||||||
if (_HasBitmap(bitmaps, bitmap) || !bitmaps.AddItem(bitmap))
|
|
||||||
delete bitmap;
|
|
||||||
else if (bitmaps.CountItems() >= 128) {
|
|
||||||
// this is enough to choose from, stop eating memory...
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
fCardBitmaps.AddItem(bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete the remaining bitmaps from the list
|
|
||||||
while (BBitmap* bitmap = (BBitmap*)bitmaps.RemoveItem((int32)0))
|
|
||||||
delete bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PairsView::_SetPairsBoard()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < fNumOfCards; i++) {
|
|
||||||
fButtonMessage = new BMessage(kMsgCardButton);
|
|
||||||
fButtonMessage->AddInt32("ButtonNum", i);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PairsView::_GenerateCardPos()
|
|
||||||
{
|
|
||||||
_ReadRandomIcons();
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
fRandPos[fNumOfCards - i] = positions[index];
|
|
||||||
|
|
||||||
for (int j = index; j < i - 1; j++)
|
|
||||||
positions[j] = positions[j + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < fNumOfCards; i++) {
|
|
||||||
fPosX[i] = (fRandPos[i]) % fWidth * (kBitmapSize + kSpaceSize)
|
|
||||||
+ kSpaceSize;
|
|
||||||
fPosY[i] = (fRandPos[i]) / fHeight * (kBitmapSize + kSpaceSize)
|
|
||||||
+ kSpaceSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] positions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PairsView::Draw(BRect updateRect)
|
PairsView::Draw(BRect updateRect)
|
||||||
{
|
{
|
||||||
SetDrawingMode(B_OP_ALPHA);
|
BObjectList<BBitmap>* bitmapsList;
|
||||||
|
switch (fIconSize) {
|
||||||
|
case kSmallIconSize:
|
||||||
|
bitmapsList = fSmallBitmapsList;
|
||||||
|
break;
|
||||||
|
|
||||||
// draw rand pair 1 & 2
|
case kLargeIconSize:
|
||||||
for (int i = 0; i < fNumOfCards; i++) {
|
bitmapsList = fLargeBitmapsList;
|
||||||
BBitmap* bitmap = ((BBitmap*)fCardBitmaps.ItemAt(i % fNumOfCards / 2));
|
break;
|
||||||
DrawBitmap(bitmap, BPoint(fPosX[i], fPosY[i]));
|
|
||||||
|
case kMediumIconSize:
|
||||||
|
default:
|
||||||
|
bitmapsList = fMediumBitmapsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
PairsView::GetIconFromPos(int pos)
|
PairsView::FrameResized(float newWidth, float newHeight)
|
||||||
{
|
{
|
||||||
return fRandPos[pos];
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_SetPositions();
|
||||||
|
Invalidate(BRect(0, 0, newWidth, newHeight));
|
||||||
|
BView::FrameResized(newWidth, newHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
PairsView::GetIconPosition(int32 index)
|
||||||
|
{
|
||||||
|
return fRandomPosition[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - PairsView private methods
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PairsView::_GenerateCardPositions()
|
||||||
|
{
|
||||||
|
// seed the random number generator based on the current timestamp
|
||||||
|
srand((unsigned)time(0));
|
||||||
|
|
||||||
|
_ReadRandomIcons();
|
||||||
|
|
||||||
|
int32* positions = new int32[fButtonsCount];
|
||||||
|
for (int32 i = 0; i < fButtonsCount; i++)
|
||||||
|
positions[i] = i;
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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::_SetPairsBoard()
|
||||||
|
{
|
||||||
|
int32 spacing = Spacing();
|
||||||
|
for (int32 i = 0; i < fButtonsCount; i++) {
|
||||||
|
BMessage* buttonMessage = new BMessage(kMsgCardButton);
|
||||||
|
buttonMessage->AddInt32("button number", 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PairsView::_SetPositions()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-16
@@ -12,40 +12,63 @@
|
|||||||
#define PAIRS_VIEW_H
|
#define PAIRS_VIEW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <ObjectList.h>
|
||||||
#include <View.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 {
|
class PairsView : public BView {
|
||||||
public:
|
public:
|
||||||
PairsView(BRect frame, const char* name,
|
PairsView(BRect frame, const char* name,
|
||||||
int width, int height,
|
uint8 rows, uint8 cols, uint8 iconSize);
|
||||||
uint32 resizingMode);
|
|
||||||
|
|
||||||
virtual ~PairsView();
|
virtual ~PairsView();
|
||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
virtual void Draw(BRect updateRect);
|
virtual void Draw(BRect updateRect);
|
||||||
|
virtual void FrameResized(float newWidth, float newHeight);
|
||||||
|
|
||||||
virtual void CreateGameBoard();
|
virtual void CreateGameBoard();
|
||||||
|
|
||||||
int fWidth;
|
int32 Rows() const { return fRows; };
|
||||||
int fHeight;
|
int32 Cols() const { return fCols; };
|
||||||
int fNumOfCards;
|
BObjectList<PairsButton>* PairsButtonList() const
|
||||||
|
{ return fPairsButtonList; };
|
||||||
|
|
||||||
BList fDeckCard;
|
int32 GetIconPosition(int32 index);
|
||||||
int GetIconFromPos(int pos);
|
|
||||||
|
int32 IconSize() const { return fIconSize; };
|
||||||
|
void SetIconSize(int32 size) { fIconSize = size; };
|
||||||
|
|
||||||
|
int32 Spacing() const { return fIconSize / 6; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _SetPairsBoard();
|
void _GenerateCardPositions();
|
||||||
void _ReadRandomIcons();
|
void _ReadRandomIcons();
|
||||||
void _GenerateCardPos();
|
void _SetPairsBoard();
|
||||||
bool _HasBitmap(BList& bitmaps, BBitmap* bitmap);
|
void _SetPositions();
|
||||||
|
|
||||||
BMessage* fButtonMessage;
|
uint8 fRows;
|
||||||
BList fCardBitmaps;
|
uint8 fCols;
|
||||||
int* fRandPos;
|
uint8 fIconSize;
|
||||||
int* fPosX;
|
int32 fButtonsCount;
|
||||||
int* fPosY;
|
int32 fCardsCount;
|
||||||
|
BObjectList<PairsButton>* fPairsButtonList;
|
||||||
|
BObjectList<BBitmap>* fSmallBitmapsList;
|
||||||
|
BObjectList<BBitmap>* fMediumBitmapsList;
|
||||||
|
BObjectList<BBitmap>* fLargeBitmapsList;
|
||||||
|
int32* fRandomPosition;
|
||||||
|
int32* fPositionX;
|
||||||
|
int32* fPositionY;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+149
-70
@@ -12,12 +12,11 @@
|
|||||||
|
|
||||||
#include "PairsWindow.h"
|
#include "PairsWindow.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
#include <Menu.h>
|
#include <Menu.h>
|
||||||
#include <MenuBar.h>
|
#include <MenuBar.h>
|
||||||
#include <MenuItem.h>
|
#include <MenuItem.h>
|
||||||
@@ -26,9 +25,8 @@
|
|||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
#include "Pairs.h"
|
#include "Pairs.h"
|
||||||
#include "PairsGlobal.h"
|
#include "PairsButton.h"
|
||||||
#include "PairsView.h"
|
#include "PairsView.h"
|
||||||
#include "PairsTopButton.h"
|
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
#undef B_TRANSLATION_CONTEXT
|
||||||
@@ -36,8 +34,11 @@
|
|||||||
|
|
||||||
|
|
||||||
const uint32 MENU_NEW = 'MGnw';
|
const uint32 MENU_NEW = 'MGnw';
|
||||||
const uint32 MENU_SIZE = 'MGsz';
|
const uint32 MENU_DIFFICULTY = 'MGdf';
|
||||||
const uint32 MENU_QUIT = 'MGqu';
|
const uint32 MENU_QUIT = 'MGqu';
|
||||||
|
const uint32 MENU_ICON_SIZE = 'MSIs';
|
||||||
|
|
||||||
|
const uint32 kMsgPairComparing = 'pcom';
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - PairsWindow
|
// #pragma mark - PairsWindow
|
||||||
@@ -45,18 +46,19 @@ const uint32 MENU_QUIT = 'MGqu';
|
|||||||
|
|
||||||
PairsWindow::PairsWindow()
|
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_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE
|
||||||
| B_NOT_RESIZABLE | B_NOT_ZOOMABLE),
|
| B_NOT_RESIZABLE | B_NOT_ZOOMABLE),
|
||||||
fPairComparing(NULL),
|
fPairComparing(NULL),
|
||||||
fIsFirstClick(true),
|
fIsFirstClick(true),
|
||||||
fIsPairsActive(true),
|
fIsPairsActive(true),
|
||||||
fPairCard(0),
|
fPairCardPosition(0),
|
||||||
fPairCardTmp(0),
|
fPairCardTmpPosition(0),
|
||||||
fButtonTmp(0),
|
fButtonTmpPosition(0),
|
||||||
fButton(0),
|
fButtonPosition(0),
|
||||||
fButtonClicks(0),
|
fButtonClicks(0),
|
||||||
fFinishPairs(0)
|
fFinishPairs(0),
|
||||||
|
fIconSizeMenu(NULL)
|
||||||
{
|
{
|
||||||
_MakeMenuBar();
|
_MakeMenuBar();
|
||||||
_MakeGameView(4, 4);
|
_MakeGameView(4, 4);
|
||||||
@@ -77,56 +79,94 @@ PairsWindow::_MakeMenuBar()
|
|||||||
fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar");
|
fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar");
|
||||||
AddChild(fMenuBar);
|
AddChild(fMenuBar);
|
||||||
|
|
||||||
BMenu* menu = new BMenu(B_TRANSLATE("Game"));
|
BMenu* gameMenu = new BMenu(B_TRANSLATE("Game"));
|
||||||
fMenuBar->AddItem(menu);
|
fMenuBar->AddItem(gameMenu);
|
||||||
|
|
||||||
BMenuItem* menuItem;
|
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"));
|
BMessage* difficultyMessage = new BMessage(MENU_DIFFICULTY);
|
||||||
sizeMenu->SetRadioMode(true);
|
difficultyMessage->AddInt32("rows", 4);
|
||||||
|
difficultyMessage->AddInt32("cols", 4);
|
||||||
BMessage* sizeMessage = new BMessage(MENU_SIZE);
|
newMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Beginner (4x4)"),
|
||||||
sizeMessage->AddInt32("width", 4);
|
difficultyMessage));
|
||||||
sizeMessage->AddInt32("height", 4);
|
|
||||||
sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Beginner (4x4)"),
|
|
||||||
sizeMessage));
|
|
||||||
menuItem->SetMarked(true);
|
menuItem->SetMarked(true);
|
||||||
|
|
||||||
sizeMessage = new BMessage(MENU_SIZE);
|
difficultyMessage = new BMessage(MENU_DIFFICULTY);
|
||||||
sizeMessage->AddInt32("width", 6);
|
difficultyMessage->AddInt32("rows", 6);
|
||||||
sizeMessage->AddInt32("height", 6);
|
difficultyMessage->AddInt32("cols", 6);
|
||||||
sizeMenu->AddItem(menuItem = new BMenuItem(
|
newMenu->AddItem(menuItem = new BMenuItem(
|
||||||
B_TRANSLATE("Intermediate (6x6)"), sizeMessage));
|
B_TRANSLATE("Intermediate (6x6)"), difficultyMessage));
|
||||||
|
|
||||||
sizeMessage = new BMessage(MENU_SIZE);
|
difficultyMessage = new BMessage(MENU_DIFFICULTY);
|
||||||
sizeMessage->AddInt32("width", 8);
|
difficultyMessage->AddInt32("rows", 8);
|
||||||
sizeMessage->AddInt32("height", 8);
|
difficultyMessage->AddInt32("cols", 8);
|
||||||
sizeMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Expert (8x8)"),
|
newMenu->AddItem(menuItem = new BMenuItem(B_TRANSLATE("Expert (8x8)"),
|
||||||
sizeMessage));
|
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'));
|
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
|
void
|
||||||
PairsWindow::_MakeGameView(int width, int height)
|
PairsWindow::_MakeGameView(uint8 rows, uint8 cols)
|
||||||
{
|
{
|
||||||
BRect viewBounds = Bounds();
|
BRect viewBounds = Bounds();
|
||||||
viewBounds.top = fMenuBar->Bounds().Height() + 1;
|
viewBounds.top = fMenuBar->Bounds().Height() + 1;
|
||||||
|
|
||||||
fPairsView = new PairsView(viewBounds, "PairsView", width, height,
|
uint8 iconSize;
|
||||||
B_FOLLOW_NONE);
|
BMenuItem* marked = fIconSizeMenu->FindMarked();
|
||||||
fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
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);
|
AddChild(fPairsView);
|
||||||
|
_ResizeWindow(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,14 +180,12 @@ PairsWindow::NewGame()
|
|||||||
|
|
||||||
|
|
||||||
void
|
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);
|
RemoveChild(fPairsView);
|
||||||
delete fPairsView;
|
delete fPairsView;
|
||||||
_MakeGameView(width, height);
|
|
||||||
|
_MakeGameView(rows, cols);
|
||||||
NewGame();
|
NewGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,44 +198,64 @@ PairsWindow::MessageReceived(BMessage* message)
|
|||||||
NewGame();
|
NewGame();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_SIZE:
|
case MENU_DIFFICULTY:
|
||||||
{
|
{
|
||||||
int32 width;
|
int32 rows;
|
||||||
int32 height;
|
int32 cols;
|
||||||
if (message->FindInt32("width", &width) == B_OK
|
if (message->FindInt32("rows", &rows) == B_OK
|
||||||
&& message->FindInt32("height", &height) == B_OK) {
|
&& message->FindInt32("cols", &cols) == B_OK) {
|
||||||
SetGameSize(width, height);
|
SetGameSize(rows, cols);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case MENU_QUIT:
|
||||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kMsgCardButton:
|
case kMsgCardButton:
|
||||||
if (fIsPairsActive) {
|
{
|
||||||
fButtonClicks++;
|
if (!fIsPairsActive)
|
||||||
|
|
||||||
int32 num;
|
|
||||||
if (message->FindInt32("ButtonNum", &num) < B_OK)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// look what Icon is behind a button
|
int32 buttonNumber;
|
||||||
for (int h = 0; h < fPairsView->fNumOfCards; h++) {
|
if (message->FindInt32("button number", &buttonNumber) != B_OK)
|
||||||
if (fPairsView->GetIconFromPos(h) == num) {
|
break;
|
||||||
fPairCard = (h % fPairsView->fNumOfCards / 2);
|
|
||||||
fButton = fPairsView->GetIconFromPos(h);
|
BObjectList<PairsButton>* pairsButtonList
|
||||||
|
= fPairsView->PairsButtonList();
|
||||||
|
if (pairsButtonList == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// gameplay
|
// gameplay
|
||||||
((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Hide();
|
fButtonClicks++;
|
||||||
|
pairsButtonList->ItemAt(fButtonPosition)->Hide();
|
||||||
|
|
||||||
if (fIsFirstClick) {
|
if (fIsFirstClick) {
|
||||||
fPairCardTmp = fPairCard;
|
fPairCardTmpPosition = fPairCardPosition;
|
||||||
fButtonTmp = fButton;
|
fButtonTmpPosition = fButtonPosition;
|
||||||
} else {
|
} else {
|
||||||
delete fPairComparing;
|
delete fPairComparing;
|
||||||
// message of message runner might not have arrived
|
// message of message runner might not have arrived
|
||||||
@@ -210,24 +268,30 @@ PairsWindow::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fIsFirstClick = !fIsFirstClick;
|
fIsFirstClick = !fIsFirstClick;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kMsgPairComparing:
|
case kMsgPairComparing:
|
||||||
|
{
|
||||||
|
BObjectList<PairsButton>* pairsButtonList
|
||||||
|
= fPairsView->PairsButtonList();
|
||||||
|
if (pairsButtonList == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
delete fPairComparing;
|
delete fPairComparing;
|
||||||
fPairComparing = NULL;
|
fPairComparing = NULL;
|
||||||
|
|
||||||
fIsPairsActive = true;
|
fIsPairsActive = true;
|
||||||
|
|
||||||
if (fPairCard == fPairCardTmp)
|
if (fPairCardPosition == fPairCardTmpPosition)
|
||||||
fFinishPairs++;
|
fFinishPairs++;
|
||||||
else {
|
else {
|
||||||
((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Show();
|
pairsButtonList->ItemAt(fButtonPosition)->Show();
|
||||||
((TopButton*)fPairsView->fDeckCard.ItemAt(fButtonTmp))->Show();
|
pairsButtonList->ItemAt(fButtonTmpPosition)->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// game end and results
|
// game end and results
|
||||||
if (fFinishPairs == fPairsView->fNumOfCards / 2) {
|
if (fFinishPairs == pairsButtonList->CountItems() / 2) {
|
||||||
BString score;
|
BString score;
|
||||||
score << fButtonClicks;
|
score << fButtonClicks;
|
||||||
BString strAbout = B_TRANSLATE("%app%\n"
|
BString strAbout = B_TRANSLATE("%app%\n"
|
||||||
@@ -264,8 +328,23 @@ PairsWindow::MessageReceived(BMessage* message)
|
|||||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(message);
|
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());
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,8 +15,9 @@
|
|||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
|
|
||||||
class PairsView;
|
class BMenu;
|
||||||
class BMessageRunner;
|
class BMessageRunner;
|
||||||
|
class PairsView;
|
||||||
|
|
||||||
|
|
||||||
class PairsWindow : public BWindow {
|
class PairsWindow : public BWindow {
|
||||||
@@ -27,11 +28,12 @@ public:
|
|||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
void NewGame();
|
void NewGame();
|
||||||
void SetGameSize(int width, int height);
|
void SetGameSize(uint8 rows, uint8 cols);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _MakeGameView(int width, int height);
|
void _MakeGameView(uint8 rows, uint8 cols);
|
||||||
void _MakeMenuBar();
|
void _MakeMenuBar();
|
||||||
|
void _ResizeWindow(uint8 rows, uint8 cols);
|
||||||
|
|
||||||
BView* fBackgroundView;
|
BView* fBackgroundView;
|
||||||
PairsView* fPairsView;
|
PairsView* fPairsView;
|
||||||
@@ -39,12 +41,13 @@ private:
|
|||||||
BMessageRunner* fPairComparing;
|
BMessageRunner* fPairComparing;
|
||||||
bool fIsFirstClick;
|
bool fIsFirstClick;
|
||||||
bool fIsPairsActive;
|
bool fIsPairsActive;
|
||||||
int fPairCard;
|
int32 fPairCardPosition;
|
||||||
int fPairCardTmp;
|
int32 fPairCardTmpPosition;
|
||||||
int fButtonTmp;
|
int32 fButtonTmpPosition;
|
||||||
int fButton;
|
int32 fButtonPosition;
|
||||||
int fButtonClicks;
|
int32 fButtonClicks;
|
||||||
int fFinishPairs;
|
int32 fFinishPairs;
|
||||||
|
BMenu* fIconSizeMenu;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PAIRS_WINDOW_H
|
#endif // PAIRS_WINDOW_H
|
||||||
|
|||||||
Reference in New Issue
Block a user