2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
3 * Copyright 2010 Adam Smith <adamd.smith@utoronto.ca>
4 * Copyright 2014 Haiku, Inc. All rights reserved.
6 * Distributed under the terms of the MIT License.
9 * Ralf Schülke, ralf.schuelke@googlemail.com
10 * John Scipione, jscipione@gmail.com
11 * Adam Smith, adamd.smith@utoronto.ca
15 #include "PairsView.h"
18 // for srand() and rand()
20 #include <Application.h>
23 #include <ControlLook.h>
25 #include <IconUtils.h>
26 #include <InterfaceDefs.h>
30 #include "PairsButton.h"
33 #undef B_TRANSLATION_CONTEXT
34 #define B_TRANSLATION_CONTEXT "PairsView"
37 // #pragma mark - PairsView
40 PairsView::PairsView(BRect frame
, const char* name
, uint8 rows
, uint8 cols
,
43 BView(frame
, name
, B_FOLLOW_ALL_SIDES
, B_WILL_DRAW
| B_FRAME_EVENTS
),
47 fButtonsCount(rows
* cols
),
48 fCardsCount(fButtonsCount
/ 2),
49 fPairsButtonList(new BObjectList
<PairsButton
>(fButtonsCount
)),
50 fSmallBitmapsList(new BObjectList
<BBitmap
>(fCardsCount
)),
51 fMediumBitmapsList(new BObjectList
<BBitmap
>(fCardsCount
)),
52 fLargeBitmapsList(new BObjectList
<BBitmap
>(fCardsCount
)),
53 fRandomPosition(new int32
[fButtonsCount
]),
54 fPositionX(new int32
[fButtonsCount
]),
55 fPositionY(new int32
[fButtonsCount
])
57 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
64 PairsView::CreateGameBoard()
66 // Show hidden buttons
67 int32 childrenCount
= CountChildren();
68 for (int32 i
= 0; i
< childrenCount
; i
++) {
69 BView
* child
= ChildAt(i
);
70 if (child
->IsHidden())
73 _GenerateCardPositions();
77 PairsView::~PairsView()
79 delete fSmallBitmapsList
;
80 delete fMediumBitmapsList
;
81 delete fLargeBitmapsList
;
82 delete fPairsButtonList
;
83 delete[] fRandomPosition
;
90 PairsView::AttachedToWindow()
92 for (int32 i
= 0; i
< fButtonsCount
; i
++) {
93 PairsButton
* button
= fPairsButtonList
->ItemAt(i
);
95 button
->SetTarget(Window());
99 BView::AttachedToWindow();
104 PairsView::Draw(BRect updateRect
)
106 BObjectList
<BBitmap
>* bitmapsList
;
109 bitmapsList
= fSmallBitmapsList
;
113 bitmapsList
= fLargeBitmapsList
;
116 case kMediumIconSize
:
118 bitmapsList
= fMediumBitmapsList
;
121 for (int32 i
= 0; i
< fButtonsCount
; i
++) {
122 SetDrawingMode(B_OP_ALPHA
);
123 DrawBitmap(bitmapsList
->ItemAt(i
% (fButtonsCount
/ 2)),
124 BPoint(fPositionX
[i
], fPositionY
[i
]));
125 SetDrawingMode(B_OP_COPY
);
131 PairsView::FrameResized(float newWidth
, float newHeight
)
133 int32 spacing
= Spacing();
134 for (int32 i
= 0; i
< fButtonsCount
; i
++) {
135 PairsButton
* button
= fPairsButtonList
->ItemAt(i
);
136 if (button
!= NULL
) {
137 button
->ResizeTo(fIconSize
, fIconSize
);
138 int32 x
= i
% fRows
* (fIconSize
+ spacing
) + spacing
;
139 int32 y
= i
/ fCols
* (fIconSize
+ spacing
) + spacing
;
140 button
->MoveTo(x
, y
);
141 button
->SetFontSize(fIconSize
- 15);
146 Invalidate(BRect(0, 0, newWidth
, newHeight
));
147 BView::FrameResized(newWidth
, newHeight
);
152 PairsView::GetIconPosition(int32 index
)
154 return fRandomPosition
[index
];
158 // #pragma mark - PairsView private methods
162 PairsView::_GenerateCardPositions()
164 // seed the random number generator based on the current timestamp
165 srand((unsigned)time(0));
169 int32
* positions
= new int32
[fButtonsCount
];
170 for (int32 i
= 0; i
< fButtonsCount
; i
++)
173 for (int32 i
= fButtonsCount
; i
> 0; i
--) {
174 int32 index
= rand() % i
;
175 fRandomPosition
[fButtonsCount
- i
] = positions
[index
];
176 for (int32 j
= index
; j
< i
- 1; j
++)
177 positions
[j
] = positions
[j
+ 1];
186 PairsView::_ReadRandomIcons()
188 Pairs
* app
= dynamic_cast<Pairs
*>(be_app
);
189 if (app
== NULL
) // check if NULL to make Coverity happy
192 // Create a copy of the icon map so we can erase elements from it as we
193 // add them to the list eliminating repeated icons without altering the
195 IconMap
tmpIconMap(app
->GetIconMap());
196 size_t mapSize
= tmpIconMap
.size();
197 if (mapSize
< (size_t)fCardsCount
) {
198 // not enough icons, we're screwed
202 // clean out any previous icons
203 fSmallBitmapsList
->MakeEmpty();
204 fMediumBitmapsList
->MakeEmpty();
205 fLargeBitmapsList
->MakeEmpty();
207 // pick bitmaps at random from the icon map
208 for (int32 i
= 0; i
< fCardsCount
; i
++) {
209 IconMap::iterator iter
= tmpIconMap
.begin();
210 if (mapSize
< (size_t)fCardsCount
) {
211 // not enough valid icons, we're really screwed
214 std::advance(iter
, rand() % mapSize
);
215 size_t key
= iter
->first
;
216 vector_icon
* icon
= iter
->second
;
218 BBitmap
* smallBitmap
= new BBitmap(
219 BRect(0, 0, kSmallIconSize
- 1, kSmallIconSize
- 1), B_RGBA32
);
220 status_t smallResult
= BIconUtils::GetVectorIcon(icon
->data
,
221 icon
->size
, smallBitmap
);
222 BBitmap
* mediumBitmap
= new BBitmap(
223 BRect(0, 0, kMediumIconSize
- 1, kMediumIconSize
- 1), B_RGBA32
);
224 status_t mediumResult
= BIconUtils::GetVectorIcon(icon
->data
,
225 icon
->size
, mediumBitmap
);
226 BBitmap
* largeBitmap
= new BBitmap(
227 BRect(0, 0, kLargeIconSize
- 1, kLargeIconSize
- 1), B_RGBA32
);
228 status_t largeResult
= BIconUtils::GetVectorIcon(icon
->data
,
229 icon
->size
, largeBitmap
);
231 if (smallResult
+ mediumResult
+ largeResult
== B_OK
) {
232 fSmallBitmapsList
->AddItem(smallBitmap
);
233 fMediumBitmapsList
->AddItem(mediumBitmap
);
234 fLargeBitmapsList
->AddItem(largeBitmap
);
242 mapSize
-= tmpIconMap
.erase(key
);
243 // remove the element from the map so we don't read it again
249 PairsView::_SetPairsBoard()
251 int32 spacing
= Spacing();
252 for (int32 i
= 0; i
< fButtonsCount
; i
++) {
253 BMessage
* buttonMessage
= new BMessage(kMsgCardButton
);
254 buttonMessage
->AddInt32("button number", i
);
256 int32 x
= i
% fRows
* (fIconSize
+ spacing
) + spacing
;
257 int32 y
= i
/ fCols
* (fIconSize
+ spacing
) + spacing
;
259 PairsButton
* button
= new PairsButton(x
, y
, fIconSize
, buttonMessage
);
260 fPairsButtonList
->AddItem(button
);
267 PairsView::_SetPositions()
269 int32 spacing
= Spacing();
270 for (int32 i
= 0; i
< fButtonsCount
; i
++) {
271 fPositionX
[i
] = fRandomPosition
[i
] % fRows
* (fIconSize
+ spacing
) + spacing
;
272 fPositionY
[i
] = fRandomPosition
[i
] / fCols
* (fIconSize
+ spacing
) + spacing
;