+class ListBox: public Element
+//class ListBox: public Window
+{
+ public:
+// ListBox(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h),
+ ListBox(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0);//: Window(x, y, w, h),
+// windowPtr(0), cursor(0), limit(0), charWidth((w / 8) - 1), charHeight(h / 8),
+// elementToTell(NULL), upArrow(w - 8, 0, upArrowBox),
+// downArrow(w - 8, h - 8, downArrowBox), upArrow2(w - 8, h - 16, upArrowBox) {}
+ virtual void HandleKey(SDLKey key);
+ virtual void HandleMouseMove(uint32 x, uint32 y);
+ virtual void HandleMouseButton(uint32 x, uint32 y, bool mouseDown);
+ virtual void Draw(uint32 offsetX = 0, uint32 offsetY = 0);
+ virtual void Notify(Element * e);
+ void SetNotificationElement(Element * e) { elementToTell = e; }
+ void AddItem(string s);
+ string GetSelectedItem(void);
+
+ protected:
+ uint32 windowPtr, cursor, limit;
+ uint32 charWidth, charHeight; // Box width/height in characters
+ Element * elementToTell;
+ Button upArrow, downArrow, upArrow2;
+ vector<string> item;
+};
+
+ListBox::ListBox(uint32 x, uint32 y, uint32 w, uint32 h): Element(x, y, w, h),
+ windowPtr(0), cursor(0), limit(0), charWidth((w / 8) - 1), charHeight(h / 8),
+ elementToTell(NULL), upArrow(w - 8, 0, upArrowBox),
+ downArrow(w - 8, h - 8, downArrowBox), upArrow2(w - 8, h - 16, upArrowBox)
+{
+ upArrow.SetNotificationElement(this);
+ downArrow.SetNotificationElement(this);
+ upArrow2.SetNotificationElement(this);
+ extents.w -= 8; // Make room for scrollbar...
+}
+
+void ListBox::HandleKey(SDLKey key)
+{
+ if (key == SDLK_DOWN)
+ {
+ if (cursor != limit - 1) // Cursor is within its window
+ cursor++;
+ else // Otherwise, scroll the window...
+ {
+ if (cursor + windowPtr != item.size() - 1)
+ windowPtr++;
+ }
+ }
+ else if (key == SDLK_UP)
+ {
+ if (cursor != 0)
+ cursor--;
+ else
+ {
+ if (windowPtr != 0)
+ windowPtr--;
+ }
+ }
+ else if (key == SDLK_PAGEDOWN)
+ {
+ if (cursor != limit - 1)
+ cursor = limit - 1;
+ else
+ {
+ windowPtr += limit;
+ if (windowPtr > item.size() - limit)
+ windowPtr = item.size() - limit;
+ }
+ }
+ else if (key == SDLK_PAGEUP)
+ {
+ if (cursor != 0)
+ cursor = 0;
+ else
+ {
+ if (windowPtr < limit)
+ windowPtr = 0;
+ else
+ windowPtr -= limit;
+ }
+ }
+//How to handle these???
+/* if (key == SDLK_RETURN)
+ done = true;
+ if (key == SDLK_ESCAPE)
+ {
+ WriteLog("GUI: Aborting VJ by user request.\n");
+ return false; // Bail out!
+ }*/
+ else if (key >= SDLK_a && key <= SDLK_z)
+ {
+ // Advance cursor to filename with first letter pressed...
+ uint8 which = (key - SDLK_a) + 65; // Convert key to A-Z char
+
+ for(uint32 i=0; i<item.size(); i++)
+ {
+ if ((item[i][0] & 0xDF) == which)
+ {
+ cursor = i - windowPtr;
+ if (i > windowPtr + limit - 1)
+ windowPtr = i - limit + 1,
+ cursor = limit - 1;
+ if (i < windowPtr)
+ windowPtr = i,
+ cursor = 0;
+ break;
+ }
+ }
+ }
+}
+
+void ListBox::HandleMouseMove(uint32 x, uint32 y)
+{
+ upArrow.HandleMouseMove(x - extents.x, y - extents.y);
+ downArrow.HandleMouseMove(x - extents.x, y - extents.y);
+ upArrow2.HandleMouseMove(x - extents.x, y - extents.y);
+}
+
+void ListBox::HandleMouseButton(uint32 x, uint32 y, bool mouseDown)
+{
+ if (Inside(x, y) && mouseDown)
+ {
+ // Why do we have to do this??? (- extents.y?)
+ // I guess it's because only the Window class has offsetting implemented...
+ cursor = (y - extents.y) / 8;
+ }
+
+ upArrow.HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
+ downArrow.HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
+ upArrow2.HandleMouseButton(x - extents.x, y - extents.y, mouseDown);
+}
+
+void ListBox::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/)
+{
+ for(uint32 i=0; i<limit; i++)
+ {
+ // Strip off the extension
+ // (extension stripping should be an option, not default!)
+ string s(item[windowPtr + i], 0, item[windowPtr + i].length() - 4);
+ DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY + i*8,
+ (cursor == i ? true : false), "%-*.*s", charWidth, charWidth, s.c_str());
+ }
+
+ upArrow.Draw(extents.x + offsetX, extents.y + offsetY);
+ downArrow.Draw(extents.x + offsetX, extents.y + offsetY);
+ upArrow2.Draw(extents.x + offsetX, extents.y + offsetY);
+
+ uint32 sbHeight = extents.h - 24,
+ thumb = (uint32)(((float)limit / (float)item.size()) * (float)sbHeight),
+ thumbStart = (uint32)(((float)windowPtr / (float)item.size()) * (float)sbHeight);
+
+ for(uint32 y=extents.y+offsetY+8; y<extents.y+offsetY+extents.h-16; y++)
+ {
+// for(uint32 x=extents.x+offsetX+extents.w-8; x<extents.x+offsetX+extents.w; x++)
+ for(uint32 x=extents.x+offsetX+extents.w; x<extents.x+offsetX+extents.w+8; x++)
+ {
+ if (y >= thumbStart + (extents.y+offsetY+8) && y < thumbStart + thumb + (extents.y+offsetY+8))
+ screenBuffer[x + (y * pitch)] = 0xFFFF;
+ else
+ screenBuffer[x + (y * pitch)] = 0x0000;
+ }
+ }
+}
+
+void ListBox::Notify(Element * e)
+{
+ if (e == &upArrow || e == &upArrow2)
+ {
+ if (windowPtr != 0)
+ {
+ windowPtr--;
+
+ if (cursor < limit - 1)
+ cursor++;
+ }
+ }
+ else if (e == &downArrow)
+ {
+ if (windowPtr < item.size() - limit)
+ {
+ windowPtr++;
+
+ if (cursor != 0)
+ cursor--;
+ }
+ }
+}
+
+void ListBox::AddItem(string s)
+{
+ item.push_back(s);
+ limit = (item.size() > charHeight ? charHeight : item.size());
+//WriteLog("ListBox: Adding item [%s], limit = %u...\n", s.c_str(), limit);
+
+ //Do this *every* time?
+ sort(item.begin(), item.end());
+}
+
+string ListBox::GetSelectedItem(void)
+{
+ return item[windowPtr + cursor];
+}
+
+class FileList: public Window
+{
+ public:
+ FileList(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0);
+ virtual ~FileList() {}
+ virtual void HandleKey(SDLKey key);
+ virtual void HandleMouseMove(uint32 x, uint32 y) { Window::HandleMouseMove(x, y); }
+ virtual void HandleMouseButton(uint32 x, uint32 y, bool mouseDown) { Window::HandleMouseButton(x, y, mouseDown); }
+ virtual void Draw(uint32 offsetX = 0, uint32 offsetY = 0) { Window::Draw(offsetX, offsetY); }
+ virtual void Notify(Element * e);
+
+ protected:
+ ListBox * files;
+ Button * load;
+};
+
+//Need 4 buttons, one scrollbar...
+FileList::FileList(uint32 x, uint32 y, uint32 w, uint32 h): Window(x, y, w, h)
+{
+ files = new ListBox(8, 8, w - 16, h - 32);
+ AddElement(files);
+ load = new Button(8, h - 16, " Load ");
+ AddElement(load);
+ load->SetNotificationElement(this);
+
+// DIR * dp = opendir(path);
+ DIR * dp = opendir(vjs.ROMPath);
+ dirent * de;
+
+ while ((de = readdir(dp)) != NULL)
+ {
+ char * ext = strrchr(de->d_name, '.');
+
+ if (ext != NULL)
+ if (stricmp(ext, ".zip") == 0 || stricmp(ext, ".jag") == 0)
+ files->AddItem(string(de->d_name));
+ }
+
+ closedir(dp);
+}
+
+void FileList::HandleKey(SDLKey key)
+{
+ if (key == SDLK_RETURN)
+ Notify(load);
+ else
+ Window::HandleKey(key);
+}
+
+void FileList::Notify(Element * e)
+{
+ if (e == load)
+ {
+ char filename[MAX_PATH];
+ strcpy(filename, vjs.ROMPath);
+
+ if (strlen(filename) > 0)
+ if (filename[strlen(filename) - 1] != '/')
+ strcat(filename, "/");
+
+ strcat(filename, files->GetSelectedItem().c_str());
+
+ uint32 romSize = JaguarLoadROM(jaguar_mainRom, filename);
+
+ if (romSize == 0)
+//We need better error checking here... !!! FIX !!!
+ WriteLog("VJ: Could not load ROM from file \"%s\"...", files->GetSelectedItem().c_str());
+ else
+ {
+ jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romSize);
+ WriteLog("CRC: %08X\n", (unsigned int)jaguar_mainRom_crc32);
+ eeprom_init();
+
+ SDL_Event event;
+ event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE;
+ SDL_PushEvent(&event);
+
+ event.type = SDL_USEREVENT, event.user.code = MENU_ITEM_CHOSEN;
+ event.user.data1 = (void *)ResetJaguar;
+ SDL_PushEvent(&event);
+ }
+ }
+ else
+ Window::Notify(e);
+}
+
+