/* GL-117 Copyright 2001, 2002 Thomas A. Drexl aka heptargon This file is part of GL-117. GL-117 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. GL-117 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GL-117; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This file includes a very general GUI. */ #ifndef IS_MENU_H #include "menu.h" #include "main.h" int menu_id = 0; int menu_z = -2; CColor menu_colwhite (255, 255, 255, 200); CColor menu_colgrey (220, 220, 220, 200); CColor menu_colyellow (255, 255, 0, 200); Component::Component () { menu_id ++; id = menu_id; func = NULL; highlight = false; active = true; visible = true; parent = NULL; colback [0] = 0; colback [1] = 0; colback [2] = 255; colback [3] = 120; } void Component::setBounds (float x, float y, float w, float h) { this->x = x; this->y = y; this->w = w; this->h = h; } void Component::draw () { } void Component::setFunction (void (*func) (Component *, int button)) { this->func = func; } void Component::execFunction (int button) { if (func) func (this, button); } void Component::eventMouse (int x, int y, int button) { } void Component::eventKey (unsigned char key) { } void Component::eventJoystick (int button) { } void Component::eventSpecial (int key) { } void Component::triggerMouse (int id, int button) { } void Component::setActive (bool value) { active = value; } void Component::setVisible (bool value) { visible = value; } void Component::setHighlight (bool value) { highlight = value; } bool Component::isActive () { return active; } bool Component::isVisible () { return visible; } bool Component::isHighlight () { return highlight; } bool Component::contains (int id) { if (id == this->id) return true; return false; } Container::Container () { numcomponents = 0; } void Container::add (Component *component) { component->parent = this; components [numcomponents] = component; numcomponents ++; } void Container::draw () { int i; if (active && visible) { for (i = 0; i < numcomponents; i ++) { components [i]->draw (); } } } int Container::getNumberOfComponents () { return numcomponents; } void Container::eventMouse (int x, int y, int button) { int i, i2; // glutSwapBuffers (); GLuint selectBuff [20 * 4]; GLint hits, viewport [4]; // Select buffer parameters glSelectBuffer (20 * 4, selectBuff); glGetIntegerv (GL_VIEWPORT, viewport); // Enter to selection mode glEnable (GL_DEPTH_TEST); glDisable (GL_LIGHTING); glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); // Set-up pick matrix gluPickMatrix (x, viewport [3] - y, 1, 1, viewport); // Set our perpective transformation matrix gluPerspective (80.0, 1.0, 0.25 * GLOBALSCALE, view * GLOBALSCALE); // gluPerspective (60.0, 1.0, 0.2, 200.0); glMatrixMode (GL_MODELVIEW); // Render all scene and fill selection buffer glRenderMode (GL_SELECT); glInitNames (); glPushName (0); draw (); // Get hits and go back to normal rendering hits = glRenderMode (GL_RENDER); // Get first model in selection buffer stack GLuint *ptr = selectBuff; int mypicks = 0; int pick [100]; if (hits > 0) { int i; for (i = 0; i < hits; i ++) { int names = *ptr; ptr ++; ptr ++; ptr ++; pick [mypicks] = *ptr; mypicks ++; ptr += names; if (mypicks >= 20) break; } } glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); for (i = 0; i < numcomponents; i ++) { components [i]->setHighlight (false); for (i2 = 0; i2 < hits; i2 ++) { if (components [i]->contains (pick [i2])) { components [i]->triggerMouse (pick [i2], button); } } } } void Container::triggerMouse (int id, int button) { int i; for (i = 0; i < numcomponents; i ++) if (components [i]->contains (id)) { components [i]->triggerMouse (id, button); } } void Container::setVisible (bool value) { int i; visible = value; for (i = 0; i < numcomponents; i ++) { components [i]->setVisible (value); } } void Container::setActive (bool value) { int i; active = value; for (i = 0; i < numcomponents; i ++) { components [i]->setActive (value); } } void Container::setHighlight (bool value) { int i; highlight = value; for (i = 0; i < numcomponents; i ++) { components [i]->setHighlight (value); } } bool Container::contains (int id) { int i; bool ret = false; for (i = 0; i < numcomponents; i ++) { ret |= components [i]->contains (id); } return ret; } void Container::eventKey (unsigned char key) { int i; for (i = 0; i < numcomponents; i ++) { components [i]->eventKey (key); } } void Container::eventSpecial (int key) { int i; for (i = 0; i < numcomponents; i ++) { components [i]->eventSpecial (key); } } void Container::eventJoystick (int button) { int i; for (i = 0; i < numcomponents; i ++) { components [i]->eventJoystick (button); } } Label::Label () { } Label::Label (char *text) { strcpy (this->text, text); transparent = false; colback [0] = 140; colback [1] = 140; colback [2] = 140; colback [3] = 180; } void Label::setText (char *text) { strcpy (this->text, text); } void Label::setTransparent (bool transparent) { this->transparent = transparent; } void Label::draw () { if (!visible) return; CColor *col = &menu_colwhite; if (!transparent) { glLoadName (id); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); glColor4ub (colback [0], colback [1], colback [2], colback [3]); glVertex3f (0.1 * x, 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * (y - h), menu_z); glVertex3f (0.1 * x, 0.1 * (y - h), menu_z); glEnd (); glDisable (GL_BLEND); } font1->zoom = 0.1 * (h - 0.1); float yf = (y - h - 0.01) / (h - 0.1); float xf = (x + 0.25) / (h - 0.1); font1->drawText (xf, yf, menu_z, text, col); font1->zoom = 0.1; } void Label::triggerMouse (int id, int button) { } Button::Button () { } Button::Button (char *text) { strcpy (this->text, text); } void Button::draw () { if (!visible) return; CColor *col_active = &menu_colwhite; CColor *col_deactive = &menu_colgrey; CColor *col_highlight = &menu_colyellow; glLoadName (id); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); if (!highlight) glColor4ub (colback [0], colback [1], colback [2], colback [3]); else glColor4ub (255, 255, 0, colback [3]); glVertex3f (0.1 * x, 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * (y - h), menu_z); glVertex3f (0.1 * x, 0.1 * (y - h), menu_z); glEnd (); glDisable (GL_BLEND); font1->zoom = 0.1 * (h - 0.1); float yf = (y - h - 0.01) / (h - 0.1); float xf = (x + 0.25) / (h - 0.1); if (active && !highlight) font1->drawText (xf, yf, menu_z, text, col_active); else if (!active) font1->drawText (xf, yf, menu_z, text, col_deactive); else font1->drawText (xf, yf, menu_z, text, col_highlight); font1->zoom = 0.1; } void Button::triggerMouse (int id, int button) { if (!active) return; highlight = true; if (button) execFunction (button); } TextField::TextField () { } TextField::TextField (char *text, float fontheight) { strcpy (this->text, text); fonth = fontheight; colback [0] = 140; colback [1] = 140; colback [2] = 140; colback [3] = 180; } void TextField::setText (char *text) { strcpy (this->text, text); } void TextField::draw () { if (!visible) return; CColor *col = &menu_colwhite; glLoadName (id); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); glColor4ub (colback [0], colback [1], colback [2], colback [3]); glVertex3f (0.1 * x, 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * (y - h), menu_z); glVertex3f (0.1 * x, 0.1 * (y - h), menu_z); glEnd (); glDisable (GL_BLEND); font1->zoom = 0.1 * (fonth - 0.1); float yf = (y - fonth - 0.1) / (fonth - 0.1); float xf = (x + 0.25) / (fonth - 0.1); font1->drawText (xf, yf, menu_z, text, col); font1->zoom = 0.1; } void TextField::triggerMouse (int id, int button) { } EditKey::EditKey () { key = 'A'; } EditKey::EditKey (char *text) { key = 'A'; strcpy (this->text, text); } void EditKey::setText (char *text) { strcpy (this->text, text); } void EditKey::setKey (int key) { if (key >= 256) { this->special = key - 256; specialActive = true; } else { this->key = key; specialActive = false; } } int EditKey::getKey () { if (specialActive) return special + 256; else return key; } void EditKey::draw () { if (!visible) return; char buf [64]; CColor *col = &menu_colwhite; glLoadName (id); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); if (!highlight) glColor4ub (colback [0], colback [1], colback [2], colback [3]); else glColor4ub (255, 255, 0, colback [3]); glVertex3f (0.1 * x, 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * (y - h), menu_z); glVertex3f (0.1 * x, 0.1 * (y - h), menu_z); glEnd (); glDisable (GL_BLEND); font1->zoom = 0.1 * (h - 0.1); float yf = (y - h - 0.01) / (h - 0.1); float xf = (x + 0.25) / (h - 0.1); font1->drawText (xf, yf, menu_z, text, col); if (specialActive) key2string (special + 256, buf); else key2string (key, buf); font1->drawText (xf + (w - 2) / h, yf, menu_z, buf, col); font1->zoom = 0.1; } void EditKey::triggerMouse (int id, int button) { if (!active) return; highlight = true; } void EditKey::eventKey (unsigned char key) { char buf [256]; if (!active) return; if (highlight) { key2string (key, buf); if (buf [0] != '\0') { this->key = (int) key; specialActive = false; execFunction (key); } } } void EditKey::eventSpecial (int key) { char buf [256]; if (!active) return; if (highlight) { key2string (key + 256, buf); if (buf [0] != '\0') { this->special = key; specialActive = true; execFunction (special + 256); } } } EditJoystick::EditJoystick () { button = 0; } EditJoystick::EditJoystick (char *text) { button = 0; strcpy (this->text, text); } void EditJoystick::setText (char *text) { strcpy (this->text, text); } void EditJoystick::setButton (int button) { this->button = button; } int EditJoystick::getButton () { return button; } void EditJoystick::draw () { if (!visible) return; char buf [64]; CColor *col = &menu_colwhite; glLoadName (id); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); if (!highlight) glColor4ub (colback [0], colback [1], colback [2], colback [3]); else glColor4ub (255, 255, 0, colback [3]); glVertex3f (0.1 * x, 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * (y - h), menu_z); glVertex3f (0.1 * x, 0.1 * (y - h), menu_z); glEnd (); glDisable (GL_BLEND); font1->zoom = 0.1 * (h - 0.1); float yf = (y - h - 0.01) / (h - 0.1); float xf = (x + 0.25) / (h - 0.1); font1->drawText (xf, yf, menu_z, text, col); joystick2string (button, buf); font1->drawText (xf + (w - 2) / h, yf, menu_z, buf, col); font1->zoom = 0.1; } void EditJoystick::triggerMouse (int id, int button) { if (!active) return; highlight = true; } void EditJoystick::eventJoystick (int button) { char buf [256]; if (!active) return; if (highlight) { joystick2string (button, buf); if (buf [0] != '\0') { this->button = (int) button; execFunction (button); } } } EditField::EditField () { memset (text, 0, 64); ptr = 0; #ifndef USE_GLUT timer = SDL_GetTicks (); #else timer = glutGet (GLUT_ELAPSED_TIME); #endif } EditField::EditField (int maxlen) { memset (this->text, 0, 64); ptr = 0; if (maxlen > 62) maxlen = 62; else if (maxlen < 0) maxlen = 0; this->maxlen = maxlen; #ifndef USE_GLUT timer = SDL_GetTicks (); #else timer = glutGet (GLUT_ELAPSED_TIME); #endif } void EditField::setText (char *text) { if (strlen (text) > (unsigned int) maxlen) return; memset (this->text, 0, 64); strcpy (this->text, text); ptr = strlen (this->text); } void EditField::draw () { char str [64]; int akttime; if (!visible) return; CColor *col = &menu_colgrey; strcpy (str, text); if (highlight) { #ifndef USE_GLUT akttime = SDL_GetTicks (); #else akttime = glutGet (GLUT_ELAPSED_TIME); #endif if (((akttime - timer) & 0xff) > 128) { str [ptr] = 'I'; str [ptr + 1] = 0; } } glLoadName (id); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); if (!highlight) glColor4ub (colback [0], colback [1], colback [2], colback [3]); else glColor4ub (255, 255, 0, colback [3]); glVertex3f (0.1 * x, 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * y, menu_z); glVertex3f (0.1 * (x + w), 0.1 * (y - h), menu_z); glVertex3f (0.1 * x, 0.1 * (y - h), menu_z); glEnd (); glDisable (GL_BLEND); font1->zoom = 0.1 * (h - 0.1); float yf = (y - h - 0.01) / (h - 0.1); float xf = (x + 0.25) / (h - 0.1); font1->drawText (xf, yf, menu_z, str, col); font1->zoom = 0.1; } void EditField::triggerMouse (int id, int button) { if (!active) return; highlight = true; } void EditField::eventKey (unsigned char key) { if (!highlight) return; if (ptr >= 62) return; if (key >= 32) { text [ptr] = key; ptr ++; text [ptr] = 0; } else if (key == 8 && ptr > 0) { ptr --; text [ptr] = 0; } } #endif