+void Text::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/)
+{
+ if (text.length() > 0)
+// DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY, false, "%s", text.c_str());
+ DrawStringOpaque(screenBuffer, extents.x + offsetX, extents.y + offsetY, fgColor, bgColor, "%s", text.c_str());
+}
+
+
+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:
+ bool thumbClicked;
+ uint32 windowPtr, cursor, limit;
+ uint32 charWidth, charHeight; // Box width/height in characters
+ Element * elementToTell;
+ Button upArrow, downArrow, upArrow2;
+ vector<string> item;
+
+ private:
+ uint32 yRelativePoint;
+};
+
+ListBox::ListBox(uint32 x, uint32 y, uint32 w, uint32 h): Element(x, y, w, h),
+ thumbClicked(false), windowPtr(0), cursor(0), limit(0), charWidth((w / FONT_WIDTH) - 1),
+ charHeight(h / FONT_HEIGHT), 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;
+ }
+ }
+ 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);
+
+ if (thumbClicked)
+ {
+ uint32 sbHeight = extents.h - 24,
+ thumb = (uint32)(((float)limit / (float)item.size()) * (float)sbHeight);
+
+//yRelativePoint is the spot on the thumb where we clicked...
+ int32 newThumbStart = y - yRelativePoint;
+
+ if (newThumbStart < 0)
+ newThumbStart = 0;
+
+ if ((uint32)newThumbStart > sbHeight - thumb)
+ newThumbStart = sbHeight - thumb;
+
+ windowPtr = (uint32)(((float)newThumbStart / (float)sbHeight) * (float)item.size());
+//Check for cursor bounds as well... Or do we need to???
+//Actually, we don't...!
+ }
+}
+
+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... !!! FIX !!!
+// cursor = (y - extents.y) / 8;
+ cursor = (y - extents.y) / FONT_HEIGHT;
+ }
+
+ // Check for a hit on the scrollbar...
+ if (x > (uint32)(extents.x + extents.w) && x <= (uint32)(extents.x + extents.w + 8)
+ && y > (uint32)(extents.y + 8) && y <= (uint32)(extents.y + extents.h - 16))
+ {
+ if (mouseDown)
+ {
+// This shiaut should be calculated in AddItem(), not here... (or in Draw() for that matter)
+ uint32 sbHeight = extents.h - 24,
+ thumb = (uint32)(((float)limit / (float)item.size()) * (float)sbHeight),
+ thumbStart = (uint32)(((float)windowPtr / (float)item.size()) * (float)sbHeight);
+
+ // Did we hit the thumb?
+ if (y >= (extents.y + 8 + thumbStart) && y < (extents.y + 8 + thumbStart + thumb))
+ thumbClicked = true, yRelativePoint = y - thumbStart;
+ }
+//Seems that this is useless--never reached except in rare cases and that the code outside is
+//more effective...
+// else
+// thumbClicked = false;
+ }
+
+ if (!mouseDown)
+ thumbClicked = false;
+
+ 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,
+ DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY + i*FONT_HEIGHT,
+ (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)] = (thumbClicked ? 0x458E : 0xFFFF);
+//458E -> 01 0001 0 1100 0 1110 -> 0100 0101 0110 0011 0111 0011 -> 45 63 73
+ screenBuffer[x + (y * pitch)] = (thumbClicked ? 0xFF736345 : 0xFFFFFFFF);
+ else
+// screenBuffer[x + (y * pitch)] = 0x0200;
+//0200 -> 000000 10000 00000 -> 00 1000 0100 00
+ screenBuffer[x + (y * pitch)] = 0xFF008400;
+ }
+ }
+}
+
+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)
+{
+ // Do a simple insertion sort
+ bool inserted = false;
+
+ for(vector<string>::iterator i=item.begin(); i<item.end(); i++)
+ {
+ if (stringCmpi(s, *i) == -1)
+ {
+ item.insert(i, s);
+ inserted = true;
+ break;
+ }
+ }
+
+ if (!inserted)
+ item.push_back(s);
+
+ limit = (item.size() > charHeight ? charHeight : item.size());
+}
+
+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);
+
+//!!! FIX !!! Directory might not exist--this shouldn't cause VJ to crash!
+ DIR * dp = opendir(vjs.ROMPath);
+ dirent * de;
+
+ if (dp != NULL)
+ {
+ while ((de = readdir(dp)) != NULL)
+ {
+ char * ext = strrchr(de->d_name, '.');
+
+ if (ext != NULL)
+ if (strcasecmp(ext, ".zip") == 0 || strcasecmp(ext, ".j64") == 0
+ || strcasecmp(ext, ".abs") == 0 || strcasecmp(ext, ".jag") == 0
+ || strcasecmp(ext, ".rom") == 0)
+ files->AddItem(string(de->d_name));
+ }
+
+ closedir(dp);
+ }
+ else
+ {
+//Give a diagnostic message here so that the (l)user can figure out what went wrong. !!! FIX !!!
+ }
+}
+
+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);
+// JaguarLoadCart(jaguar_mainRom, filename);
+ if (JaguarLoadFile(filename))
+ {
+ 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
+ {
+ SDL_Event event;
+ event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE;
+ SDL_PushEvent(&event);
+
+ // Handle the error, but don't run...
+ // Tell the user that we couldn't run their file for some reason... !!! FIX !!!
+//how to kludge: Make a function like ResetJaguar which creates the dialog window
+ }
+ }
+ else
+ Window::Notify(e);