xref: /haiku/src/apps/pairs/PairsView.cpp (revision e221c09e508ffc3c62738140c9b6fc4fa211662a)
1 /*
2  * Copyright 2008, Ralf Schülke, teammaui@web.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #include "PairsView.h"
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #include <Alert.h>
11 #include <Application.h>
12 #include <Bitmap.h>
13 #include <Button.h>
14 #include <Directory.h>
15 #include <Entry.h>
16 #include <FindDirectory.h>
17 #include <IconUtils.h>
18 #include <List.h>
19 #include <Node.h>
20 #include <NodeInfo.h>
21 #include <Path.h>
22 
23 #include "Pairs.h"
24 #include "PairsGlobal.h"
25 #include "PairsTopButton.h"
26 
27 // TODO: support custom board sizes
28 
29 PairsView::PairsView(BRect frame, const char* name, uint32 resizingMode)
30 	: BView(frame, name, resizingMode, B_WILL_DRAW)
31 {
32 	// init bitmap pointers
33 	for (int i = 0; i < 8; i++)
34 		fCard[i] = NULL;
35 
36 	CreateGameBoard();
37 	_SetPairsBoard();
38 }
39 
40 
41 void
42 PairsView::CreateGameBoard()
43 {
44 	// Show hidden buttons
45 	for (int32 i = 0; i < CountChildren(); i++) {
46 		BView* child = ChildAt(i);
47 		if (child->IsHidden())
48 			child->Show();
49 	}
50 	_GenarateCardPos();
51 }
52 
53 
54 PairsView::~PairsView()
55 {
56 	for (int i = 0; i < 8; i++)
57 		delete fCard[i];
58 
59 	for (int i = 0; i < 16; i++)
60 		delete fDeckCard[i];
61 }
62 
63 
64 void
65 PairsView::AttachedToWindow()
66 {
67 	MakeFocus(true);
68 }
69 
70 
71 void
72 PairsView::_ReadRandomIcons()
73 {
74 	// TODO: maybe read the icons only once at startup
75 
76 	// clean out any previous icons
77 	for (int i = 0; i < 8; i++) {
78 		delete fCard[i];
79 		fCard[i] = NULL;
80 	}
81 
82 	BDirectory appsDirectory;
83 	BDirectory prefsDirectory;
84 
85 	BPath path;
86 	if (find_directory(B_BEOS_APPS_DIRECTORY, &path) == B_OK)
87 		appsDirectory.SetTo(path.Path());
88 	if (find_directory(B_BEOS_PREFERENCES_DIRECTORY, &path) == B_OK)
89 		prefsDirectory.SetTo(path.Path());
90 
91 	// read vector icons from apps and prefs folder and put them
92 	// into a BList as BBitmaps
93 	BList bitmaps;
94 
95 	BEntry entry;
96 	while (appsDirectory.GetNextEntry(&entry) == B_OK
97 		|| prefsDirectory.GetNextEntry(&entry) == B_OK) {
98 
99 		BNode node(&entry);
100 		BNodeInfo nodeInfo(&node);
101 
102 		if (nodeInfo.InitCheck() < B_OK)
103 			continue;
104 
105 		uint8* data;
106 		size_t size;
107 		type_code type;
108 
109 		if (nodeInfo.GetIcon(&data, &size, &type) < B_OK)
110 			continue;
111 
112 		if (type != B_VECTOR_ICON_TYPE) {
113 			delete[] data;
114 			continue;
115 		}
116 
117 		BBitmap* bitmap = new BBitmap(
118 			BRect(0, 0, kBitmapSize - 1, kBitmapSize - 1), 0, B_RGBA32);
119 		if (BIconUtils::GetVectorIcon(data, size, bitmap) < B_OK) {
120 			delete[] data;
121 			delete bitmap;
122 			continue;
123 		}
124 
125 		delete[] data;
126 
127 		if (!bitmaps.AddItem(bitmap))
128 			delete bitmap;
129 
130 		if (bitmaps.CountItems() >= 128) {
131 			// this is enough to choose from, stop eating memory...
132 			break;
133 		}
134 	}
135 
136 	// pick eight random bitmaps from the ones we got in the list
137 	srand((unsigned)time(0));
138 
139 	for (int i = 0; i < 8; i++) {
140 		int32 index = rand() % bitmaps.CountItems();
141 		fCard[i] = (BBitmap*)bitmaps.RemoveItem(index);
142 		if (fCard[i] == NULL) {
143 			BAlert* alert = new BAlert("fatal", "Pairs did not find enough "
144 				"vector icons in the system, it needs at least eight.",
145 				"Oh!", NULL, NULL, B_WIDTH_FROM_WIDEST, B_STOP_ALERT);
146 			alert->Go();
147 			exit(1);
148 		}
149 	}
150 
151 	// delete the remaining bitmaps from the list
152 	while (BBitmap* bitmap = (BBitmap*)bitmaps.RemoveItem(0L))
153 		delete bitmap;
154 }
155 
156 
157 void
158 PairsView::_SetPairsBoard()
159 {
160 	for (int i = 0; i < 16; i++) {
161 		fButtonMessage = new BMessage(kMsgCardButton);
162 		fButtonMessage->AddInt32("ButtonNum", i);
163 
164 		int x =  i % 4 * (kBitmapSize + 10) + 10;
165 		int y =  i / 4 * (kBitmapSize + 10) + 10;
166 
167 		fDeckCard[i] = new TopButton(x, y, fButtonMessage);
168 		AddChild(fDeckCard[i]);
169 	}
170 }
171 
172 
173 void
174 PairsView::_GenarateCardPos()
175 {
176 	_ReadRandomIcons();
177 
178 	srand((unsigned)time(0));
179 
180 	int positions[16];
181 	for (int i = 0; i < 16; i++)
182 		positions[i] = i;
183 
184 	for (int i = 16; i >= 1; i--) {
185 		int index = rand() % i;
186 
187 		fRandPos[16-i] = positions[index];
188 
189 		for (int j = index; j < i - 1; j++)
190 			positions[j] = positions[j + 1];
191 	}
192 
193 	for (int i = 0; i < 16; i++) {
194 		fPosX[i] = (fRandPos[i]) % 4 * (kBitmapSize + 10) + 10;
195 		fPosY[i] = (fRandPos[i]) / 4 * (kBitmapSize + 10) + 10;
196 	}
197 }
198 
199 
200 void
201 PairsView::Draw(BRect updateRect)
202 {
203 	SetDrawingMode(B_OP_ALPHA);
204 
205 	// draw rand pair 1 & 2
206 	for (int i = 0; i < 16; i++)
207 		DrawBitmap(fCard[i % 8], BPoint(fPosX[i], fPosY[i]));
208 }
209 
210 
211 int
212 PairsView::GetIconFromPos(int pos)
213 {
214 	return fRandPos[pos];
215 }
216 
217 
218