691 lines
16 KiB
C++
691 lines
16 KiB
C++
/* --------------------------------------------------------------------
|
|
EXTREME TUXRACER
|
|
|
|
Copyright (C) 1999-2001 Jasmin F. Patry (Tuxracer)
|
|
Copyright (C) 2010 Extreme Tuxracer Team
|
|
|
|
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.
|
|
|
|
This program 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.
|
|
---------------------------------------------------------------------*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <etr_config.h>
|
|
#endif
|
|
|
|
#include "gui.h"
|
|
#include "textures.h"
|
|
#include "font.h"
|
|
#include "ogl.h"
|
|
#include "winsys.h"
|
|
#include <list>
|
|
#include <vector>
|
|
|
|
|
|
#define CURSOR_SIZE 10
|
|
|
|
static vector<TWidget*> Widgets;
|
|
|
|
static bool Inside(int x, int y, const TRect& Rect) {
|
|
return (x >= Rect.left
|
|
&& x <= Rect.left + Rect.width
|
|
&& y >= Rect.top
|
|
&& y <= Rect.top + Rect.height);
|
|
}
|
|
|
|
TWidget::TWidget(int x, int y, int width, int height)
|
|
: active(true)
|
|
, visible(true)
|
|
, focus(false) {
|
|
mouseRect.top = y;
|
|
mouseRect.left = x;
|
|
mouseRect.height = height;
|
|
mouseRect.width = width;
|
|
position.x = x;
|
|
position.y = y;
|
|
}
|
|
|
|
bool TWidget::Click(int x, int y) {
|
|
return active && visible && Inside(x, y, mouseRect);
|
|
}
|
|
|
|
void TWidget::MouseMove(int x, int y) {
|
|
focus = active && visible && Inside(x, y, mouseRect);
|
|
}
|
|
|
|
TTextButton::TTextButton(int x, int y, const string& text_, double ftsize_)
|
|
: TWidget(x, y, 0, 0)
|
|
, text(text_)
|
|
, ftsize(ftsize_) {
|
|
if (ftsize < 0) ftsize = FT.AutoSizeN(4);
|
|
|
|
double len = FT.GetTextWidth(text);
|
|
if (x == CENTER) position.x = (int)((Winsys.resolution.width - len) / 2);
|
|
int offs = (int)(ftsize / 5);
|
|
mouseRect.left = position.x-20;
|
|
mouseRect.top = position.y+offs;
|
|
mouseRect.width = len+40;
|
|
mouseRect.height = ftsize+offs;
|
|
}
|
|
|
|
void TTextButton::Draw() const {
|
|
if (focus)
|
|
FT.SetColor(colDYell);
|
|
else
|
|
FT.SetColor(colWhite);
|
|
FT.SetSize(ftsize);
|
|
FT.DrawString(position.x, position.y, text);
|
|
}
|
|
|
|
TTextButton* AddTextButton(const string& text, int x, int y, double ftsize) {
|
|
Widgets.push_back(new TTextButton(x, y, text, ftsize));
|
|
return static_cast<TTextButton*>(Widgets.back());
|
|
}
|
|
|
|
TTextButton* AddTextButtonN(const string& text, int x, int y, int rel_ftsize) {
|
|
double siz = FT.AutoSizeN(rel_ftsize);
|
|
return AddTextButton(text, x, y, siz);
|
|
}
|
|
|
|
|
|
TTextField::TTextField(int x, int y, int width, int height, const string& text_)
|
|
: TWidget(x, y, width, height)
|
|
, text(text_)
|
|
, cursorPos(0)
|
|
, maxLng(32)
|
|
, time(0.0)
|
|
, cursor(false) {
|
|
}
|
|
|
|
void TTextField::Draw() const {
|
|
const TColor& col = focus?colDYell:colWhite;
|
|
FT.SetColor(col);
|
|
DrawFrameX(mouseRect.left, mouseRect.top, mouseRect.width, mouseRect.height, 3, colMBackgr, col, 1.0);
|
|
FT.AutoSizeN(5);
|
|
FT.DrawString(mouseRect.left+20, mouseRect.top, text);
|
|
|
|
if (cursor && focus) {
|
|
int x = mouseRect.left + 20 + 1;
|
|
if (cursorPos != 0) {
|
|
string temp = text.substr(0, cursorPos);
|
|
x += FT.GetTextWidth(temp);
|
|
}
|
|
int w = 3;
|
|
int h = 26 * Winsys.scale;
|
|
int scrheight = Winsys.resolution.height;
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
glColor(colYellow);
|
|
const GLshort vtx[] = {
|
|
x, scrheight - mouseRect.top - h - 9,
|
|
x + w, scrheight - mouseRect.top - h - 9,
|
|
x + w, scrheight - mouseRect.top - 9,
|
|
x, scrheight - mouseRect.top - 9
|
|
};
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glVertexPointer(2, GL_SHORT, 0, vtx);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glEnable(GL_TEXTURE_2D);
|
|
}
|
|
}
|
|
|
|
void TTextField::Key(unsigned int key, unsigned int mod, bool released) {
|
|
if (islower(key)) {
|
|
if (text.size() < maxLng) {
|
|
if (mod & KMOD_SHIFT) text.insert(cursorPos, 1, toupper(key));
|
|
else text.insert(cursorPos, 1, key);
|
|
cursorPos++;
|
|
}
|
|
} else if (isdigit(key)) {
|
|
if (text.size() < maxLng) {
|
|
text.insert(cursorPos, 1, key);
|
|
cursorPos++;
|
|
}
|
|
} else {
|
|
switch (key) {
|
|
case SDLK_DELETE:
|
|
if (cursorPos < text.size()) text.erase(cursorPos, 1);
|
|
break;
|
|
case SDLK_BACKSPACE:
|
|
if (cursorPos > 0) { text.erase(cursorPos-1, 1); cursorPos--; }
|
|
break;
|
|
case SDLK_RIGHT:
|
|
if (cursorPos < text.size()) cursorPos++;
|
|
break;
|
|
case SDLK_LEFT:
|
|
if (cursorPos > 0) cursorPos--;
|
|
break;
|
|
case SDLK_HOME:
|
|
cursorPos = 0;
|
|
break;
|
|
case SDLK_END:
|
|
cursorPos = text.size();
|
|
break;
|
|
case SDLK_SPACE:
|
|
text.insert(cursorPos, 1, 21);
|
|
cursorPos++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TTextField::UpdateCursor(double timestep) {
|
|
time += timestep;
|
|
if (time > CRSR_PERIODE) {
|
|
time = 0;
|
|
cursor = !cursor;
|
|
}
|
|
}
|
|
|
|
TTextField* AddTextField(const string& text, int x, int y, int width, int height) {
|
|
Widgets.push_back(new TTextField(x, y, width, height, text));
|
|
return static_cast<TTextField*>(Widgets.back());
|
|
}
|
|
|
|
void TCheckbox::Draw() const {
|
|
Tex.Draw(CHECKBOX, position.x + width - 32, position.y, 1.0);
|
|
if (checked)
|
|
Tex.Draw(CHECKMARK_SMALL, position.x + width - 32, position.y, 1.0);
|
|
if (focus)
|
|
FT.SetColor(colDYell);
|
|
else
|
|
FT.SetColor(colWhite);
|
|
FT.DrawString(position.x, position.y, tag);
|
|
}
|
|
|
|
bool TCheckbox::Click(int x, int y) {
|
|
if (active && visible && Inside(x, y, mouseRect)) {
|
|
checked = !checked;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TCheckbox::Key(unsigned int key, unsigned int mod, bool released) {
|
|
if (released) return;
|
|
|
|
if (key == SDLK_SPACE || key == SDLK_RIGHT || key == SDLK_LEFT) {
|
|
checked = !checked;
|
|
}
|
|
}
|
|
|
|
TCheckbox* AddCheckbox(int x, int y, int width, const string& tag) {
|
|
Widgets.push_back(new TCheckbox(x, y, width, tag));
|
|
return static_cast<TCheckbox*>(Widgets.back());
|
|
}
|
|
|
|
void TIconButton::SetValue(int _value) {
|
|
value = _value;
|
|
if (value > maximum)
|
|
value = maximum;
|
|
}
|
|
|
|
void TIconButton::Draw() const {
|
|
TColor framecol = colWhite;
|
|
if (focus) framecol = colDYell;
|
|
|
|
int line = 3;
|
|
int framesize = size + 2 * line;
|
|
int t = Winsys.resolution.height - position.y;
|
|
int y = t - size;
|
|
int x = position.x;
|
|
int r = x + size;
|
|
|
|
DrawFrameX(position.x-line, position.y-line,
|
|
framesize, framesize, line, colBlack, framecol, 1.0);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
texture->Bind();
|
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
|
|
const GLshort vtx[] = {
|
|
x, y,
|
|
r, y,
|
|
r, t,
|
|
x, t
|
|
};
|
|
static const GLfloat tex[4][8] = {
|
|
{
|
|
0, 0.5,
|
|
0.5, 0.5,
|
|
0.5, 1,
|
|
0, 1
|
|
}, {
|
|
0.5, 0.5,
|
|
1, 0.5,
|
|
1, 1,
|
|
0.5, 1
|
|
}, {
|
|
0, 0,
|
|
0.5, 0,
|
|
0.5, 0.5,
|
|
0, 0.5
|
|
}, {
|
|
0.5, 0,
|
|
1, 0,
|
|
1, 0.5,
|
|
0.5, 0.5
|
|
}
|
|
};
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glVertexPointer(2, GL_SHORT, 0, vtx);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, tex[value]);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
bool TIconButton::Click(int x, int y) {
|
|
if (Inside(x, y, mouseRect)) {
|
|
value++;
|
|
if (value > maximum)
|
|
value = 0;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TIconButton::Key(unsigned int key, unsigned int mod, bool released) {
|
|
if (released) return;
|
|
|
|
if (key == SDLK_DOWN || key == SDLK_LEFT) { // Arrow down/left
|
|
value--;
|
|
if (value < 0)
|
|
value = maximum;
|
|
} else if (key == SDLK_UP || key == SDLK_RIGHT) { // Arrow up/right
|
|
value++;
|
|
if (value > maximum)
|
|
value = 0;
|
|
}
|
|
}
|
|
|
|
TIconButton* AddIconButton(int x, int y, TTexture* texture, double size, int maximum, int value) {
|
|
Widgets.push_back(new TIconButton(x, y, texture, size, maximum, value));
|
|
return static_cast<TIconButton*>(Widgets.back());
|
|
}
|
|
|
|
void TArrow::Draw() const {
|
|
static const float textl[6] = { 0.5, 0.0, 0.5, 0.5, 0.0, 0.5 };
|
|
static const float textr[6] = { 1.0, 0.5, 1.0, 1.0, 0.5, 1.0 };
|
|
static const float texbl[6] = { 0.25, 0.25, 0.75, 0.00, 0.00, 0.50 };
|
|
static const float texbr[6] = {0.50, 0.50, 1.00, 0.25, 0.25, 0.75};
|
|
|
|
int type = 0;
|
|
if (active)
|
|
type = 1;
|
|
if (focus)
|
|
type++;
|
|
if (down)
|
|
type += 3;
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_TEXTURE_2D);
|
|
Tex.BindTex(LB_ARROWS);
|
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
|
|
const GLfloat tex[] = {
|
|
textl[type], texbl[type],
|
|
textr[type], texbl[type],
|
|
textr[type], texbr[type],
|
|
textl[type], texbr[type]
|
|
};
|
|
const GLshort vtx[] = {
|
|
position.x, Winsys.resolution.height - position.y - 16,
|
|
position.x + 32, Winsys.resolution.height - position.y - 16,
|
|
position.x + 32, Winsys.resolution.height - position.y,
|
|
position.x, Winsys.resolution.height - position.y
|
|
};
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glVertexPointer(2, GL_SHORT, 0, vtx);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, tex);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
TArrow* AddArrow(int x, int y, bool down) {
|
|
Widgets.push_back(new TArrow(x, y, down));
|
|
return static_cast<TArrow*>(Widgets.back());
|
|
}
|
|
|
|
|
|
TUpDown::TUpDown(int x, int y, int min_, int max_, int value_, int distance)
|
|
: TWidget(x, y, 32, 32+distance)
|
|
, up(x, y+16+distance, true)
|
|
, down(x, y, false)
|
|
, value(value_)
|
|
, minimum(min_)
|
|
, maximum(max_) {
|
|
up.SetActive(value < maximum);
|
|
down.SetActive(value > minimum);
|
|
}
|
|
|
|
void TUpDown::Draw() const {
|
|
up.Draw();
|
|
down.Draw();
|
|
}
|
|
|
|
bool TUpDown::Click(int x, int y) {
|
|
if (active && visible && up.Click(x, y)) {
|
|
value++;
|
|
down.SetActive(true);
|
|
if (value == maximum)
|
|
up.SetActive(false);
|
|
return true;
|
|
}
|
|
if (active && visible && down.Click(x, y)) {
|
|
up.SetActive(true);
|
|
value--;
|
|
if (value == minimum)
|
|
down.SetActive(false);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TUpDown::Key(unsigned int key, unsigned int mod, bool released) {
|
|
if (released) return;
|
|
|
|
if (key == SDLK_UP || key == SDLK_RIGHT) { // Arrow down/left
|
|
if (value > minimum) {
|
|
value--;
|
|
up.SetActive(true);
|
|
if (value == minimum)
|
|
down.SetActive(false);
|
|
}
|
|
} else if (key == SDLK_DOWN || key == SDLK_LEFT) { // Arrow up/right
|
|
if (value < maximum) {
|
|
value++;
|
|
down.SetActive(true);
|
|
if (value == maximum)
|
|
up.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TUpDown::MouseMove(int x, int y) {
|
|
focus = active && visible &&Inside(x, y, mouseRect);
|
|
up.MouseMove(x, y);
|
|
down.MouseMove(x, y);
|
|
}
|
|
|
|
void TUpDown::SetValue(int value_) {
|
|
value = clamp(minimum, value_, maximum);
|
|
up.SetActive(value < maximum);
|
|
down.SetActive(value > minimum);
|
|
}
|
|
void TUpDown::SetMinimum(int min_) {
|
|
minimum = min_;
|
|
value = clamp(minimum, value, maximum);
|
|
up.SetActive(value < maximum);
|
|
down.SetActive(value > minimum);
|
|
}
|
|
void TUpDown::SetMaximum(int max_) {
|
|
maximum = max_;
|
|
value = clamp(minimum, value, maximum);
|
|
up.SetActive(value < maximum);
|
|
down.SetActive(value > minimum);
|
|
}
|
|
|
|
TUpDown* AddUpDown(int x, int y, int minimum, int maximum, int value, int distance) {
|
|
Widgets.push_back(new TUpDown(x, y, minimum, maximum, value, distance));
|
|
return static_cast<TUpDown*>(Widgets.back());
|
|
}
|
|
|
|
// ------------------ Elementary drawing ---------------------------------------------
|
|
|
|
void DrawFrameX(int x, int y, int w, int h, int line, const TColor& backcol, const TColor& framecol, double transp) {
|
|
float yy = Winsys.resolution.height - y - h;
|
|
if (x < 0) x = (Winsys.resolution.width -w) / 2;
|
|
|
|
glPushMatrix();
|
|
glDisable(GL_TEXTURE_2D);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
glColor(framecol, transp);
|
|
glTranslatef(x, yy, 0);
|
|
const GLshort frame [] = {
|
|
0, 0,
|
|
w, 0,
|
|
w, h,
|
|
0, h
|
|
};
|
|
glVertexPointer(2, GL_SHORT, 0, frame);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glColor(backcol, transp);
|
|
const GLshort back [] = {
|
|
0 + line, 0 + line,
|
|
w - line, 0 + line,
|
|
w - line, h - line,
|
|
0 + line, h - line
|
|
};
|
|
glVertexPointer(2, GL_SHORT, 0, back);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glEnable(GL_TEXTURE_2D);
|
|
glPopMatrix();
|
|
}
|
|
|
|
void DrawBonusExt(int y, size_t numraces, size_t num) {
|
|
size_t maxtux = numraces * 3;
|
|
if (num > maxtux) return;
|
|
|
|
TVector2i bl, tr;
|
|
|
|
//TColor col1 = {0.3, 0.5, 0.7, 1};
|
|
TColor col2(0.45, 0.65, 0.85, 1);
|
|
//TColor col3 = {0.6, 0.8, 1.0, 1};
|
|
//TColor gold = {1, 1, 0, 1};
|
|
|
|
int lleft[3];
|
|
|
|
int framewidth = (int)numraces * 40 + 8;
|
|
int totalwidth = framewidth * 3 + 8;
|
|
int xleft = (Winsys.resolution.width - totalwidth) / 2;
|
|
lleft[0] = xleft;
|
|
lleft[1] = xleft + framewidth + 4;
|
|
lleft[2] = xleft + framewidth + framewidth + 8;
|
|
|
|
DrawFrameX(lleft[0], y, framewidth, 40, 1, col2, colBlack, 1);
|
|
DrawFrameX(lleft[1], y, framewidth, 40, 1, col2, colBlack, 1);
|
|
DrawFrameX(lleft[2], y, framewidth, 40, 1, col2, colBlack, 1);
|
|
if (param.use_papercut_font > 0) FT.SetSize(20);
|
|
else FT.SetSize(15);
|
|
bl.y = Winsys.resolution.height - y - 32 -4;
|
|
tr.y = Winsys.resolution.height - y - 0 -4;
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_TEXTURE_2D);
|
|
Tex.BindTex(TUXBONUS);
|
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
for (size_t i=0; i<maxtux; i++) {
|
|
size_t majr = (i/numraces);
|
|
size_t minr = i - majr * numraces;
|
|
if (majr > 2) majr = 2;
|
|
bl.x = lleft[majr] + (int)minr * 40 + 6;
|
|
tr.x = bl.x + 32;
|
|
|
|
// with tux outlines:
|
|
// if (i<num) bott = 0.5; else bott = 0.0;
|
|
// top = bott + 0.5;
|
|
if (i<num) {
|
|
float bott = 0.5;
|
|
float top = 1.0;
|
|
|
|
const GLfloat tex[] = {
|
|
0, bott,
|
|
1, bott,
|
|
1, top,
|
|
0, top
|
|
};
|
|
const GLshort vtx[] = {
|
|
bl.x, bl.y,
|
|
tr.x, bl.y,
|
|
tr.x, tr.y,
|
|
bl.x, tr.y
|
|
};
|
|
glVertexPointer(2, GL_SHORT, 0, vtx);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, tex);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
}
|
|
}
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void DrawCursor() {
|
|
Tex.Draw(MOUSECURSOR, cursor_pos.x, cursor_pos.y,
|
|
CURSOR_SIZE * (double)Winsys.resolution.width / 14000);
|
|
}
|
|
|
|
|
|
// ------------------ Main GUI functions ---------------------------------------------
|
|
|
|
void DrawGUI() {
|
|
for (size_t i = 0; i < Widgets.size(); i++)
|
|
if (Widgets[i]->GetVisible())
|
|
Widgets[i]->Draw();
|
|
if (param.ice_cursor)
|
|
DrawCursor();
|
|
}
|
|
|
|
TWidget* ClickGUI(int x, int y) {
|
|
TWidget* clicked = NULL;
|
|
for (size_t i = 0; i < Widgets.size(); i++)
|
|
if (Widgets[i]->Click(x, y))
|
|
clicked = Widgets[i];
|
|
return clicked;
|
|
}
|
|
|
|
static int focussed = -1;
|
|
TWidget* MouseMoveGUI(int x, int y) {
|
|
if (x != 0 || y != 0) {
|
|
focussed = -1;
|
|
for (size_t i = 0; i < Widgets.size(); i++) {
|
|
Widgets[i]->MouseMove(cursor_pos.x, cursor_pos.y);
|
|
if (Widgets[i]->focussed())
|
|
focussed = (int)i;
|
|
}
|
|
}
|
|
if (focussed == -1)
|
|
return 0;
|
|
|
|
return Widgets[focussed];
|
|
}
|
|
|
|
TWidget* KeyGUI(unsigned int key, unsigned int mod, bool released) {
|
|
if (!released) {
|
|
switch (key) {
|
|
case SDLK_TAB:
|
|
IncreaseFocus();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (focussed == -1)
|
|
return 0;
|
|
Widgets[focussed]->Key(key, mod, released);
|
|
return Widgets[focussed];
|
|
}
|
|
|
|
void SetFocus(TWidget* widget) {
|
|
if (!widget)
|
|
focussed = -1;
|
|
else
|
|
for (int i = 0; i < (int)Widgets.size(); i++)
|
|
if (Widgets[i] == widget) {
|
|
focussed = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void IncreaseFocus() {
|
|
if (focussed >= 0)
|
|
Widgets[focussed]->focus = false;
|
|
|
|
focussed++;
|
|
if (focussed >= (int)Widgets.size())
|
|
focussed = 0;
|
|
int end = focussed;
|
|
// Select only active widgets
|
|
do {
|
|
if (Widgets[focussed]->GetActive())
|
|
break;
|
|
|
|
focussed++;
|
|
if (focussed >= (int)Widgets.size())
|
|
focussed = 0;
|
|
} while (end != focussed);
|
|
|
|
if (focussed >= 0)
|
|
Widgets[focussed]->focus = true;
|
|
}
|
|
void DecreaseFocus() {
|
|
if (focussed >= 0)
|
|
Widgets[focussed]->focus = false;
|
|
|
|
if (focussed > 0)
|
|
focussed--;
|
|
else
|
|
focussed = (int)Widgets.size()-1;
|
|
int end = focussed;
|
|
// Select only active widgets
|
|
do {
|
|
if (Widgets[focussed]->GetActive())
|
|
break;
|
|
|
|
if (focussed > 0)
|
|
focussed--;
|
|
else
|
|
focussed = (int)Widgets.size()-1;
|
|
} while (end != focussed);
|
|
|
|
if (focussed >= 0)
|
|
Widgets[focussed]->focus = true;
|
|
}
|
|
|
|
void ResetGUI() {
|
|
for (size_t i = 0; i < Widgets.size(); i++)
|
|
delete Widgets[i];
|
|
Widgets.clear();
|
|
focussed = 0;
|
|
}
|
|
|
|
// ------------------ new ---------------------------------------------
|
|
|
|
int AutoYPosN(double percent) {
|
|
double hh = (double)Winsys.resolution.height;
|
|
double po = hh * percent / 100;
|
|
return (int)(po);
|
|
}
|
|
|
|
TArea AutoAreaN(double top_perc, double bott_perc, int w) {
|
|
TArea res;
|
|
res.top = AutoYPosN(top_perc);
|
|
res.bottom = AutoYPosN(bott_perc);
|
|
if (w > Winsys.resolution.width) w = Winsys.resolution.width;
|
|
res.left = (Winsys.resolution.width - w) / 2;
|
|
res.right = Winsys.resolution.width - res.left;
|
|
return res;
|
|
}
|