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:
parent
0933046655
commit
97e1b053b6
@ -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
|
||||
;
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
28
src/apps/pairs/PairsButton.cpp
Normal file
28
src/apps/pairs/PairsButton.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#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:
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
#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
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
#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, ralf.schuelke@googlemail.com.
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
|
||||
#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()
|
||||
{
|
||||
}
|
@ -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"
|
||||
|
||||
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),
|
||||
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()
|
||||
{
|
||||
for (int32 i = 0; i < fButtonsCount; i++) {
|
||||
PairsButton* button = fPairsButtonList->ItemAt(i);
|
||||
if (button != NULL)
|
||||
button->SetTarget(Window());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
BView::AttachedToWindow();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PairsView::Draw(BRect updateRect)
|
||||
{
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
BObjectList<BBitmap>* bitmapsList;
|
||||
switch (fIconSize) {
|
||||
case kSmallIconSize:
|
||||
bitmapsList = fSmallBitmapsList;
|
||||
break;
|
||||
|
||||
// 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]));
|
||||
case kLargeIconSize:
|
||||
bitmapsList = fLargeBitmapsList;
|
||||
break;
|
||||
|
||||
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
|
||||
PairsView::GetIconFromPos(int pos)
|
||||
void
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
void _SetPairsBoard();
|
||||
void _SetPositions();
|
||||
|
||||
BMessage* fButtonMessage;
|
||||
BList fCardBitmaps;
|
||||
int* fRandPos;
|
||||
int* fPosX;
|
||||
int* fPosY;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
int32 buttonNumber;
|
||||
if (message->FindInt32("button number", &buttonNumber) != B_OK)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gameplay
|
||||
((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Hide();
|
||||
// gameplay
|
||||
fButtonClicks++;
|
||||
pairsButtonList->ItemAt(fButtonPosition)->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;
|
||||
}
|
||||
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;
|
||||
fIsFirstClick = !fIsFirstClick;
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgPairComparing:
|
||||
{
|
||||
BObjectList<PairsButton>* pairsButtonList
|
||||
= fPairsView->PairsButtonList();
|
||||
if (pairsButtonList == NULL)
|
||||
break;
|
||||
|
||||
delete fPairComparing;
|
||||
fPairComparing = NULL;
|
||||
|
||||
fIsPairsActive = true;
|
||||
|
||||
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;
|
||||
|
||||
case kMsgPairComparing:
|
||||
delete fPairComparing;
|
||||
fPairComparing = NULL;
|
||||
|
||||
fIsPairsActive = true;
|
||||
|
||||
if (fPairCard == fPairCardTmp)
|
||||
fFinishPairs++;
|
||||
else {
|
||||
((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Show();
|
||||
((TopButton*)fPairsView->fDeckCard.ItemAt(fButtonTmp))->Show();
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user