📄 window.cpp
字号:
/*************************************************************************** window.cpp - description ------------------- begin : Thu Aug 28 2003 copyright : (C) 2003 by Gabor Torok email : cctorok@yahoo.com ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include "window.h"#define OPEN_STEPS 10int Window::windowCount = 0;Window *Window::window[MAX_WINDOW];/** *@author Gabor Torok */#define CLOSE_BUTTON_SIZE 10Window *Window::message_dialog = NULL;Label *Window::message_label = NULL;Button *Window::message_button = NULL;Window::Window(SDLHandler *sdlHandler, int x, int y, int w, int h, char *title, GLuint texture, bool hasCloseButton, int type) :Widget(x, y, w, h) { this->sdlHandler = sdlHandler; this->title = title; this->texture = texture; this->visible = false; this->modal = false; this->widgetCount = 0; this->dragging = false; this->dragX = this->dragY = 0; if(hasCloseButton) { this->closeButton = new Button(0, 0, CLOSE_BUTTON_SIZE, TOP_HEIGHT - 6); } else closeButton = NULL; openHeight = 0; this->type = type; setBackgroundTileWidth(TILE_W); setBackgroundTileHeight(TILE_H); // make windows stay on screen this->move(x, y); addWindow(this);}Window::~Window() { delete closeButton; // Delete all widgets, may cause problem if someday we use same widgets for // multiple windows. For now, no problem. for(int i = 0; i < widgetCount ; i++){ if(this->widget[i]) delete this->widget[i]; } removeWindow(this);}void Window::addWindow(Window *win) { if(windowCount < MAX_WINDOW) { win->setZ(50 + windowCount * 10); window[windowCount++] = win; }}void Window::removeWindow(Window *win) { for(int i = 0; i < windowCount; i++) { if(window[i] == win) { for(int t = i; t < windowCount - 1; t++) { window[t] = window[t + 1]; } windowCount--; return; } }}void Window::drawVisibleWindows() { // glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); for(int i = 0; i < windowCount; i++) { if(window[i]->isVisible()) window[i]->drawWidget(NULL); } glEnable(GL_DEPTH_TEST);}Widget *Window::delegateEvent(SDL_Event *event, int x, int y) { // find the topmost window Window *win = NULL; int maxz = 0; for(int i = 0; i < windowCount; i++) { if(window[i]->isVisible()) { if(window[i]->isModal()) { win = window[i]; break; } else if(window[i]->isInside(x, y)) { if(maxz < window[i]->getZ()) { win = window[i]; maxz = win->getZ(); } } } } // find the active widget Widget *widget = NULL; if(win) { widget = win->handleWindowEvent(event, x, y); } // tell the other windows that the mouse is elsewhere for(int i = 0; i < windowCount; i++) { if(window[i] != win) { for(int t = 0; t < window[i]->widgetCount; t++) { window[i]->widget[t]->removeEffects(window[i]); } } } return widget;}Widget *Window::handleWindowEvent(SDL_Event *event, int x, int y) { if(dragging) { handleEvent(NULL, event, x, y); return this; } // handled by a component? bool insideWidget = false; Widget *w = NULL; for(int t = 0; t < widgetCount; t++) { if(this->widget[t]->isVisible()) { if(!insideWidget) insideWidget = this->widget[t]->isInside(x - getX(), y - (getY() + TOP_HEIGHT)); if(this->widget[t]->handleEvent(this, event, x - getX(), y - (getY() + TOP_HEIGHT))) w = this->widget[t]; } } // special handling if(message_button && w == message_button) { message_dialog->setVisible(false); } if(w) return w; // handled by closebutton if(closeButton) { if(!insideWidget) { insideWidget = closeButton->isInside(x - (getX() + (getWidth() - (closeButton->getWidth() + 3))), y - (getY() + 3)); } if(closeButton->handleEvent(this, event, x - (getX() + (getWidth() - (closeButton->getWidth() + 3))), y - (getY() + 3))) { return closeButton; } } if(insideWidget) { return this; } // see if the window wants it if(handleEvent(NULL, event, x, y)) { return this; } // swallow event if in a modal window return(isModal() ? this : NULL);}bool Window::isInside(int x, int y) { return(dragging || Widget::isInside(x, y));}bool Window::handleEvent(Widget *parent, SDL_Event *event, int x, int y) { switch(event->type) { case SDL_MOUSEMOTION: if(dragging) move(x - dragX, y - dragY); break; case SDL_MOUSEBUTTONUP: dragging = false; break; case SDL_MOUSEBUTTONDOWN: toTop(); dragging = isInside(x, y); dragX = x - getX(); dragY = y - getY(); break; } return isInside(x, y);}void Window::addWidget(Widget *widget) { if(widgetCount < MAX_WIDGET){ this->widget[widgetCount++] = widget; // apply the window's color scheme widget->setColor( getColor() ); widget->setBackground( getBackgroundColor() ); widget->setSelectionColor( getSelectionColor() ); widget->setBorderColor( getBorderColor() ); } else{ cerr<<"Gui/Window.cpp : max widget limit reached!" << endl; }}void Window::removeWidget(Widget *widget) { for(int i = 0; i < widgetCount; i++) { if(this->widget[i] == widget) { for(int t = i; t < widgetCount - 1; t++) { this->widget[t] = this->widget[t + 1]; } widgetCount--; return; } }}void Window::drawWidget(Widget *parent) { GLint t = SDL_GetTicks(); //if(openHeight < (h - (TOP_HEIGHT + BOTTOM_HEIGHT)) && (lastTick == 0 || t - lastTick > 15)) { if(openHeight < (h - (TOP_HEIGHT + BOTTOM_HEIGHT))) { lastTick = t; openHeight += ( h / OPEN_STEPS ); // always open in the same number of steps if(openHeight >= (h - (TOP_HEIGHT + BOTTOM_HEIGHT))) openHeight = (h - (TOP_HEIGHT + BOTTOM_HEIGHT)); } GLint topY = ((h - (TOP_HEIGHT + BOTTOM_HEIGHT)) / 2) - (openHeight / 2); glPushMatrix(); glLoadIdentity( ); glEnable( GL_TEXTURE_2D ); // tile the background glColor3f(1.0f, 0.6f, 0.3f); glTranslated(x, y, z); if(texture) glBindTexture( GL_TEXTURE_2D, texture ); if(type == BASIC_WINDOW) { glBegin (GL_QUADS); glTexCoord2f (0.0f, 0.0f); glVertex2i (0, topY); glTexCoord2f (0.0f, TOP_HEIGHT/(float)tileHeight); glVertex2i (0, topY + TOP_HEIGHT); glTexCoord2f (w/(float)tileWidth, TOP_HEIGHT/(float)tileHeight); glVertex2i (w, topY + TOP_HEIGHT); glTexCoord2f (w/(float)tileWidth, 0.0f); glVertex2i (w, topY); glEnd (); glBegin (GL_QUADS); glTexCoord2f (0.0f, 0.0f); glVertex2i (0, topY + TOP_HEIGHT + openHeight);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -