2010-08-29 23:59:24 +02:00
|
|
|
#include "IMGUIControls.h"
|
|
|
|
|
|
|
|
#include "Engine.h"
|
|
|
|
#include "ControllerBase.h"
|
|
|
|
#include "ViewBase.h"
|
|
|
|
#include <GL/gl.h>
|
|
|
|
#include "DrawingsGL.h"
|
|
|
|
#include "keytable.h"
|
|
|
|
|
|
|
|
Engine::ControllerBase *controller = NULL;
|
|
|
|
Engine::ViewBase *view = NULL;
|
|
|
|
|
|
|
|
namespace Engine {
|
|
|
|
namespace GUI {
|
|
|
|
|
|
|
|
/** \brief Checks whether the mouse is in the given rectangle */
|
|
|
|
bool regionhit (int x, int y, int w, int h) {
|
|
|
|
controller = EngineGetController();
|
|
|
|
assert (controller);
|
|
|
|
|
|
|
|
int mouse_pos[2];
|
|
|
|
|
|
|
|
controller->GetMouseScreenPosition(mouse_pos);
|
|
|
|
|
|
|
|
if (mouse_pos[0] < x ||
|
|
|
|
mouse_pos[1] < y ||
|
|
|
|
mouse_pos[0] >= x + w ||
|
|
|
|
mouse_pos[1] >= y + h)
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-10-30 11:39:59 +02:00
|
|
|
void DrawBlock (int x, int y, int w, int h) {
|
|
|
|
const float shading_dark = 0.5;
|
|
|
|
const float shading_light = 1.3;
|
|
|
|
|
2010-11-13 18:45:15 +01:00
|
|
|
float color[4];
|
|
|
|
glGetFloatv (GL_CURRENT_COLOR, color);
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
|
|
|
// middle part
|
|
|
|
glVertex3f (x, y, 0.);
|
|
|
|
glVertex3f (x, y + h, 0.);
|
|
|
|
glVertex3f (x + w, y + h, 0.);
|
|
|
|
glVertex3f (x + w, y, 0.);
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glColor4fv (color);
|
|
|
|
|
|
|
|
// "Shading"
|
|
|
|
glLineWidth(3);
|
|
|
|
glColor3f (color[0] * shading_dark, color[1] * shading_dark, color[2] * shading_dark);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3f (x,y + 2, 0.);
|
|
|
|
glVertex3f (x,y +h, 0.);
|
|
|
|
glVertex3f (x + w - 2, y + h, 0.);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DrawRoundedBlock (int x, int y, int w, int h) {
|
|
|
|
const int d = 16;
|
|
|
|
const float shading_dark = 0.5;
|
|
|
|
const float shading_light = 1.3;
|
|
|
|
|
|
|
|
assert (h > d);
|
|
|
|
assert (w > d);
|
|
|
|
|
2010-10-30 11:39:59 +02:00
|
|
|
glBegin(GL_QUADS);
|
2011-01-02 18:25:20 +01:00
|
|
|
// lower part
|
2010-10-30 11:39:59 +02:00
|
|
|
glVertex3f (x, y, 0.);
|
|
|
|
glVertex3f (x, y + d, 0.);
|
|
|
|
glVertex3f (x + w, y + d, 0.);
|
|
|
|
glVertex3f (x + w - d, y, 0.);
|
|
|
|
|
|
|
|
// middle part
|
|
|
|
glVertex3f (x, y + d, 0.);
|
|
|
|
glVertex3f (x, y + d + h - 2 * d, 0.);
|
|
|
|
glVertex3f (x + w, y + d + h - 2 * d, 0.);
|
|
|
|
glVertex3f (x + w, y + d, 0.);
|
|
|
|
|
|
|
|
// bottom part
|
|
|
|
glVertex3f (x, y + h - d, 0.);
|
|
|
|
glVertex3f (x + d, y + h, 0.);
|
|
|
|
glVertex3f (x + w, y + h, 0.);
|
|
|
|
glVertex3f (x + w, y + h - d, 0.);
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
// "Shading"
|
|
|
|
float color[4];
|
|
|
|
glGetFloatv (GL_CURRENT_COLOR, color);
|
|
|
|
|
|
|
|
glLineWidth(3);
|
|
|
|
glColor3f (color[0] * shading_dark, color[1] * shading_dark, color[2] * shading_dark);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3f (x,y + 2, 0.);
|
|
|
|
glVertex3f (x,y + h -d, 0.);
|
|
|
|
glVertex3f (x + d, y + h, 0.);
|
|
|
|
glVertex3f (x + w - 2, y + h, 0.);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glColor3f (color[0] * shading_light, color[1] * shading_light, color[2] * shading_light);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3f (x + w - d, y, 0.);
|
|
|
|
glVertex3f (x + w, y + d, 0.);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glColor4fv (color);
|
|
|
|
}
|
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
/** \brief Draws a label with a given caption at the position (vertically centered)
|
|
|
|
*
|
|
|
|
* This function draws the label at the horizontal x position and centers the
|
|
|
|
* label with regard to the height of the rendered caption.
|
|
|
|
*
|
|
|
|
* \TODO [med] The vertical alignment around the center of the vertical height
|
|
|
|
* of the string is rather unfortunate as different contents will be rendered
|
|
|
|
* at different vertical positions (e.g. "aaa" and "ggg")
|
|
|
|
*/
|
2010-08-29 23:59:24 +02:00
|
|
|
void Label (int id, const char* caption, int x, int y) {
|
|
|
|
if (caption != NULL) {
|
|
|
|
float width, height;
|
|
|
|
view = EngineGetView ();
|
|
|
|
assert (view);
|
|
|
|
|
|
|
|
view->DrawGLStringMeasure(caption, &width, &height);
|
|
|
|
view->DrawGLString(x , y + height * 0.5, caption);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-13 18:45:15 +01:00
|
|
|
/** \brief Draws a label with a given caption centered at the position (vertically centered)
|
|
|
|
*
|
|
|
|
* This function draws the label at the horizontal x position and centers the
|
|
|
|
* label with regard to the height of the rendered caption.
|
|
|
|
*
|
|
|
|
* \TODO [med] The vertical alignment around the center of the vertical height
|
|
|
|
* of the string is rather unfortunate as different contents will be rendered
|
|
|
|
* at different vertical positions (e.g. "aaa" and "ggg")
|
|
|
|
*/
|
|
|
|
void LabelCentered (int id, const char* caption, int x, int y) {
|
|
|
|
if (caption != NULL) {
|
|
|
|
float width, height;
|
|
|
|
view = EngineGetView ();
|
|
|
|
assert (view);
|
|
|
|
|
2011-01-02 18:25:20 +01:00
|
|
|
SelectFont("console.ttf size=23");
|
2010-11-13 18:45:15 +01:00
|
|
|
view->DrawGLStringMeasure(caption, &width, &height);
|
|
|
|
view->DrawGLString(x - 0.5 * width, y + height * 0.5, caption);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-29 23:59:24 +02:00
|
|
|
/** \brief Draws a button at the given position
|
2010-09-11 02:28:50 +02:00
|
|
|
*
|
|
|
|
* The area defined by the parameters defines the clickable area. However
|
|
|
|
* decorations might be drawn on a smaller or bigger area.
|
2010-08-29 23:59:24 +02:00
|
|
|
*
|
|
|
|
* \returns true if it was clicked
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
bool Button (int id, const char* caption, int x, int y, int w, int h) {
|
|
|
|
controller = EngineGetController();
|
|
|
|
assert (controller);
|
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
// LogMessage ("id = %d hotitem = %d activeitem = %d kbditem = %d", id, controller->uistate.hotitem, controller->uistate.activeitem, controller->uistate.kbditem);
|
|
|
|
|
2010-08-29 23:59:24 +02:00
|
|
|
// Check for hotness
|
|
|
|
if (regionhit (x, y, w, h)) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
if (controller->uistate.activeitem == 0
|
|
|
|
&& controller->GetButtonState(MouseButtonLeft))
|
|
|
|
controller->uistate.activeitem = id;
|
|
|
|
}
|
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
// If nothing is selected
|
|
|
|
if (controller->uistate.hotitem != 0) {
|
|
|
|
controller->uistate.kbditem = controller->uistate.hotitem;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == 0) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
controller->uistate.kbditem = id;
|
|
|
|
}
|
|
|
|
|
2010-08-29 23:59:24 +02:00
|
|
|
// Render
|
|
|
|
glColor3f (0.2, 0.2, 0.2);
|
2010-11-13 18:45:15 +01:00
|
|
|
// DrawRoundedBlock (x + 4, y + 4, w, h);
|
2010-08-29 23:59:24 +02:00
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
if (controller->uistate.hotitem == id
|
|
|
|
|| controller->uistate.kbditem == id) {
|
2010-08-29 23:59:24 +02:00
|
|
|
if (controller->uistate.activeitem == id) {
|
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
2010-11-13 18:45:15 +01:00
|
|
|
DrawRoundedBlock (x, y, w, h);
|
2010-08-29 23:59:24 +02:00
|
|
|
} else {
|
|
|
|
glColor3f (0.7, 0.7, 0.7);
|
2010-11-13 18:45:15 +01:00
|
|
|
DrawRoundedBlock (x, y, w, h);
|
2010-08-29 23:59:24 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
2010-11-13 18:45:15 +01:00
|
|
|
DrawRoundedBlock (x, y, w, h);
|
2010-08-29 23:59:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Caption
|
|
|
|
if (caption != NULL) {
|
2011-02-11 17:43:23 +01:00
|
|
|
float width, height;
|
|
|
|
view = EngineGetView ();
|
|
|
|
assert (view);
|
|
|
|
|
|
|
|
// we have to load the font prior to measuring it
|
|
|
|
SelectFont("console.ttf size=23");
|
|
|
|
view->DrawGLStringMeasure(caption, &width, &height);
|
|
|
|
|
|
|
|
float xpos = x + w * 0.5 - width * 0.5;
|
|
|
|
float ypos = y + h * 0.5 - height * 0.5;
|
|
|
|
// LogDebug ("measure '%s' width = %f height = %f", caption, width, height);
|
|
|
|
|
|
|
|
if (controller->uistate.hotitem == id || controller->uistate.kbditem == id) {
|
|
|
|
SelectFont("console.ttf size=23 color=#666666");
|
|
|
|
view->DrawGLString( xpos - 2., ypos + 2., caption);
|
|
|
|
SelectFont("console.ttf size=23 color=#ffffff");
|
|
|
|
view->DrawGLString( xpos, ypos, caption);
|
|
|
|
} else {
|
|
|
|
SelectFont("console.ttf size=23 color=#4d4d4d");
|
|
|
|
view->DrawGLString( xpos - 2., ypos + 2., caption);
|
|
|
|
SelectFont("console.ttf size=23 color=#b3b3b3");
|
|
|
|
view->DrawGLString( xpos, ypos, caption);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mouse Logic
|
|
|
|
if (controller->GetButtonState(MouseButtonLeft) == false
|
|
|
|
&& controller->uistate.hotitem == id
|
|
|
|
&& controller->uistate.activeitem == id) {
|
|
|
|
controller->uistate.lastwidget = id;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Keyboard Logic
|
|
|
|
if (controller->uistate.kbditem == id) {
|
|
|
|
// Any unicode keys that were sent get cleared
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
|
|
|
|
// We have to make sure, that we always clear the uistate.last_keysym
|
|
|
|
// value, otherwise the same action might be repeated over and over.
|
|
|
|
switch (controller->uistate.last_keysym) {
|
|
|
|
case SDLK_DOWN:
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_UP:
|
|
|
|
controller->uistate.kbditem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.hotitem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
2011-02-12 15:43:06 +01:00
|
|
|
case SDLK_TAB:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
break;
|
2011-02-11 17:43:23 +01:00
|
|
|
case SDLK_RETURN:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
// As we (probably) exit the current set of widgets, we have to clear
|
|
|
|
// the uistate.kbditem value.
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
controller->uistate.lastwidget = id;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CheckButton (int id, const char* caption, bool checked, int x, int y, int w, int h) {
|
|
|
|
controller = EngineGetController();
|
|
|
|
assert (controller);
|
|
|
|
|
|
|
|
// LogMessage ("id = %d hotitem = %d activeitem = %d kbditem = %d", id, controller->uistate.hotitem, controller->uistate.activeitem, controller->uistate.kbditem);
|
|
|
|
|
|
|
|
// Check for hotness
|
|
|
|
if (regionhit (x, y, w, h)) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
if (controller->uistate.activeitem == 0
|
|
|
|
&& controller->GetButtonState(MouseButtonLeft))
|
|
|
|
controller->uistate.activeitem = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If nothing is selected
|
|
|
|
if (controller->uistate.hotitem != 0) {
|
|
|
|
controller->uistate.kbditem = controller->uistate.hotitem;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == 0) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
controller->uistate.kbditem = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render
|
|
|
|
if (checked) {
|
|
|
|
glColor3f (0.91, 0.84, 0.);
|
|
|
|
DrawRoundedBlock (x - 2, y - 2, w + 4, h + 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
glColor3f (0.2, 0.2, 0.2);
|
|
|
|
|
|
|
|
if (controller->uistate.hotitem == id
|
|
|
|
|| controller->uistate.kbditem == id) {
|
|
|
|
if (controller->uistate.activeitem == id) {
|
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
|
|
|
DrawRoundedBlock (x, y, w, h);
|
|
|
|
} else {
|
|
|
|
glColor3f (0.7, 0.7, 0.7);
|
|
|
|
DrawRoundedBlock (x, y, w, h);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
|
|
|
DrawRoundedBlock (x, y, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Caption
|
|
|
|
if (caption != NULL) {
|
2010-08-29 23:59:24 +02:00
|
|
|
float width, height;
|
|
|
|
view = EngineGetView ();
|
|
|
|
assert (view);
|
|
|
|
|
2010-11-13 18:45:15 +01:00
|
|
|
// we have to load the font prior to measuring it
|
|
|
|
SelectFont("console.ttf size=23");
|
2010-08-29 23:59:24 +02:00
|
|
|
view->DrawGLStringMeasure(caption, &width, &height);
|
2010-11-13 18:45:15 +01:00
|
|
|
|
|
|
|
float xpos = x + w * 0.5 - width * 0.5;
|
|
|
|
float ypos = y + h * 0.5 - height * 0.5;
|
|
|
|
// LogDebug ("measure '%s' width = %f height = %f", caption, width, height);
|
|
|
|
|
|
|
|
if (controller->uistate.hotitem == id || controller->uistate.kbditem == id) {
|
|
|
|
SelectFont("console.ttf size=23 color=#666666");
|
|
|
|
view->DrawGLString( xpos - 2., ypos + 2., caption);
|
|
|
|
SelectFont("console.ttf size=23 color=#ffffff");
|
|
|
|
view->DrawGLString( xpos, ypos, caption);
|
|
|
|
} else {
|
|
|
|
SelectFont("console.ttf size=23 color=#4d4d4d");
|
|
|
|
view->DrawGLString( xpos - 2., ypos + 2., caption);
|
|
|
|
SelectFont("console.ttf size=23 color=#b3b3b3");
|
|
|
|
view->DrawGLString( xpos, ypos, caption);
|
|
|
|
}
|
2010-08-29 23:59:24 +02:00
|
|
|
}
|
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
// Mouse Logic
|
2010-08-29 23:59:24 +02:00
|
|
|
if (controller->GetButtonState(MouseButtonLeft) == false
|
|
|
|
&& controller->uistate.hotitem == id
|
2010-09-11 02:28:50 +02:00
|
|
|
&& controller->uistate.activeitem == id) {
|
|
|
|
controller->uistate.lastwidget = id;
|
|
|
|
|
2010-08-29 23:59:24 +02:00
|
|
|
return true;
|
2010-09-11 02:28:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Keyboard Logic
|
|
|
|
if (controller->uistate.kbditem == id) {
|
2010-09-11 14:32:31 +02:00
|
|
|
// Any unicode keys that were sent get cleared
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
// We have to make sure, that we always clear the uistate.last_keysym
|
|
|
|
// value, otherwise the same action might be repeated over and over.
|
|
|
|
switch (controller->uistate.last_keysym) {
|
|
|
|
case SDLK_DOWN:
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_UP:
|
|
|
|
controller->uistate.kbditem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.hotitem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
2011-02-12 15:43:06 +01:00
|
|
|
case SDLK_TAB:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
break;
|
2010-09-11 02:28:50 +02:00
|
|
|
case SDLK_RETURN:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
// As we (probably) exit the current set of widgets, we have to clear
|
|
|
|
// the uistate.kbditem value.
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
controller->uistate.lastwidget = id;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief An Edit widget that allows editing of a string consisting of one line
|
|
|
|
*
|
|
|
|
* \TODO [med] vertical alignment (especially of text) is a bit whacky
|
|
|
|
*
|
|
|
|
* \returns true if it was clicked
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
bool LineEdit (int id, int x, int y, std::string &text_value, const int &maxlength) {
|
|
|
|
controller = EngineGetController();
|
|
|
|
assert (controller);
|
|
|
|
|
2010-11-13 18:45:15 +01:00
|
|
|
int textpos_x = x + 8;
|
|
|
|
int textpos_y = y + 5;
|
|
|
|
|
|
|
|
y -= 16;
|
2010-09-11 02:28:50 +02:00
|
|
|
int w = maxlength * 16;
|
2010-11-13 18:45:15 +01:00
|
|
|
int h = 30;
|
2010-09-11 02:28:50 +02:00
|
|
|
|
2010-09-11 14:32:31 +02:00
|
|
|
// LogMessage ("id = %d hotitem = %d activeitem = %d kbditem = %d key = %s", id, controller->uistate.hotitem, controller->uistate.activeitem, controller->uistate.kbditem, convert_keycode (controller->uistate.last_keysym));
|
2010-09-11 02:28:50 +02:00
|
|
|
|
|
|
|
// Check for hotness
|
|
|
|
if (regionhit (x, y, w, h)) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
if (controller->uistate.activeitem == 0
|
2010-09-11 14:32:31 +02:00
|
|
|
&& controller->GetButtonState(MouseButtonLeft)) {
|
2010-09-11 02:28:50 +02:00
|
|
|
controller->uistate.activeitem = id;
|
2010-09-11 14:32:31 +02:00
|
|
|
}
|
2010-09-11 02:28:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == 0) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
controller->uistate.kbditem = id;
|
2010-09-11 14:32:31 +02:00
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return false;
|
2010-09-11 02:28:50 +02:00
|
|
|
}
|
|
|
|
|
2010-09-11 14:32:31 +02:00
|
|
|
// If we have keyboard focus, we highlight the widget
|
|
|
|
if ( controller->uistate.kbditem == id) {
|
2010-09-11 02:28:50 +02:00
|
|
|
if (controller->uistate.activeitem == id) {
|
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
2010-10-30 11:39:59 +02:00
|
|
|
DrawBlock (x, y, w, h);
|
2010-09-11 02:28:50 +02:00
|
|
|
} else {
|
|
|
|
glColor3f (0.7, 0.7, 0.7);
|
2010-10-30 11:39:59 +02:00
|
|
|
DrawBlock (x, y, w, h);
|
2010-09-11 02:28:50 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
2010-10-30 11:39:59 +02:00
|
|
|
DrawBlock (x, y, w, h);
|
2010-09-11 02:28:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Rendering of the current value
|
|
|
|
float width, height;
|
|
|
|
view = EngineGetView ();
|
|
|
|
assert (view);
|
|
|
|
|
|
|
|
glColor3f (1., 1., 1.);
|
|
|
|
|
|
|
|
std::string text_output = text_value;
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == id && SDL_GetTicks() >> 9 & 1)
|
|
|
|
text_output += "_";
|
|
|
|
|
2011-01-02 18:25:20 +01:00
|
|
|
SelectFont("console.ttf size=23");
|
2010-09-11 02:28:50 +02:00
|
|
|
view->DrawGLStringMeasure(text_value.c_str(), &width, &height);
|
2010-11-13 18:45:15 +01:00
|
|
|
view->DrawGLString(textpos_x, textpos_y, text_output.c_str());
|
2010-09-11 02:28:50 +02:00
|
|
|
|
|
|
|
// Keyboard Logic
|
|
|
|
if (controller->uistate.kbditem == id) {
|
|
|
|
switch (controller->uistate.last_keysym) {
|
|
|
|
case SDLK_DOWN:
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_UP:
|
|
|
|
controller->uistate.kbditem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.hotitem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_CLEAR:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
case SDLK_ESCAPE:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return false;
|
|
|
|
break;
|
2011-02-12 15:43:06 +01:00
|
|
|
case SDLK_TAB:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return false;
|
|
|
|
break;
|
2010-09-11 02:28:50 +02:00
|
|
|
case SDLK_RETURN:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case SDLK_BACKSPACE:
|
|
|
|
if (text_value.size() > 0) {
|
|
|
|
text_value = text_value.substr(0, text_value.size() - 1);
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// The raw input processing
|
|
|
|
if (maxlength > 0 && text_value.size() < maxlength) {
|
|
|
|
if (controller->uistate.last_unicode) {
|
|
|
|
if ((controller->uistate.last_unicode & 0xFF80) == 0) {
|
2011-01-30 21:43:04 +01:00
|
|
|
// we do not want to add special characters such as backspaces
|
|
|
|
// etc.
|
|
|
|
if ((controller->uistate.last_unicode & 0xFFFF) >= 0x20)
|
|
|
|
text_value += controller->uistate.last_unicode & 0x7F;
|
2010-09-11 02:28:50 +02:00
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
LogWarning ("Input key not supported!");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
controller->uistate.lastwidget = id;
|
|
|
|
|
|
|
|
// Mouse Logic
|
|
|
|
if (controller->GetButtonState(MouseButtonLeft) == false
|
|
|
|
&& controller->uistate.hotitem == id
|
|
|
|
&& controller->uistate.activeitem == id) {
|
|
|
|
controller->uistate.kbditem = id;
|
2010-09-11 14:32:31 +02:00
|
|
|
controller->uistate.last_unicode = 0;
|
2010-09-11 02:28:50 +02:00
|
|
|
}
|
2010-08-29 23:59:24 +02:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-16 17:03:41 +01:00
|
|
|
bool LineEditMasked (int id, int x, int y, std::string &text_value, const int &maxlength, const std::string &valid_chars) {
|
|
|
|
controller = EngineGetController();
|
|
|
|
assert (controller);
|
|
|
|
|
|
|
|
int textpos_x = x + 8;
|
|
|
|
int textpos_y = y + 5;
|
|
|
|
|
|
|
|
y -= 16;
|
|
|
|
int w = maxlength * 16;
|
|
|
|
int h = 30;
|
|
|
|
|
|
|
|
// LogMessage ("id = %d hotitem = %d activeitem = %d kbditem = %d key = %s", id, controller->uistate.hotitem, controller->uistate.activeitem, controller->uistate.kbditem, convert_keycode (controller->uistate.last_keysym));
|
|
|
|
|
|
|
|
// Check for hotness
|
|
|
|
if (regionhit (x, y, w, h)) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
if (controller->uistate.activeitem == 0
|
|
|
|
&& controller->GetButtonState(MouseButtonLeft)) {
|
|
|
|
controller->uistate.activeitem = id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == 0) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
controller->uistate.kbditem = id;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have keyboard focus, we highlight the widget
|
|
|
|
if ( controller->uistate.kbditem == id) {
|
|
|
|
if (controller->uistate.activeitem == id) {
|
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
|
|
|
DrawBlock (x, y, w, h);
|
|
|
|
} else {
|
|
|
|
glColor3f (0.7, 0.7, 0.7);
|
|
|
|
DrawBlock (x, y, w, h);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
|
|
|
DrawBlock (x, y, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rendering of the current value
|
|
|
|
float width, height;
|
|
|
|
view = EngineGetView ();
|
|
|
|
assert (view);
|
|
|
|
|
|
|
|
glColor3f (1., 1., 1.);
|
|
|
|
|
|
|
|
std::string text_output = text_value;
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == id && SDL_GetTicks() >> 9 & 1)
|
|
|
|
text_output += "_";
|
|
|
|
|
|
|
|
SelectFont("console.ttf size=23");
|
|
|
|
view->DrawGLStringMeasure(text_value.c_str(), &width, &height);
|
|
|
|
view->DrawGLString(textpos_x, textpos_y, text_output.c_str());
|
|
|
|
|
|
|
|
// Keyboard Logic
|
|
|
|
if (controller->uistate.kbditem == id) {
|
|
|
|
switch (controller->uistate.last_keysym) {
|
|
|
|
case SDLK_DOWN:
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_UP:
|
|
|
|
controller->uistate.kbditem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.hotitem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_CLEAR:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
case SDLK_ESCAPE:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
case SDLK_TAB:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
case SDLK_RETURN:
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case SDLK_BACKSPACE:
|
|
|
|
if (text_value.size() > 0) {
|
|
|
|
text_value = text_value.substr(0, text_value.size() - 1);
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// The raw input processing
|
|
|
|
if (maxlength > 0 && text_value.size() < maxlength) {
|
|
|
|
if (controller->uistate.last_unicode) {
|
|
|
|
if ((controller->uistate.last_unicode & 0xFF80) == 0) {
|
|
|
|
char c = controller->uistate.last_unicode & 0x7F;
|
|
|
|
|
|
|
|
// we do not want to add special characters such as backspaces
|
|
|
|
// etc.
|
|
|
|
if (c >= 0x20 && valid_chars.find(c) != std::string::npos ) {
|
|
|
|
text_value += c;
|
|
|
|
}
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
LogWarning ("Input key not supported!");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
controller->uistate.lastwidget = id;
|
|
|
|
|
|
|
|
// Mouse Logic
|
|
|
|
if (controller->GetButtonState(MouseButtonLeft) == false
|
|
|
|
&& controller->uistate.hotitem == id
|
|
|
|
&& controller->uistate.activeitem == id) {
|
|
|
|
controller->uistate.kbditem = id;
|
|
|
|
controller->uistate.last_unicode = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-11-22 20:00:44 +01:00
|
|
|
float VerticalSlider (int id, int x, int y, int w, int h, float min_value, float max_value, float &value) {
|
|
|
|
const int knob_width = 16;
|
|
|
|
const int knob_height = h * 2;
|
|
|
|
|
|
|
|
int slider_pos = (w * value) / max_value - knob_width / 2;
|
|
|
|
|
|
|
|
// Check for hotness
|
|
|
|
if (regionhit (x, y + h * 0.5 - knob_height * 0.5, w, knob_height)) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
if (controller->uistate.activeitem == 0
|
|
|
|
&& controller->GetButtonState(MouseButtonLeft)) {
|
|
|
|
controller->uistate.activeitem = id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If nothing is selected
|
|
|
|
if (controller->uistate.hotitem != 0) {
|
|
|
|
controller->uistate.kbditem = controller->uistate.hotitem;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == 0) {
|
|
|
|
controller->uistate.hotitem = id;
|
|
|
|
controller->uistate.kbditem = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have keyboard focus, we highlight the widget
|
|
|
|
if ( controller->uistate.kbditem == id) {
|
|
|
|
if (controller->uistate.activeitem == id) {
|
|
|
|
glColor3f (0.6, 0.6, 0.6);
|
|
|
|
DrawBlock (x, y, w, h);
|
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
|
|
|
DrawBlock (x + slider_pos, y + h * 0.5 - knob_height * 0.5, knob_width, knob_height);
|
|
|
|
} else {
|
|
|
|
glColor3f (0.6, 0.6, 0.6);
|
|
|
|
DrawBlock (x, y, w, h);
|
|
|
|
glColor3f (0.7, 0.7, 0.7);
|
|
|
|
DrawBlock (x + slider_pos, y + h * 0.5 - knob_height * 0.5, knob_width, knob_height);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
|
|
|
DrawBlock (x, y, w, h);
|
|
|
|
glColor3f (0.5, 0.5, 0.5);
|
|
|
|
DrawBlock (x + slider_pos, y + h * 0.5 - knob_height * 0.5, knob_width, knob_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (controller->uistate.kbditem == id) {
|
|
|
|
switch (controller->uistate.last_keysym) {
|
|
|
|
case SDLK_DOWN:
|
|
|
|
controller->uistate.kbditem = 0;
|
|
|
|
controller->uistate.hotitem = 0;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_UP:
|
|
|
|
controller->uistate.kbditem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.hotitem = controller->uistate.lastwidget;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
break;
|
|
|
|
case SDLK_LEFT:
|
|
|
|
value -= (max_value - min_value) * 0.1;
|
|
|
|
if ( value < min_value)
|
|
|
|
value = min_value;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case SDLK_RIGHT:
|
|
|
|
value += (max_value - min_value) * 0.1;
|
|
|
|
if ( value > max_value)
|
|
|
|
value = max_value;
|
|
|
|
controller->uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
controller->uistate.lastwidget = id;
|
|
|
|
|
|
|
|
if (controller->uistate.activeitem == id) {
|
|
|
|
int mouse_pos[2];
|
|
|
|
controller->GetMouseScreenPosition(mouse_pos);
|
|
|
|
int rel_mouse_pos = mouse_pos[0] - x;
|
|
|
|
if (rel_mouse_pos < 0)
|
|
|
|
rel_mouse_pos = 0;
|
|
|
|
if (rel_mouse_pos > w)
|
|
|
|
rel_mouse_pos = w;
|
|
|
|
|
|
|
|
float mouse_value = rel_mouse_pos * max_value / static_cast<float>(w);
|
|
|
|
|
|
|
|
if (mouse_value != value) {
|
|
|
|
value = mouse_value;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-09-11 14:32:31 +02:00
|
|
|
bool CheckKeyPress (int keycode) {
|
2011-01-30 21:43:04 +01:00
|
|
|
if (controller->GetButtonState(keycode))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CheckKeyPressed (int keycode) {
|
2011-03-15 10:21:26 +01:00
|
|
|
if (controller->uistate.keypressed_set.find(keycode) != controller->uistate.keypressed_set.end()) {
|
|
|
|
controller->uistate.keypressed_set.erase(keycode);
|
2010-09-11 14:32:31 +02:00
|
|
|
return true;
|
2011-03-15 10:21:26 +01:00
|
|
|
}
|
2010-09-11 14:32:31 +02:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-01-30 21:43:04 +01:00
|
|
|
|
2010-08-29 23:59:24 +02:00
|
|
|
};
|
|
|
|
};
|