Widgets can now use borders + 2 memory leaks fixed found with valgrind within the Widget Manager's selection.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1677 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
122b22a77e
commit
1ebcbf4b7c
144
src/widget.cpp
144
src/widget.cpp
@ -77,6 +77,7 @@ Widget::Widget
|
||||
m_width(WIDTH_), m_height(HEIGHT_),
|
||||
m_rect_list(0),
|
||||
m_round_corners(WGT_AREA_ALL),
|
||||
m_border_list(0),
|
||||
m_scroll_pos_x(0), m_scroll_pos_y(0),
|
||||
m_text_scale(1.0f)
|
||||
{
|
||||
@ -89,6 +90,12 @@ Widget::~Widget()
|
||||
{
|
||||
glDeleteLists(m_rect_list, 1);
|
||||
}
|
||||
|
||||
if(glIsList(m_border_list))
|
||||
{
|
||||
glDeleteLists(m_border_list, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -136,6 +143,10 @@ void Widget::update(const float DELTA)
|
||||
|
||||
if(glIsList(m_rect_list))
|
||||
{
|
||||
//m_enable_rect == false doesn't disables this chunk of code because
|
||||
//we still need to draw the rect into OpenGL's selection buffer even
|
||||
//if it's not visible
|
||||
|
||||
//FIXME: maybe there is some sort of stacking method to disable/enable
|
||||
//color masking
|
||||
if(!m_enable_rect)
|
||||
@ -165,6 +176,26 @@ void Widget::update(const float DELTA)
|
||||
std::cerr << "(Did you created the rect?)\n";
|
||||
}
|
||||
|
||||
if(glIsList(m_border_list))
|
||||
{
|
||||
if( m_enable_border )
|
||||
{
|
||||
glColor4fv(m_border_color);
|
||||
|
||||
//FIXME: I should probably revert the values to the defaults within the widget manager
|
||||
//(if glPushAttrib() doesn't)
|
||||
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glCallList(m_border_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Warning: widget tried to draw null border list.\n";
|
||||
std::cerr << "(Did you created the border?)\n";
|
||||
}
|
||||
|
||||
|
||||
if( m_enable_track )
|
||||
{
|
||||
if( m_track_num > (int)(track_manager->getTrackCount()) - 1)
|
||||
@ -553,31 +584,32 @@ bool Widget::createRect(int radius)
|
||||
}
|
||||
|
||||
//Calculate the number of quads each side should have. The algorithm
|
||||
//isn't based on pure logic, instead it's based on the perception of
|
||||
//roundness and some visual testing.
|
||||
//isn't based just on logic, since it went through visual testing to give
|
||||
//the perception of roundness.
|
||||
const int MIN_QUADS = 2;
|
||||
const float QUAD_RADIUS_RAISE = 0.413f;
|
||||
const int NUM_QUADS = MIN_QUADS + (int)(pow((float)radius, QUAD_RADIUS_RAISE));
|
||||
const int NUM_QUADS = MIN_QUADS + radius;
|
||||
|
||||
int i;
|
||||
|
||||
const int SMALLER_SIDE_LENGTH = m_height < m_width ? m_height / 2 : m_width / 2;
|
||||
const float BORDER_LENGTH = SMALLER_SIDE_LENGTH * m_border_percentage;
|
||||
|
||||
float inner_vertex [(NUM_QUADS + 1) * 2][3];
|
||||
float outer_vertex [(NUM_QUADS + 1) * 2][3];
|
||||
|
||||
const float HALF_WIDTH = m_width * 0.5f;
|
||||
const float HALF_HEIGHT = m_height * 0.5f;
|
||||
|
||||
glNewList(m_rect_list, GL_COMPILE);
|
||||
{
|
||||
//To create a rounded rectangle, we generate lines that are
|
||||
//progressively bigger, which are given as vertex points for each
|
||||
//quad.
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
{
|
||||
//These are used to center the widget; without centering, the
|
||||
//widget's 0,0 coordinates are at the lower left corner.
|
||||
float half_width = m_width * 0.5f;
|
||||
float half_height = m_height * 0.5f;
|
||||
|
||||
float angle;
|
||||
float circle_x, circle_y;
|
||||
float vertex_x, vertex_ya, vertex_yb;
|
||||
|
||||
//Draw the left side of a rectangle.
|
||||
//Draw the left side of the inside
|
||||
for (i = 0; i <= NUM_QUADS; ++i)
|
||||
{
|
||||
//To find the position in the X and Y axis of each point of
|
||||
@ -604,76 +636,120 @@ bool Widget::createRect(int radius)
|
||||
//position for the circle is dependant on rect; if a corner
|
||||
//wasn't given, then the y position is computed as if it was
|
||||
//for a rectangle without rounder corners.
|
||||
vertex_x = radius - circle_x;
|
||||
outer_vertex[i][0] = radius - circle_x;
|
||||
inner_vertex[i][0] = outer_vertex[i][0] + BORDER_LENGTH;
|
||||
|
||||
if( m_round_corners & WGT_AREA_NW )
|
||||
{
|
||||
vertex_ya = m_height + circle_y - radius;
|
||||
outer_vertex[i][1] = m_height + circle_y - radius;
|
||||
inner_vertex[i][1] = outer_vertex[i][1] - BORDER_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_ya = (float)m_height;
|
||||
outer_vertex[i][1] = m_height;
|
||||
inner_vertex[i][1] = outer_vertex[i][1] - BORDER_LENGTH;
|
||||
}
|
||||
|
||||
if( m_round_corners & WGT_AREA_SW )
|
||||
{
|
||||
vertex_yb = radius - circle_y;
|
||||
outer_vertex[i][2] = radius - circle_y;
|
||||
inner_vertex[i][2] = outer_vertex[i][2] + BORDER_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_yb = 0;
|
||||
outer_vertex[i][2] = 0;
|
||||
inner_vertex[i][2] = outer_vertex[i][2] + BORDER_LENGTH;
|
||||
}
|
||||
|
||||
glTexCoord2f(vertex_x / m_width, vertex_ya / m_height);
|
||||
glVertex2f(vertex_x - half_width, vertex_ya - half_height);
|
||||
glTexCoord2f(inner_vertex[i][0] / (float)m_width, inner_vertex[i][1] / (float)m_height);
|
||||
glVertex2f(inner_vertex[i][0] - HALF_WIDTH, inner_vertex[i][1] - HALF_HEIGHT);
|
||||
|
||||
glTexCoord2f(vertex_x / m_width, vertex_yb / m_height);
|
||||
glVertex2f(vertex_x - half_width, vertex_yb - half_height);
|
||||
glTexCoord2f(inner_vertex[i][0] / (float)m_width, inner_vertex[i][2] / (float)m_height);
|
||||
glVertex2f(inner_vertex[i][0] - HALF_WIDTH, inner_vertex[i][2] - HALF_HEIGHT);
|
||||
}
|
||||
|
||||
//Draw the right side of a rectangle
|
||||
for (i = 0; i <= NUM_QUADS; ++i)
|
||||
for (i = NUM_QUADS; i < NUM_QUADS * 2 + 1; ++i)
|
||||
{
|
||||
angle = 0.5f * M_PI * (float) i / (float) NUM_QUADS;
|
||||
angle = 0.5f * M_PI * (float) (i - NUM_QUADS) / (float) NUM_QUADS;
|
||||
|
||||
//By inverting the use of sin and cos we get corners that are
|
||||
//drawn from left to right instead of right to left
|
||||
circle_x = radius * sin(angle);
|
||||
circle_y = radius * cos(angle);
|
||||
|
||||
vertex_x = m_width - radius + circle_x;
|
||||
outer_vertex[i+1][0] = m_width - radius + circle_x;
|
||||
inner_vertex[i+1][0] = outer_vertex[i+1][0] - BORDER_LENGTH;
|
||||
|
||||
if( m_round_corners & WGT_AREA_NE )
|
||||
{
|
||||
vertex_ya = m_height + circle_y - radius;
|
||||
outer_vertex[i+1][1] = m_height - radius + circle_y;
|
||||
inner_vertex[i+1][1] = outer_vertex[i+1][1] - BORDER_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_ya = (float)m_height;
|
||||
outer_vertex[i+1][1] = m_height;
|
||||
inner_vertex[i+1][1] = outer_vertex[i+1][1] - BORDER_LENGTH;
|
||||
}
|
||||
|
||||
if( m_round_corners & WGT_AREA_SE )
|
||||
{
|
||||
vertex_yb = radius - circle_y;
|
||||
outer_vertex[i+1][2] = radius - circle_y;
|
||||
inner_vertex[i+1][2] = outer_vertex[i+1][2] + BORDER_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_yb = 0;
|
||||
outer_vertex[i+1][2] = 0;
|
||||
inner_vertex[i+1][2] = outer_vertex[i+1][2] + BORDER_LENGTH;
|
||||
}
|
||||
|
||||
glTexCoord2f(inner_vertex[i+1][0] / (float)m_width, inner_vertex[i+1][1] / (float)m_height);
|
||||
glVertex2f(inner_vertex[i+1][0] - HALF_WIDTH, inner_vertex[i+1][1] - HALF_HEIGHT);
|
||||
|
||||
glTexCoord2f(vertex_x / m_width, vertex_ya / m_height);
|
||||
glVertex2f(vertex_x - half_width, vertex_ya - half_height);
|
||||
|
||||
glTexCoord2f(vertex_x / m_width, vertex_yb / m_height);
|
||||
glVertex2f(vertex_x - half_width, vertex_yb - half_height);
|
||||
glTexCoord2f(inner_vertex[i+1][0] / (float)m_width, inner_vertex[i+1][2] / (float)m_height);
|
||||
glVertex2f(inner_vertex[i+1][0] - HALF_WIDTH, inner_vertex[i+1][2] - HALF_HEIGHT);
|
||||
}
|
||||
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glEndList();
|
||||
|
||||
|
||||
if(!glIsList(m_border_list))
|
||||
{
|
||||
m_border_list = glGenLists(1);
|
||||
if(m_border_list == 0)
|
||||
{
|
||||
std::cerr << "Error: could not create a widget's border list.\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
glNewList(m_border_list, GL_COMPILE);
|
||||
{
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
{
|
||||
for (i = NUM_QUADS * 2 + 1; i >= 0 ; --i)
|
||||
{
|
||||
glVertex2f(outer_vertex[i][0] - HALF_WIDTH, outer_vertex[i][1] - HALF_HEIGHT);
|
||||
glVertex2f(inner_vertex[i][0] - HALF_WIDTH, inner_vertex[i][1] - HALF_HEIGHT);
|
||||
}
|
||||
|
||||
for (i = 0; i <= NUM_QUADS * 2 + 1; ++i)
|
||||
{
|
||||
glVertex2f(outer_vertex[i][0] - HALF_WIDTH, outer_vertex[i][2] - HALF_HEIGHT);
|
||||
glVertex2f(inner_vertex[i][0] - HALF_WIDTH, inner_vertex[i][2] - HALF_HEIGHT);
|
||||
}
|
||||
|
||||
//Close the border
|
||||
glVertex2f(outer_vertex[NUM_QUADS * 2 + 1][0] - HALF_WIDTH, outer_vertex[NUM_QUADS * 2 + 1][1] - HALF_HEIGHT);
|
||||
glVertex2f(inner_vertex[NUM_QUADS * 2 + 1][0] - HALF_WIDTH, inner_vertex[NUM_QUADS * 2 + 1][1] - HALF_HEIGHT);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
glEndList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ extern const GLfloat WGT_LIGHT_TRANS_RED [4];
|
||||
extern const GLfloat WGT_LIGHT_TRANS_GREEN [4];
|
||||
extern const GLfloat WGT_LIGHT_TRANS_BLUE [4];
|
||||
|
||||
extern const GLfloat WGT_TRANSPARENT [4];
|
||||
extern const GLfloat WGT_TRANSPARENT [4];
|
||||
|
||||
|
||||
class Widget
|
||||
@ -136,11 +136,16 @@ class Widget
|
||||
/* Low level features. They are off by default. */
|
||||
bool m_enable_rect;
|
||||
GLuint m_rect_list; //A display list number that draws the rectangle with
|
||||
//possibly rounded corners.
|
||||
//possibly rounded corners.
|
||||
const GLfloat *m_rect_color; //This const cannot change the value it points to, but it
|
||||
//can change where it points to.
|
||||
WidgetArea m_round_corners;
|
||||
|
||||
bool m_enable_border;
|
||||
GLuint m_border_list; //Display list for the border
|
||||
float m_border_percentage;
|
||||
const GLfloat *m_border_color;
|
||||
|
||||
bool m_enable_texture;
|
||||
GLuint m_texture;
|
||||
|
||||
|
@ -82,6 +82,10 @@ bool WidgetManager::addWgt
|
||||
new_id.widget->m_enable_rect = m_default_show_rect;
|
||||
new_id.widget->m_rect_color = m_default_rect_color;
|
||||
|
||||
new_id.widget->m_enable_border = m_default_show_border;
|
||||
new_id.widget->m_border_percentage = m_default_border_percentage;
|
||||
new_id.widget->m_border_color = m_default_border_color;
|
||||
|
||||
new_id.widget->m_enable_texture = m_default_show_texture;
|
||||
new_id.widget->m_texture = m_default_texture;
|
||||
|
||||
@ -746,6 +750,19 @@ void WidgetManager::setInitialRectState
|
||||
m_default_rect_color = COLOR;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WidgetManager::setInitialBorderState
|
||||
(
|
||||
const bool SHOW,
|
||||
const int PERCENTAGE,
|
||||
const GLfloat* const COLOR
|
||||
)
|
||||
{
|
||||
m_default_show_border = SHOW;
|
||||
m_default_border_percentage = PERCENTAGE * 0.01;
|
||||
m_default_border_color = COLOR;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WidgetManager::setInitialTextureState
|
||||
(
|
||||
@ -821,6 +838,9 @@ void WidgetManager::restoreDefaultStates()
|
||||
m_default_show_rect = false;
|
||||
m_default_rect_round_corners = WGT_AREA_NONE;
|
||||
m_default_rect_color = WGT_TRANS_BLACK;
|
||||
m_default_show_border = false;
|
||||
m_default_border_percentage = 0.0;
|
||||
m_default_border_color = WGT_TRANS_WHITE;
|
||||
m_default_show_texture = false;
|
||||
m_default_texture = 0;
|
||||
m_default_show_text = false;
|
||||
@ -910,6 +930,69 @@ void WidgetManager::hideWgtRect(const int TOKEN)
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WidgetManager::setWgtBorderColor(const int TOKEN, const GLfloat* const COLOR)
|
||||
{
|
||||
const int ID = findId(TOKEN);
|
||||
if( ID != WGT_NONE ) m_widgets[ID].widget->m_border_color = COLOR;
|
||||
else
|
||||
{
|
||||
std::cerr << "WARNING: tried to change the border color of an " <<
|
||||
"unnamed widget with token " << TOKEN << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WidgetManager::setWgtBorderPercentage(const int TOKEN, const int PERCENTAGE)
|
||||
{
|
||||
if( PERCENTAGE > 100 )
|
||||
{
|
||||
std::cerr << "WARNING: tried to set the border's percentage of " <<
|
||||
"widget with token " << TOKEN << " to something bigger than " <<
|
||||
"100% \n";
|
||||
return;
|
||||
}
|
||||
else if( PERCENTAGE < 1 )
|
||||
{
|
||||
std::cerr << "WARNING: tried to set the border's percentage of " <<
|
||||
"widget with token " << TOKEN << " to something smaller than " <<
|
||||
"1% \n";
|
||||
return;
|
||||
}
|
||||
|
||||
const int ID = findId(TOKEN);
|
||||
if( ID != WGT_NONE ) m_widgets[ID].widget->m_border_percentage = PERCENTAGE * 0.01;
|
||||
else
|
||||
{
|
||||
std::cerr << "WARNING: tried to change the rect color of an " <<
|
||||
"unnamed widget with token " << TOKEN << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WidgetManager::showWgtBorder(const int TOKEN)
|
||||
{
|
||||
const int ID = findId(TOKEN);
|
||||
if( ID != WGT_NONE ) m_widgets[ID].widget->m_enable_border = true;
|
||||
else
|
||||
{
|
||||
std::cerr << "WARNING: tried to show the border of an unnamed widget "
|
||||
<< "with token " << TOKEN << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WidgetManager::hideWgtBorder(const int TOKEN)
|
||||
{
|
||||
const int ID = findId(TOKEN);
|
||||
if( ID != WGT_NONE ) m_widgets[ID].widget->m_enable_border = false;
|
||||
else
|
||||
{
|
||||
std::cerr << "WARNING: tried to hide the border of an unnamed widget "
|
||||
<< "with token " << TOKEN << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WidgetManager::setWgtTexture(const int TOKEN, const int TEXTURE)
|
||||
{
|
||||
@ -1346,7 +1429,7 @@ int WidgetManager::handlePointer(const int X, const int Y )
|
||||
|
||||
++position;
|
||||
}
|
||||
delete select_buffer;
|
||||
delete[] select_buffer;
|
||||
|
||||
if( m_widgets[nearest_id].token == m_selected_wgt_token )
|
||||
{
|
||||
@ -1357,7 +1440,7 @@ int WidgetManager::handlePointer(const int X, const int Y )
|
||||
return m_selected_wgt_token;
|
||||
}
|
||||
|
||||
delete select_buffer;
|
||||
delete[] select_buffer;
|
||||
return WGT_NONE;
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,10 @@ class WidgetManager
|
||||
bool m_default_rect_round_corners;
|
||||
const GLfloat *m_default_rect_color;
|
||||
|
||||
bool m_default_show_border;
|
||||
float m_default_border_percentage;
|
||||
const GLfloat *m_default_border_color;
|
||||
|
||||
bool m_default_show_texture;
|
||||
int m_default_texture;
|
||||
|
||||
@ -177,9 +181,23 @@ public:
|
||||
|
||||
/* On/off widget switch features. They are all disabled/hidden initially. */
|
||||
void setInitialActivationState( const bool ACTIVE);
|
||||
void setInitialRectState(const bool SHOW, const WidgetArea ROUND_CORNERS, const GLfloat* const COLOR );
|
||||
|
||||
void setInitialRectState
|
||||
(
|
||||
const bool SHOW,
|
||||
const WidgetArea ROUND_CORNERS,
|
||||
const GLfloat* const COLOR
|
||||
);
|
||||
|
||||
void setInitialTextureState(const bool SHOW, const int TEXTURE );
|
||||
|
||||
void setInitialBorderState
|
||||
(
|
||||
const bool SHOW,
|
||||
const int PERCENTAGE,
|
||||
const GLfloat* const COLOR
|
||||
);
|
||||
|
||||
void setInitialTextState
|
||||
(
|
||||
const bool SHOW,
|
||||
@ -222,6 +240,11 @@ public:
|
||||
void showWgtRect(const int TOKEN);
|
||||
void hideWgtRect(const int TOKEN);
|
||||
|
||||
void setWgtBorderColor(const int TOKEN, const GLfloat* const COLOR);
|
||||
void setWgtBorderPercentage(const int TOKEN, const int PERCENTAGE);
|
||||
void showWgtBorder(const int TOKEN);
|
||||
void hideWgtBorder(const int TOKEN);
|
||||
|
||||
void setWgtTexture(const int TOKEN, const int TEXTURE);
|
||||
void showWgtTexture(const int TOKEN);
|
||||
void hideWgtTexture(const int TOKEN);
|
||||
|
Loading…
x
Reference in New Issue
Block a user