155 lines
4.3 KiB
C++
155 lines
4.3 KiB
C++
/*
|
|
Copyright 2013 Peter Nelson
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
#include <pugl/pugl.h>
|
|
#include "pui.h"
|
|
|
|
Container::~Container()
|
|
{
|
|
std::list<Widget *>::iterator it;
|
|
for (it = children.begin(); it != children.end(); ++it) {
|
|
delete *it;
|
|
}
|
|
}
|
|
|
|
void Container::OnPaint(const PUi *pui) const
|
|
{
|
|
if (this->back) {
|
|
int t = this->back == 1 ? TEX_BACKTILE : TEX_BACKTILE2;
|
|
float tw = (float)w / pui->w[t];
|
|
float th = (float)h / pui->h[t];
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, pui->tex[t]);
|
|
glBegin(GL_QUADS);
|
|
glColor4f(colour.r, colour.g, colour.b, colour.a);
|
|
glTexCoord2f(.0, .0);
|
|
glVertex2f( x, y);
|
|
glTexCoord2f(.0, th);
|
|
glVertex2f( x, h + y);
|
|
glTexCoord2f(tw, th);
|
|
glVertex2f(w + x, h + y);
|
|
glTexCoord2f(tw, .0);
|
|
glVertex2f(w + x, y);
|
|
glEnd();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, pui->tex[TEX_BACKGLOW]);
|
|
glBegin(GL_QUADS);
|
|
glColor4f(colour.r, colour.g, colour.b, colour.a * 0.3f);
|
|
glTexCoord2f(.0, .0);
|
|
glVertex2f( x, y);
|
|
glTexCoord2f(.0, 1);
|
|
glVertex2f( x, h + y);
|
|
glTexCoord2f(1, 1);
|
|
glVertex2f(w + x, h + y);
|
|
glTexCoord2f(1, .0);
|
|
glVertex2f(w + x, y);
|
|
glEnd();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
} else if (this->colour.a) {
|
|
glBegin(GL_QUADS);
|
|
glColor4f(colour.r, colour.g, colour.b, colour.a);
|
|
glVertex2f( x, y);
|
|
glVertex2f( x, h + y);
|
|
glVertex2f(w + x, h + y);
|
|
glVertex2f(w + x, y);
|
|
glEnd();
|
|
}
|
|
|
|
if (this->frame.a) {
|
|
if (true) {
|
|
glBegin(GL_LINE_LOOP);
|
|
glColor4f(frame.r, frame.g, frame.b, frame.a);
|
|
glVertex2f( x + .5f, y + .5f);
|
|
glVertex2f( x + .5f, h + y - .5f);
|
|
glVertex2f(w + x - .5f, h + y - .5f);
|
|
glVertex2f(w + x - .5f, y + .5f);
|
|
glEnd();
|
|
} else {
|
|
glBegin(GL_LINE_LOOP);
|
|
glColor4f(1, 1, 1, frame.a);
|
|
glVertex2f( x + 1.5f, y + 1.5f);
|
|
glVertex2f( x + 1.5f, h + y - .5f);
|
|
glVertex2f(w + x - .5f, h + y - .5f);
|
|
glVertex2f(w + x - .5f, y + 1.5f);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
glColor4f(0, 0, 0, frame.a);
|
|
glVertex2f( x + .5f, y + .5f);
|
|
glVertex2f( x + .5f, h + y - 1.5f);
|
|
glVertex2f(w + x - 1.5f, h + y - 1.5f);
|
|
glVertex2f(w + x - 1.5f, y + .5f);
|
|
glEnd();
|
|
|
|
}
|
|
}
|
|
|
|
std::list<Widget *>::const_iterator it;
|
|
for (it = children.begin(); it != children.end(); ++it) {
|
|
(*it)->OnPaint(pui);
|
|
}
|
|
}
|
|
|
|
Widget *Container::GetWidget(int x, int y)
|
|
{
|
|
std::list<Widget *>::iterator it;
|
|
for (it = children.begin(); it != children.end(); ++it) {
|
|
if ((*it)->Hit(x, y)) return (*it)->GetWidget(x, y);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Widget *Container::GetWidget(uint32_t port)
|
|
{
|
|
if (this->port == port) return this;
|
|
|
|
std::list<Widget *>::iterator it;
|
|
for (it = children.begin(); it != children.end(); ++it) {
|
|
Widget *w = (*it)->GetWidget(port);
|
|
if (w) return w;
|
|
}
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void Container::Pack(Widget *widget)
|
|
{
|
|
this->children.push_back(widget);
|
|
}
|
|
|
|
void HBox::Pack(Widget *widget)
|
|
{
|
|
Widget *last = this->children.empty() ? NULL : this->children.back();
|
|
widget->x = (last == NULL) ? this->x : (last->x + last->w + this->padding);
|
|
widget->y = this->y;
|
|
widget->h = this->h;
|
|
if (widget->w < 0) widget->w = this->w - (widget->x - this->x);
|
|
if (this->x + this->w < widget->x + widget->w) this->w = widget->x + widget->w - this->x;
|
|
Container::Pack(widget);
|
|
}
|
|
|
|
void VBox::Pack(Widget *widget)
|
|
{
|
|
Widget *last = this->children.empty() ? NULL : this->children.back();
|
|
widget->x = this->x;
|
|
widget->y = (last == NULL) ? this->y : (last->y + last->h + this->padding);
|
|
widget->w = this->w;
|
|
if (widget->h < 0) widget->h = this->h - (widget->y - this->y);
|
|
if (this->y + this->h < widget->y + widget->h) this->h = widget->y + widget->h - this->y;
|
|
Container::Pack(widget);
|
|
}
|