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