// // WINDOW.CPP // // Graphical User Interface window class // by James Hammons // // JLH = James Hammons // // WHO WHEN WHAT // --- ---------- ------------------------------------------------------------ // JLH 02/03/2006 Created this file // JLH 02/09/2006 Fixed various problems with the class implementation // JLH 02/14/2006 Added window rendering // #include "window.h" #include "button.h" #include "guimisc.h" // Various support functions #include // Debug support... //#define DESTRUCTOR_TESTING // Rendering experiment... //BAH //#define USE_COVERAGE_LISTS #if SDL_BYTEORDER == SDL_BIG_ENDIAN #define MASK_R 0xFF000000 #define MASK_G 0x00FF0000 #define MASK_B 0x0000FF00 #define MASK_A 0x000000FF #else #define MASK_R 0x000000FF #define MASK_G 0x0000FF00 #define MASK_B 0x00FF0000 #define MASK_A 0xFF000000 #endif // // Window class implementation // // NOTE: FG/BG colors are hard-wired // Window::Window(uint32_t x/*= 0*/, uint32_t y/*= 0*/, uint32_t w/*= 0*/, uint32_t h/*= 0*/, void (* f)(Element *)/*= NULL*/): Element(x, y, w, h, 0x4D, 0xFF, 0x84, 0xFF, 0x1F, 0x84, 0x84, 0xFF), handler(f), cbWidth((closeBox[0] << 8) | closeBox[1]), cbHeight((closeBox[2] << 8) | closeBox[3]), cbUp(SDL_CreateRGBSurfaceFrom(&closeBox[4], cbWidth, cbHeight, 32, cbWidth * 4, MASK_R, MASK_G, MASK_B, MASK_A)), cbDown(SDL_CreateRGBSurfaceFrom(&closeBoxDown[4], cbWidth, cbHeight, 32, cbWidth * 4, MASK_R, MASK_G, MASK_B, MASK_A)), cbHover(SDL_CreateRGBSurfaceFrom(&closeBoxHover[4], cbWidth, cbHeight, 32, cbWidth * 4, MASK_R, MASK_G, MASK_B, MASK_A)), drawBackground(true) { //Could probably move this into the initializer list as well... // closeButton = new Button(w - (cbWidth + 1), 1, cbUp, cbHover, cbDown, this); // list.push_back(closeButton); CreateBackstore(); Draw(); // Can we do this in the constructor??? Mebbe. } Window::~Window() { #ifdef DESTRUCTOR_TESTING printf("Inside ~Window()...\n"); #endif for(uint32_t i=0; iHandleKey(key); } void Window::HandleMouseMove(uint32_t x, uint32_t y) { // Handle the items this window contains... for(uint32_t i=0; iHandleMouseMove(x - extents.x, y - extents.y); } void Window::HandleMouseButton(uint32_t x, uint32_t y, bool mouseDown) { #if 1 // Handle the items this window contains... for(uint32_t i=0; iHandleMouseButton(x - extents.x, y - extents.y, mouseDown); #else //? This works in draggablewindow2... // Handle the items this window contains... for(uint32_t i=0; iHandleMouseButton(x - extents.x, y - extents.y, mouseDown); if (list[i]->Inside(x - extents.x, y - extents.y)) clicked = false; } #endif } void Window::Draw(void) { #ifdef USE_COVERAGE_LISTS // These are *always* top level and parentless, so no need to traverse up through // the parent chain... for(std::list::iterator i=coverList.begin(); i!=coverList.end(); i++) SDL_FillRect(screen, &(*i), bgColor); // Handle the items this window contains... for(uint32_t i=0; iDraw(); #else if (drawBackground) { // These are *always* top level and parentless, so no need to traverse up through // the parent chain... SDL_FillRect(screen, &extents, bgColor); } else RestoreScreenFromBackstore(); // Handle the items this window contains... for(uint32_t i=0; iDraw(); #endif //Prolly don't need this since the close button will do this for us... //Close button isn't mandatory anymore... needToRefreshScreen = true; } // This is only called if a close button has been added void Window::Notify(Element * e) { if (e == closeButton) { SDL_Event event; event.type = SDL_USEREVENT; event.user.code = WINDOW_CLOSE; event.user.data1 = (void *)this; SDL_PushEvent(&event); } } void Window::AddElement(Element * e) { list.push_back(e); } void Window::AddCloseButton(void) { // Only allow this to happen once! if (closeButton == NULL) { closeButton = new Button(extents.w - (cbWidth + 1), 1, cbUp, cbHover, cbDown, this); list.push_back(closeButton); } } void Window::SetBackgroundDraw(bool state) { drawBackground = state; }