Ran fixtabs to enforce four space tabs

This commit is contained in:
Robert Osfield 2008-08-18 11:17:44 +00:00
parent 9c8e44659f
commit 0b39044666
15 changed files with 2295 additions and 2295 deletions

View File

@ -22,173 +22,173 @@ _lastAdd (box._lastAdd) {
// TODO: Here's something to consider! If we resize the box by 1 every time, only the
// first resizable Widget will continue to get larger. This is really silly.
void Box::_resizeImplementation(point_type w, point_type h) {
// Get the number of Widgets that agree to fill. Also perfom some casting to integers
// in case we're being request to resize with pixel perfection.
point_type numFill = _getNumFill();
int iw = static_cast<int>(w);
int ih = static_cast<int>(h);
int inumFill = static_cast<int>(numFill);
int wrem = 0;
int hrem = 0;
// Get the number of Widgets that agree to fill. Also perfom some casting to integers
// in case we're being request to resize with pixel perfection.
point_type numFill = _getNumFill();
int iw = static_cast<int>(w);
int ih = static_cast<int>(h);
int inumFill = static_cast<int>(numFill);
int wrem = 0;
int hrem = 0;
// If we have some widgets that fill, use these variables to keep a running count
// of what needs to be added.
if(inumFill) {
wrem = iw % inumFill;
hrem = ih % inumFill;
}
// If we have some widgets that fill, use these variables to keep a running count
// of what needs to be added.
if(inumFill) {
wrem = iw % inumFill;
hrem = ih % inumFill;
}
// If we have any widgets that agree to fill and there has been an honest resize
// request, handle it here. The first case handles resizes where we have AT LEAST
// as many pixels to fill as we have objects.
if(numFill > 0.0f && (w != 0.0f || h != 0.0f)) {
unsigned int cur = 0;
// If we have any widgets that agree to fill and there has been an honest resize
// request, handle it here. The first case handles resizes where we have AT LEAST
// as many pixels to fill as we have objects.
if(numFill > 0.0f && (w != 0.0f || h != 0.0f)) {
unsigned int cur = 0;
for(Iterator i = begin(); i != end(); i++) if(i->valid() && i->get()->canFill()) {
point_type addWidth = 0.0f;
point_type addHeight = 0.0f;
for(Iterator i = begin(); i != end(); i++) if(i->valid() && i->get()->canFill()) {
point_type addWidth = 0.0f;
point_type addHeight = 0.0f;
// If our last added-to Widget was the last one, reset it to 0.
if(_lastAdd >= size()) _lastAdd = 0;
// If our last added-to Widget was the last one, reset it to 0.
if(_lastAdd >= size()) _lastAdd = 0;
// We EVENLY give any remaining space to all fillable Widgets. In the
// future we may want to be able to specify a fill "percent", which
// would be some portion of the total available space.
if(_boxType == HORIZONTAL) {
if(w) {
addWidth += static_cast<point_type>(iw / inumFill);
// We EVENLY give any remaining space to all fillable Widgets. In the
// future we may want to be able to specify a fill "percent", which
// would be some portion of the total available space.
if(_boxType == HORIZONTAL) {
if(w) {
addWidth += static_cast<point_type>(iw / inumFill);
if(cur >= _lastAdd && wrem) {
_lastAdd++;
addWidth++;
wrem--;
}
}
if(cur >= _lastAdd && wrem) {
_lastAdd++;
addWidth++;
wrem--;
}
}
if(h) addHeight += h;
}
if(h) addHeight += h;
}
else {
if(w) addWidth += w;
else {
if(w) addWidth += w;
if(h) {
addHeight += static_cast<point_type>(ih / inumFill);
if(h) {
addHeight += static_cast<point_type>(ih / inumFill);
if(cur >= _lastAdd && hrem) {
_lastAdd++;
addHeight++;
hrem--;
}
}
}
if(cur >= _lastAdd && hrem) {
_lastAdd++;
addHeight++;
hrem--;
}
}
}
if(addWidth != 0.0f) i->get()->addWidth(addWidth);
if(addWidth != 0.0f) i->get()->addWidth(addWidth);
if(addHeight != 0.0f) i->get()->addHeight(addHeight);
if(addHeight != 0.0f) i->get()->addHeight(addHeight);
cur++;
}
}
cur++;
}
}
// Get the width and height of our largest widgets; these values take
// into account the padding, and will be affected by any resizing that occured above.
point_type maxWidth = _getMaxWidgetWidthTotal();
point_type maxHeight = _getMaxWidgetHeightTotal();
// Get the width and height of our largest widgets; these values take
// into account the padding, and will be affected by any resizing that occured above.
point_type maxWidth = _getMaxWidgetWidthTotal();
point_type maxHeight = _getMaxWidgetHeightTotal();
// Create counters for the various offsets as we position Widgets.
point_type xoff = 0.0f;
point_type yoff = 0.0f;
point_type xadd = 0.0f;
point_type yadd = 0.0f;
// Create counters for the various offsets as we position Widgets.
point_type xoff = 0.0f;
point_type yoff = 0.0f;
point_type xadd = 0.0f;
point_type yadd = 0.0f;
for(Iterator i = begin(); i != end(); i++) {
Widget* widget = i->get();
for(Iterator i = begin(); i != end(); i++) {
Widget* widget = i->get();
// This positioning works by setting each Widget's unmodified origin and then
// letting Window::_positionWidget calculate the padding/fill.
if(_boxType == HORIZONTAL) {
// First, lets set it to the proper x offset, ignoring any padding.
widget->setOrigin(xoff, 0.0f);
// This positioning works by setting each Widget's unmodified origin and then
// letting Window::_positionWidget calculate the padding/fill.
if(_boxType == HORIZONTAL) {
// First, lets set it to the proper x offset, ignoring any padding.
widget->setOrigin(xoff, 0.0f);
// Immediately reset our xoff for the next iteration.
if(_uniform) {
_positionWidget(widget, maxWidth, maxHeight);
// Immediately reset our xoff for the next iteration.
if(_uniform) {
_positionWidget(widget, maxWidth, maxHeight);
xadd = maxWidth;
}
xadd = maxWidth;
}
else {
_positionWidget(widget, widget->getWidthTotal(), maxHeight);
else {
_positionWidget(widget, widget->getWidthTotal(), maxHeight);
xadd = widget->getWidthTotal();
}
}
xadd = widget->getWidthTotal();
}
}
else {
widget->setOrigin(0.0f, yoff);
else {
widget->setOrigin(0.0f, yoff);
if(_uniform) {
_positionWidget(widget, maxWidth, maxHeight);
if(_uniform) {
_positionWidget(widget, maxWidth, maxHeight);
yadd = maxHeight;
}
yadd = maxHeight;
}
else {
_positionWidget(widget, maxWidth, widget->getHeightTotal());
else {
_positionWidget(widget, maxWidth, widget->getHeightTotal());
yadd = widget->getHeightTotal();
}
}
yadd = widget->getHeightTotal();
}
}
xoff += xadd;
yoff += yadd;
}
xoff += xadd;
yoff += yadd;
}
}
Window::Sizes Box::_getWidthImplementation() const {
// The width of a horizontal box is all of the widgets added together.
if(_boxType == HORIZONTAL) {
// If we're a uniformly sized box, our width is our largest width plus our
// largest padding, multiplied times the number of widgets. Our minimum width
// is the size of the largest minWidth times the number of widgets.
if(_uniform) return Sizes(
_getMaxWidgetWidthTotal() * size(),
_getMaxWidgetMinWidthTotal() * size()
);
// The width of a horizontal box is all of the widgets added together.
if(_boxType == HORIZONTAL) {
// If we're a uniformly sized box, our width is our largest width plus our
// largest padding, multiplied times the number of widgets. Our minimum width
// is the size of the largest minWidth times the number of widgets.
if(_uniform) return Sizes(
_getMaxWidgetWidthTotal() * size(),
_getMaxWidgetMinWidthTotal() * size()
);
// Othweriwse, our width is all of the widths added together, and our minWidth
// is all of the minWidths added together.
else return Sizes(
_accumulate<Plus>(&Widget::getWidthTotal),
_accumulate<Plus>(&Widget::getMinWidthTotal)
);
}
// Othweriwse, our width is all of the widths added together, and our minWidth
// is all of the minWidths added together.
else return Sizes(
_accumulate<Plus>(&Widget::getWidthTotal),
_accumulate<Plus>(&Widget::getMinWidthTotal)
);
}
// If we're a vertical Box, our width is the width of the larget Widget in the group.
// Our minWidth is the largest minWidth of the Widgets in the group.
else return Sizes(
_getMaxWidgetWidthTotal(),
_getMaxWidgetMinWidthTotal()
);
// If we're a vertical Box, our width is the width of the larget Widget in the group.
// Our minWidth is the largest minWidth of the Widgets in the group.
else return Sizes(
_getMaxWidgetWidthTotal(),
_getMaxWidgetMinWidthTotal()
);
}
Window::Sizes Box::_getHeightImplementation() const {
if(_boxType == VERTICAL) {
if(_uniform) return Sizes(
_getMaxWidgetHeightTotal() * size(),
_getMaxWidgetMinHeightTotal() * size()
);
else return Sizes(
_accumulate<Plus>(&Widget::getHeightTotal),
_accumulate<Plus>(&Widget::getMinHeightTotal)
);
}
if(_boxType == VERTICAL) {
if(_uniform) return Sizes(
_getMaxWidgetHeightTotal() * size(),
_getMaxWidgetMinHeightTotal() * size()
);
else return Sizes(
_accumulate<Plus>(&Widget::getHeightTotal),
_accumulate<Plus>(&Widget::getMinHeightTotal)
);
}
else return Sizes(
_getMaxWidgetHeightTotal(),
_getMaxWidgetMinHeightTotal()
);
else return Sizes(
_getMaxWidgetHeightTotal(),
_getMaxWidgetMinHeightTotal()
);
}
}

View File

@ -14,19 +14,19 @@ Window(canvas, co) {
}
void Canvas::_resizeImplementation(point_type w, point_type h) {
// A Canvas has no layout, so it doesn't really know how to honor a resize
// request. :) The best I could do here is store the differences and add them
// later to the calls to getWidth/getHeight.
// A Canvas has no layout, so it doesn't really know how to honor a resize
// request. :) The best I could do here is store the differences and add them
// later to the calls to getWidth/getHeight.
}
bool Canvas::addWidget(Widget* widget, point_type x, point_type y) {
if(Window::addWidget(widget)) {
widget->setOrigin(x, y);
if(Window::addWidget(widget)) {
widget->setOrigin(x, y);
return true;
}
return true;
}
return false;
return false;
}
}

View File

@ -8,29 +8,29 @@
namespace osgWidget {
std::string Frame::cornerToString(CORNER c) {
if(c == CORNER_LOWER_LEFT) return "CornerLowerLeft";
if(c == CORNER_LOWER_LEFT) return "CornerLowerLeft";
else if(c == CORNER_LOWER_RIGHT) return "CornerLowerRight";
else if(c == CORNER_LOWER_RIGHT) return "CornerLowerRight";
else if(c == CORNER_UPPER_RIGHT) return "CornerUpperRight";
else if(c == CORNER_UPPER_RIGHT) return "CornerUpperRight";
else return "CornerUpperLeft";
else return "CornerUpperLeft";
}
std::string Frame::borderToString(BORDER b) {
if(b == BORDER_LEFT) return "BorderLeft";
if(b == BORDER_LEFT) return "BorderLeft";
else if(b == BORDER_RIGHT) return "BorderRight";
else if(b == BORDER_RIGHT) return "BorderRight";
else if(b == BORDER_TOP) return "BorderTop";
else if(b == BORDER_TOP) return "BorderTop";
else return "BorderBottom";
else return "BorderBottom";
}
Frame::Corner::Corner(CORNER corner, point_type width, point_type height):
Widget (cornerToString(corner), width, height),
_corner (corner) {
setEventMask(EVENT_MASK_MOUSE_DRAG);
setEventMask(EVENT_MASK_MOUSE_DRAG);
}
Frame::Corner::Corner(const Corner& corner, const osg::CopyOp& co):
@ -39,54 +39,54 @@ _corner (corner._corner) {
}
bool Frame::Corner::mouseDrag(double x, double y, WindowManager* wm) {
Window* parent = getParent();
Window* parent = getParent();
if(!parent) return false;
if(!parent) return false;
if(wm->isInvertedY()) {
if(_corner == CORNER_UPPER_LEFT) {
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
}
if(wm->isInvertedY()) {
if(_corner == CORNER_UPPER_LEFT) {
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
}
else if(_corner == CORNER_UPPER_RIGHT) {
if(parent->resizeAdd(x, -y)) parent->addY(y);
}
else if(_corner == CORNER_UPPER_RIGHT) {
if(parent->resizeAdd(x, -y)) parent->addY(y);
}
else if(_corner == CORNER_LOWER_RIGHT) parent->resizeAdd(x, y);
else if(_corner == CORNER_LOWER_RIGHT) parent->resizeAdd(x, y);
else {
if(parent->resizeAdd(-x, y)) parent->addX(x);
}
}
else {
if(parent->resizeAdd(-x, y)) parent->addX(x);
}
}
// These are basically flipped-around versions of the above routines; we
// do it this way to avoid lots of uncessary if tests.
else {
if(_corner == CORNER_UPPER_LEFT) {
if(parent->resizeAdd(-x, y)) parent->addX(x);
}
// These are basically flipped-around versions of the above routines; we
// do it this way to avoid lots of uncessary if tests.
else {
if(_corner == CORNER_UPPER_LEFT) {
if(parent->resizeAdd(-x, y)) parent->addX(x);
}
else if(_corner == CORNER_UPPER_RIGHT) parent->resizeAdd(x, y);
else if(_corner == CORNER_UPPER_RIGHT) parent->resizeAdd(x, y);
else if(_corner == CORNER_LOWER_RIGHT) {
if(parent->resizeAdd(x, -y)) parent->addY(y);
}
else if(_corner == CORNER_LOWER_RIGHT) {
if(parent->resizeAdd(x, -y)) parent->addY(y);
}
else {
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
}
}
else {
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
}
}
parent->update();
return true;
parent->update();
return true;
}
Frame::Border::Border(BORDER border, point_type width, point_type height):
Widget (borderToString(border), width, height),
_border (border) {
setCanFill(true);
setEventMask(EVENT_MASK_MOUSE_DRAG);
setCanFill(true);
setEventMask(EVENT_MASK_MOUSE_DRAG);
}
Frame::Border::Border(const Border& border, const osg::CopyOp& co):
@ -95,30 +95,30 @@ _border (border._border) {
}
bool Frame::Border::mouseDrag(double x, double y, WindowManager* wm) {
Window* parent = getParent();
Window* parent = getParent();
if(!parent) return false;
if(!parent) return false;
if(_border == BORDER_LEFT) {
if(parent->resizeAdd(-x, 0.0f)) parent->addX(x);
}
if(_border == BORDER_LEFT) {
if(parent->resizeAdd(-x, 0.0f)) parent->addX(x);
}
else if(_border == BORDER_RIGHT) parent->resizeAdd(x, 0.0f);
else if(_border == BORDER_RIGHT) parent->resizeAdd(x, 0.0f);
else if(_border == BORDER_TOP) parent->addOrigin(x, y);
else if(_border == BORDER_TOP) parent->addOrigin(x, y);
else {
// The only BORDER that inverted-Y affects is this...
if(wm->isInvertedY()) parent->resizeAdd(0.0f, y);
else {
// The only BORDER that inverted-Y affects is this...
if(wm->isInvertedY()) parent->resizeAdd(0.0f, y);
else {
if(parent->resizeAdd(0.0f, -y)) parent->addY(y);
}
}
else {
if(parent->resizeAdd(0.0f, -y)) parent->addY(y);
}
}
parent->update();
parent->update();
return true;
return true;
}
Frame::Frame(const std::string& name):
@ -130,122 +130,122 @@ Table(frame, co) {
}
Widget* Frame::_getCorner(CORNER c) const {
return const_cast<Widget*>(getByName(cornerToString(c)));
return const_cast<Widget*>(getByName(cornerToString(c)));
}
Widget* Frame::_getBorder(BORDER b) const {
return const_cast<Widget*>(getByName(borderToString(b)));
return const_cast<Widget*>(getByName(borderToString(b)));
}
void Frame::managed(WindowManager* wm) {
Window::managed(wm);
Window::managed(wm);
// Our Frame is created in an inverted-Y environment, so if this is the case
// just return here.
if(wm->isInvertedY()) return;
// Our Frame is created in an inverted-Y environment, so if this is the case
// just return here.
if(wm->isInvertedY()) return;
Corner* ll = getCorner(CORNER_LOWER_LEFT);
Corner* lr = getCorner(CORNER_LOWER_RIGHT);
Corner* ul = getCorner(CORNER_UPPER_LEFT);
Corner* ur = getCorner(CORNER_UPPER_RIGHT);
Border* t = getBorder(BORDER_TOP);
Border* b = getBorder(BORDER_BOTTOM);
Corner* ll = getCorner(CORNER_LOWER_LEFT);
Corner* lr = getCorner(CORNER_LOWER_RIGHT);
Corner* ul = getCorner(CORNER_UPPER_LEFT);
Corner* ur = getCorner(CORNER_UPPER_RIGHT);
Border* t = getBorder(BORDER_TOP);
Border* b = getBorder(BORDER_BOTTOM);
if(!ll || !lr || !ul || !ur || !t || !b) {
warn()
<< "One or more of your Corner/Border objects in the Frame ["
<< _name << "] are invalid; cannot invert orientation." << std::endl
;
if(!ll || !lr || !ul || !ur || !t || !b) {
warn()
<< "One or more of your Corner/Border objects in the Frame ["
<< _name << "] are invalid; cannot invert orientation." << std::endl
;
return;
}
return;
}
ll->setCornerAndName(CORNER_UPPER_LEFT);
lr->setCornerAndName(CORNER_UPPER_RIGHT);
ul->setCornerAndName(CORNER_LOWER_LEFT);
ur->setCornerAndName(CORNER_LOWER_RIGHT);
t->setBorderAndName(BORDER_BOTTOM);
b->setBorderAndName(BORDER_TOP);
ll->setCornerAndName(CORNER_UPPER_LEFT);
lr->setCornerAndName(CORNER_UPPER_RIGHT);
ul->setCornerAndName(CORNER_LOWER_LEFT);
ur->setCornerAndName(CORNER_LOWER_RIGHT);
t->setBorderAndName(BORDER_BOTTOM);
b->setBorderAndName(BORDER_TOP);
}
bool Frame::setWindow(Window* window) {
if(!window) return false;
if(!window) return false;
EmbeddedWindow* ew = getEmbeddedWindow();
EmbeddedWindow* ew = getEmbeddedWindow();
// If it's the first time setting the Window...
// if(!ew || !ew->getWindow()) return addWidget(window->embed(), 1, 1);
if(!ew) return addWidget(window->embed(), 1, 1);
// If it's the first time setting the Window...
// if(!ew || !ew->getWindow()) return addWidget(window->embed(), 1, 1);
if(!ew) return addWidget(window->embed(), 1, 1);
else return ew->setWindow(window);
else return ew->setWindow(window);
}
Frame* Frame::createSimpleFrame(
const std::string& name,
point_type cw,
point_type ch,
point_type w,
point_type h,
Frame* exFrame
const std::string& name,
point_type cw,
point_type ch,
point_type w,
point_type h,
Frame* exFrame
) {
Frame* frame = 0;
// Use an "existing frame" if we have it (for example, if you've in inherited from
// Frame and want to use this stuff.
if(!exFrame) frame = new Frame(name);
Frame* frame = 0;
// Use an "existing frame" if we have it (for example, if you've in inherited from
// Frame and want to use this stuff.
if(!exFrame) frame = new Frame(name);
else frame = exFrame;
frame->addWidget(new Corner(CORNER_UPPER_LEFT, cw, ch), 0, 0);
frame->addWidget(new Border(BORDER_TOP, w, ch), 0, 1);
frame->addWidget(new Corner(CORNER_UPPER_RIGHT, cw, ch), 0, 2);
frame->addWidget(new Border(BORDER_LEFT, cw, h), 1, 0);
frame->addWidget(new Border(BORDER_RIGHT, cw, h), 1, 2);
frame->addWidget(new Corner(CORNER_LOWER_LEFT, cw, ch), 2, 0);
frame->addWidget(new Border(BORDER_BOTTOM, w, ch), 2, 1);
frame->addWidget(new Corner(CORNER_LOWER_RIGHT, cw, ch), 2, 2);
else frame = exFrame;
frame->addWidget(new Corner(CORNER_UPPER_LEFT, cw, ch), 0, 0);
frame->addWidget(new Border(BORDER_TOP, w, ch), 0, 1);
frame->addWidget(new Corner(CORNER_UPPER_RIGHT, cw, ch), 0, 2);
frame->addWidget(new Border(BORDER_LEFT, cw, h), 1, 0);
frame->addWidget(new Border(BORDER_RIGHT, cw, h), 1, 2);
frame->addWidget(new Corner(CORNER_LOWER_LEFT, cw, ch), 2, 0);
frame->addWidget(new Border(BORDER_BOTTOM, w, ch), 2, 1);
frame->addWidget(new Corner(CORNER_LOWER_RIGHT, cw, ch), 2, 2);
EmbeddedWindow* ew = new EmbeddedWindow(name, w, h);
EmbeddedWindow* ew = new EmbeddedWindow(name, w, h);
ew->setCanFill(true);
ew->setCanFill(true);
frame->addWidget(ew, 1, 1);
frame->addWidget(ew, 1, 1);
return frame;
return frame;
}
Frame* Frame::createSimpleFrameWithSingleTexture(
const std::string& name,
const std::string& texture,
point_type tw,
point_type th,
point_type cw,
point_type ch,
point_type w,
point_type h,
Frame* exFrame
const std::string& name,
const std::string& texture,
point_type tw,
point_type th,
point_type cw,
point_type ch,
point_type w,
point_type h,
Frame* exFrame
) {
Frame* frame = 0;
Frame* frame = 0;
// The same as above...
if(!exFrame) frame = createSimpleFrame(name, cw, ch, w, h);
// The same as above...
if(!exFrame) frame = createSimpleFrame(name, cw, ch, w, h);
else frame = createSimpleFrame(name, cw, ch, w, h, exFrame);
else frame = createSimpleFrame(name, cw, ch, w, h, exFrame);
for(unsigned int i = 0; i < 9; i++) frame->getObjects()[i]->setImage(texture);
for(unsigned int i = 0; i < 9; i++) frame->getObjects()[i]->setImage(texture);
frame->getByRowCol(0, 0)->setTexCoordRegion(0.0f, th - ch, cw, ch);
frame->getByRowCol(0, 1)->setTexCoordRegion(cw, th - ch, tw - (cw * 2.0f), ch);
frame->getByRowCol(0, 2)->setTexCoordRegion(tw - cw, th - ch, cw, ch);
frame->getByRowCol(1, 0)->setTexCoordRegion(0.0f, ch, cw, th - (ch * 2.0f));
frame->getByRowCol(1, 2)->setTexCoordRegion(tw - cw, ch, cw, th - (ch * 2.0f));
frame->getByRowCol(2, 0)->setTexCoordRegion(0.0f, 0.0f, cw, ch);
frame->getByRowCol(2, 1)->setTexCoordRegion(cw, 0.0f, tw - (cw * 2.0f), ch);
frame->getByRowCol(2, 2)->setTexCoordRegion(tw - cw, 0.0f, cw, ch);
frame->getByRowCol(0, 0)->setTexCoordRegion(0.0f, th - ch, cw, ch);
frame->getByRowCol(0, 1)->setTexCoordRegion(cw, th - ch, tw - (cw * 2.0f), ch);
frame->getByRowCol(0, 2)->setTexCoordRegion(tw - cw, th - ch, cw, ch);
frame->getByRowCol(1, 0)->setTexCoordRegion(0.0f, ch, cw, th - (ch * 2.0f));
frame->getByRowCol(1, 2)->setTexCoordRegion(tw - cw, ch, cw, th - (ch * 2.0f));
frame->getByRowCol(2, 0)->setTexCoordRegion(0.0f, 0.0f, cw, ch);
frame->getByRowCol(2, 1)->setTexCoordRegion(cw, 0.0f, tw - (cw * 2.0f), ch);
frame->getByRowCol(2, 2)->setTexCoordRegion(tw - cw, 0.0f, cw, ch);
frame->getEmbeddedWindow()->setTexCoordRegion(cw, ch, tw - (cw * 2.0f), th - (ch * 2.0f));
frame->getEmbeddedWindow()->setTexCoordRegion(cw, ch, tw - (cw * 2.0f), th - (ch * 2.0f));
return frame;
return frame;
}
}

View File

@ -16,161 +16,161 @@ _size (0),
_cursorIndex (0),
_maxSize (size),
_cursor (new Widget("cursor")) {
_text->setAlignment(osgText::Text::LEFT_BOTTOM_BASE_LINE);
_text->setKerningType(osgText::KERNING_NONE);
_text->setAlignment(osgText::Text::LEFT_BOTTOM_BASE_LINE);
_text->setKerningType(osgText::KERNING_NONE);
// Make the cursor un-copyable.
_cursor->setCanClone(false);
_cursor->setDataVariance(osg::Object::DYNAMIC);
_cursor->setColor(0.0f, 0.0f, 0.0f, 0.0f);
// Make the cursor un-copyable.
_cursor->setCanClone(false);
_cursor->setDataVariance(osg::Object::DYNAMIC);
_cursor->setColor(0.0f, 0.0f, 0.0f, 0.0f);
setEventMask(
// For showing/hiding the "cursor."
EVENT_MASK_FOCUS |
// For keypresses, obviously.
EVENT_MASK_KEY |
// For "click" focusing.
EVENT_MOUSE_PUSH
);
setEventMask(
// For showing/hiding the "cursor."
EVENT_MASK_FOCUS |
// For keypresses, obviously.
EVENT_MASK_KEY |
// For "click" focusing.
EVENT_MOUSE_PUSH
);
_offsets.resize(size, 0.0f);
_offsets.resize(size, 0.0f);
_text->getText().resize(size, ' ');
_text->update();
_text->getText().resize(size, ' ');
_text->update();
}
void Input::_calculateSize(const XYCoord& size) {
// An Input cannot currently set it's own size RELIABLY until the osgText implementation
// is dratiscally improved. I'm getting wildly crazy results. :(
// point_type height = size.y() > _cursor->getHeight() ? size.y() : _cursor->getHeight();
point_type width = size.x() + _cursor->getWidth();
point_type height = _cursor->getHeight();
// An Input cannot currently set it's own size RELIABLY until the osgText implementation
// is dratiscally improved. I'm getting wildly crazy results. :(
// point_type height = size.y() > _cursor->getHeight() ? size.y() : _cursor->getHeight();
point_type width = size.x() + _cursor->getWidth();
point_type height = _cursor->getHeight();
if(width > getWidth()) setWidth(osg::round(width));
if(width > getWidth()) setWidth(osg::round(width));
if(height > getHeight()) setHeight(osg::round(height));
if(height > getHeight()) setHeight(osg::round(height));
}
void Input::_calculateCursorOffsets() {
// Determine the "offset"
const osgText::Text::TextureGlyphQuadMap& tgqm = _text->getTextureGlyphQuadMap();
// Determine the "offset"
const osgText::Text::TextureGlyphQuadMap& tgqm = _text->getTextureGlyphQuadMap();
const osgText::Text::TextureGlyphQuadMap::const_iterator tgqmi = tgqm.begin();
const osgText::Text::GlyphQuads& gq = tgqmi->second;
const osgText::Text::TextureGlyphQuadMap::const_iterator tgqmi = tgqm.begin();
const osgText::Text::GlyphQuads& gq = tgqmi->second;
point_type accum = 0.0f;
point_type accum = 0.0f;
std::ostream& os = warn() << "_offsets[ ";
for(unsigned int i = 0; i < _maxSize; i++) {
osg::Vec2 ul = gq.getCoords()[0 + (i * 4)];
osg::Vec2 ll = gq.getCoords()[1 + (i * 4)];
osg::Vec2 lr = gq.getCoords()[2 + (i * 4)];
osg::Vec2 ur = gq.getCoords()[3 + (i * 4)];
accum += osg::round(lr.x() - ll.x());
std::ostream& os = warn() << "_offsets[ ";
for(unsigned int i = 0; i < _maxSize; i++) {
osg::Vec2 ul = gq.getCoords()[0 + (i * 4)];
osg::Vec2 ll = gq.getCoords()[1 + (i * 4)];
osg::Vec2 lr = gq.getCoords()[2 + (i * 4)];
osg::Vec2 ur = gq.getCoords()[3 + (i * 4)];
accum += osg::round(lr.x() - ll.x());
_offsets[i] = accum;
_offsets[i] = accum;
os << _offsets[i] << " (" << static_cast<char>(_text->getText()[i]) << ") ";
}
os << _offsets[i] << " (" << static_cast<char>(_text->getText()[i]) << ") ";
}
os << "]" << std::endl;
os << "]" << std::endl;
}
bool Input::focus(WindowManager*) {
_cursor->setColor(1.0f, 1.0f, 1.0f, 0.5f);
_cursor->setColor(1.0f, 1.0f, 1.0f, 0.5f);
return true;
return true;
}
bool Input::unfocus(WindowManager*) {
_cursor->setColor(0.0f, 0.0f, 0.0f, 0.0f);
_cursor->setColor(0.0f, 0.0f, 0.0f, 0.0f);
return true;
return true;
}
void Input::parented(Window* parent) {
Label::parented(parent);
Label::parented(parent);
_cursor->setSize(2.0f, _text->getCharacterHeight());
_cursor->setSize(2.0f, _text->getCharacterHeight());
if(_cursorIndex) parent->getGeode()->setDrawable(_cursorIndex, _cursor.get());
if(_cursorIndex) parent->getGeode()->setDrawable(_cursorIndex, _cursor.get());
else _cursorIndex = parent->addDrawableAndGetIndex(_cursor.get());
else _cursorIndex = parent->addDrawableAndGetIndex(_cursor.get());
}
void Input::positioned() {
point_type ln = static_cast<point_type>(_text->getLineCount());
point_type ln = static_cast<point_type>(_text->getLineCount());
ln = ln == 0.0f ? 1.0f : ln;
ln = ln == 0.0f ? 1.0f : ln;
point_type th =
(_text->getCharacterHeight() * ln) +
(_text->getLineSpacing() * (ln - 1.0f))
;
point_type th =
(_text->getCharacterHeight() * ln) +
(_text->getLineSpacing() * (ln - 1.0f))
;
point_type x = getX() + _xoff;
point_type y = getY() + th + _yoff;
point_type x = getX() + _xoff;
point_type y = getY() + th + _yoff;
// XYCoord size = getTextSize();
// XYCoord size = getTextSize();
_text->setPosition(osg::Vec3(x, y, _calculateZ(LAYER_MIDDLE)));
point_type xoffset = _index > 0 ? _offsets[_index - 1] : 0.0f;
_text->setPosition(osg::Vec3(x, y, _calculateZ(LAYER_MIDDLE)));
point_type xoffset = _index > 0 ? _offsets[_index - 1] : 0.0f;
_cursor->setOrigin(x + xoffset + 1.0f, y - _cursor->getHeight() + 1.0f);
_cursor->setZ(_calculateZ(LAYER_MIDDLE));
_cursor->setOrigin(x + xoffset + 1.0f, y - _cursor->getHeight() + 1.0f);
_cursor->setZ(_calculateZ(LAYER_MIDDLE));
}
bool Input::keyUp(int key, int mask, WindowManager*) {
return false;
return false;
}
bool Input::keyDown(int key, int mask, WindowManager*) {
/*
osgText::String& s = _text->getText();
/*
osgText::String& s = _text->getText();
if(key == osgGA::GUIEventAdapter::KEY_BackSpace) {
if(_index >= 1) {
// s.erase(s.begin() + (_index - 1));
if(key == osgGA::GUIEventAdapter::KEY_BackSpace) {
if(_index >= 1) {
// s.erase(s.begin() + (_index - 1));
s[_index - 1] = ' ';
s[_index - 1] = ' ';
_text->update();
_calculateCursorOffsets();
_text->update();
_calculateCursorOffsets();
_index--;
}
}
_index--;
}
}
else {
if(key > 255 || _index >= _maxSize) return false;
else {
if(key > 255 || _index >= _maxSize) return false;
// else if(_index < s.size()) s.insert(s.begin() + _index, key);
// else if(_index == s.size()) s.push_back(key);
// else if(_index < s.size()) s.insert(s.begin() + _index, key);
// else if(_index == s.size()) s.push_back(key);
s[_index] = key;
_text->update();
_calculateCursorOffsets();
s[_index] = key;
_text->update();
_calculateCursorOffsets();
_index++;
}
_index++;
}
// _text->update();
// _text->update();
_calculateSize(getTextSize());
_calculateSize(getTextSize());
getParent()->resize();
*/
getParent()->resize();
*/
warn() << "Input is disabled until someone can help me understand how to use osgText; sorry..." << std::endl;
warn() << "Input is disabled until someone can help me understand how to use osgText; sorry..." << std::endl;
return false;
return false;
}
}

View File

@ -11,130 +11,130 @@ Label::Label(const std::string& name, const std::string& label):
Widget (name, 0, 0),
_textIndex (0),
_text (new osgText::Text()) {
_text->setText(label);
_text->setAlignment(osgText::Text::LEFT_BOTTOM);
_text->setDataVariance(osg::Object::DYNAMIC);
_text->setText(label);
_text->setAlignment(osgText::Text::LEFT_BOTTOM);
_text->setDataVariance(osg::Object::DYNAMIC);
// TODO: Make a patch for this!
// If you're wondering why we don't use this let me explain...
//
// _text->setAlignment(osgText::Text::CENTER_CENTER);
//
// When you set the position of an osgText::Text object which has a CENTER_CENTER
// alignment, the internal implementation of osgText may give it values that have
// a "decimal" portion, which is NO GOOD on orthographic 2D displays where we
// want "pixel perfect" ratios. Thus, until I can remedy this internally with
// osgText::Text, I will need to calculate the center myself.
// TODO: Make a patch for this!
// If you're wondering why we don't use this let me explain...
//
// _text->setAlignment(osgText::Text::CENTER_CENTER);
//
// When you set the position of an osgText::Text object which has a CENTER_CENTER
// alignment, the internal implementation of osgText may give it values that have
// a "decimal" portion, which is NO GOOD on orthographic 2D displays where we
// want "pixel perfect" ratios. Thus, until I can remedy this internally with
// osgText::Text, I will need to calculate the center myself.
setColor(0.0f, 0.0f, 0.0f, 0.0f);
setColor(0.0f, 0.0f, 0.0f, 0.0f);
}
Label::Label(const Label& label, const osg::CopyOp& co):
Widget (label, co),
_textIndex (label._textIndex) {
_text = new osgText::Text(*label._text, co);
_text = new osgText::Text(*label._text, co);
}
void Label::_calculateSize(const XYCoord& size) {
if(size.x() && size.y()) setMinimumSize(size.x(), size.y());
if(size.x() && size.y()) setMinimumSize(size.x(), size.y());
if(getWidth() < size.x()) setWidth(size.x());
if(getHeight() < size.y()) setHeight(size.y());
if(getWidth() < size.x()) setWidth(size.x());
if(getHeight() < size.y()) setHeight(size.y());
}
// TODO: This will almost certainly get out of sync. :(
void Label::parented(Window* parent) {
// If we've been cloned, use the index of the old text Drawable.
if(_textIndex) parent->getGeode()->setDrawable(_textIndex, _text.get());
// If we've been cloned, use the index of the old text Drawable.
if(_textIndex) parent->getGeode()->setDrawable(_textIndex, _text.get());
// Otherwise, add it as new.
else _textIndex = parent->addDrawableAndGetIndex(_text.get());
// Otherwise, add it as new.
else _textIndex = parent->addDrawableAndGetIndex(_text.get());
}
void Label::unparented(Window* parent) {
if(_textIndex) parent->getGeode()->removeDrawable(_text.get());
if(_textIndex) parent->getGeode()->removeDrawable(_text.get());
_textIndex = 0;
_textIndex = 0;
}
void Label::managed(WindowManager* wm) {
if(wm->isInvertedY()) {
// We rotate along our X axis, so we need to make sure and translate the
// text later to preserve centering.
_text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
_text->setRotation(osg::Quat(
osg::DegreesToRadians(180.0f),
osg::Vec3(1.0f, 0.0f, 0.0f)
));
}
if(wm->isInvertedY()) {
// We rotate along our X axis, so we need to make sure and translate the
// text later to preserve centering.
_text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
_text->setRotation(osg::Quat(
osg::DegreesToRadians(180.0f),
osg::Vec3(1.0f, 0.0f, 0.0f)
));
}
}
void Label::positioned() {
XYCoord size = getTextSize();
point_type x = osg::round(((getWidth() - size.x()) / 2.0f) + getX());
point_type y = 0.0f;
XYCoord size = getTextSize();
point_type x = osg::round(((getWidth() - size.x()) / 2.0f) + getX());
point_type y = 0.0f;
if(getWindowManager() && getWindowManager()->isInvertedY()) y =
osg::round(((getHeight() - size.y()) / 2.0f) + getY() + size.y())
;
if(getWindowManager() && getWindowManager()->isInvertedY()) y =
osg::round(((getHeight() - size.y()) / 2.0f) + getY() + size.y())
;
else y = osg::round(((getHeight() - size.y()) / 2.0f) + getY());
// These values are permisable with CENTER_CENTER mode is active.
// point_type x = round(getX() + (getWidth() / 2.0f));
// point_type y = round(getY() + (getHeight() / 2.0f));
/*
warn() << "Label widget size : " << getWidth() << " x " << getHeight() << std::endl;
warn() << "Label widget tsize: " << getWidthTotal() << " x " << getHeightTotal() << std::endl;
warn() << "Label XY coords : " << getX() << " x " << getY() << std::endl;
warn() << "Label BB in size : " << size.x() << " x " << size.y() << std::endl;
warn() << "Label xy position : " << x << " y " << y << std::endl;
warn() << "------------------------------------" << std::endl;
*/
else y = osg::round(((getHeight() - size.y()) / 2.0f) + getY());
// These values are permisable with CENTER_CENTER mode is active.
// point_type x = round(getX() + (getWidth() / 2.0f));
// point_type y = round(getY() + (getHeight() / 2.0f));
/*
warn() << "Label widget size : " << getWidth() << " x " << getHeight() << std::endl;
warn() << "Label widget tsize: " << getWidthTotal() << " x " << getHeightTotal() << std::endl;
warn() << "Label XY coords : " << getX() << " x " << getY() << std::endl;
warn() << "Label BB in size : " << size.x() << " x " << size.y() << std::endl;
warn() << "Label xy position : " << x << " y " << y << std::endl;
warn() << "------------------------------------" << std::endl;
*/
_text->setPosition(osg::Vec3(x, y, _calculateZ(getLayer() + 1)));
_text->setPosition(osg::Vec3(x, y, _calculateZ(getLayer() + 1)));
}
void Label::setLabel(const std::string& label) {
_text->setText(label);
_text->setText(label);
_calculateSize(getTextSize());
_calculateSize(getTextSize());
}
void Label::setFont(const std::string& font) {
_text->setFont(font);
_calculateSize(getTextSize());
_text->setFont(font);
_calculateSize(getTextSize());
}
void Label::setFontSize(unsigned int size) {
_text->setCharacterSize(size);
_text->setFontResolution(size, size);
_calculateSize(getTextSize());
_text->setCharacterSize(size);
_text->setFontResolution(size, size);
_calculateSize(getTextSize());
}
void Label::setFontColor(const Color& c) {
_text->setColor(c);
_text->setColor(c);
}
void Label::setShadow(point_type offset) {
_text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
_text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
_text->setBackdropOffset(offset);
_text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
_text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
_text->setBackdropOffset(offset);
_calculateSize(getTextSize());
_calculateSize(getTextSize());
}
XYCoord Label::getTextSize() const {
osg::BoundingBox bb = _text->getBound();
osg::BoundingBox bb = _text->getBound();
return XYCoord(
osg::round(bb.xMax() - bb.xMin()),
osg::round(bb.yMax() - bb.yMin())
);
return XYCoord(
osg::round(bb.xMax() - bb.xMin()),
osg::round(bb.yMax() - bb.yMin())
);
}
}

View File

@ -28,34 +28,34 @@ namespace lua {
const char* G_WM = "osgWidget_G_WindowManager";
WindowManager* getWindowManager(lua_State* L) {
lua_pushstring(L, G_WM);
lua_gettable(L, LUA_REGISTRYINDEX);
lua_pushstring(L, G_WM);
lua_gettable(L, LUA_REGISTRYINDEX);
return reinterpret_cast<WindowManager*>(lua_touserdata(L, -1));
return reinterpret_cast<WindowManager*>(lua_touserdata(L, -1));
}
int newWindow(lua_State* L) {
osg::ref_ptr<Window> w = new Box("testLUA", Box::HORIZONTAL);
osg::ref_ptr<Window> w = new Box("testLUA", Box::HORIZONTAL);
lua_pushstring(L, w->getName().c_str());
lua_pushstring(L, w->getName().c_str());
return 1;
return 1;
}
int newWidget(lua_State* L) {
osg::ref_ptr<Widget> w = new Widget("testLUA", 0.0f, 0.0f);
lua_pushstring(L, w->getName().c_str());
osg::ref_ptr<Widget> w = new Widget("testLUA", 0.0f, 0.0f);
lua_pushstring(L, w->getName().c_str());
return 1;
return 1;
}
int getWindow(lua_State* L) {
WindowManager* wm = getWindowManager(L);
WindowManager* wm = getWindowManager(L);
lua_pushlightuserdata(L, wm);
lua_pushlightuserdata(L, wm);
return 1;
return 1;
}
#endif
@ -64,107 +64,107 @@ int getWindow(lua_State* L) {
// A helper function for all those cases where we need to inform the user that there isn't
// a LUA engine available.
bool noLuaFail(const std::string& err) {
warn() << err << "; Lua not compiled in library." << std::endl;
warn() << err << "; Lua not compiled in library." << std::endl;
return false;
return false;
}
// Our "private", internal data.
struct LuaEngineData {
#ifdef OSGWIDGET_USELUA
LuaEngineData():
lua(0) {
}
LuaEngineData():
lua(0) {
}
lua_State* lua;
lua_State* lua;
#endif
};
LuaEngine::LuaEngine(WindowManager* wm):
_wm(wm) {
#ifdef OSGWIDGET_USELUA
_data = new LuaEngineData();
_data = new LuaEngineData();
#else
_data = 0;
_data = 0;
#endif
}
bool LuaEngine::initialize() {
#ifdef OSGWIDGET_USELUA
_data->lua = lua_open();
_data->lua = lua_open();
luaL_openlibs(_data->lua);
static const struct luaL_reg library[] = {
{"newWindow", lua::newWindow},
{"newWidget", lua::newWidget},
{"getWindow", lua::getWindow},
{0, 0}
};
luaL_openlibs(_data->lua);
static const struct luaL_reg library[] = {
{"newWindow", lua::newWindow},
{"newWidget", lua::newWidget},
{"getWindow", lua::getWindow},
{0, 0}
};
luaL_openlib(_data->lua, "osgwidget", library, 0);
luaL_openlib(_data->lua, "osgwidget", library, 0);
// An alternative to using the Registry here would be to pass the WindowManager
// as a userdata "closure" (pvalue). Please see the following doc on more info:
// http://www.lua.org/pil/27.3.3.html
lua_pushstring(_data->lua, lua::G_WM);
lua_pushlightuserdata(_data->lua, _wm);
lua_settable(_data->lua, LUA_REGISTRYINDEX);
// An alternative to using the Registry here would be to pass the WindowManager
// as a userdata "closure" (pvalue). Please see the following doc on more info:
// http://www.lua.org/pil/27.3.3.html
lua_pushstring(_data->lua, lua::G_WM);
lua_pushlightuserdata(_data->lua, _wm);
lua_settable(_data->lua, LUA_REGISTRYINDEX);
return true;
return true;
#else
return noLuaFail("Can't initialize the LuaEngine");
return noLuaFail("Can't initialize the LuaEngine");
#endif
}
bool LuaEngine::close() {
#ifdef OSGWIDGET_USELUA
lua_close(_data->lua);
lua_close(_data->lua);
delete _data;
delete _data;
return true;
return true;
#else
return noLuaFail("Can't close the LuaEngine");
return noLuaFail("Can't close the LuaEngine");
#endif
}
bool LuaEngine::eval(const std::string& code) {
#ifdef OSGWIDGET_USELUA
if(luaL_dostring(_data->lua, code.c_str())) {
warn() << "LuaEngine::eval - " << lua_tostring(_data->lua, -1) << std::endl;
if(luaL_dostring(_data->lua, code.c_str())) {
warn() << "LuaEngine::eval - " << lua_tostring(_data->lua, -1) << std::endl;
return false;
}
return false;
}
return true;
return true;
#else
return noLuaFail("Can't evaluate code in LuaEngine");
return noLuaFail("Can't evaluate code in LuaEngine");
#endif
}
bool LuaEngine::runFile(const std::string& filePath) {
#ifdef OSGWIDGET_USELUA
if(!osgDB::fileExists(filePath)) {
warn() << "Couldn't find file \"" << filePath << "\" for LuaEngine." << std::endl;
if(!osgDB::fileExists(filePath)) {
warn() << "Couldn't find file \"" << filePath << "\" for LuaEngine." << std::endl;
return false;
}
return false;
}
if(luaL_dofile(_data->lua, filePath.c_str())) {
warn() << "LuaEngine::runFile - " << lua_tostring(_data->lua, -1) << std::endl;
if(luaL_dofile(_data->lua, filePath.c_str())) {
warn() << "LuaEngine::runFile - " << lua_tostring(_data->lua, -1) << std::endl;
return false;
}
return false;
}
return true;
return true;
#else
return noLuaFail("Can't run file in LuaEngine");
return noLuaFail("Can't run file in LuaEngine");
#endif
}

View File

@ -22,40 +22,40 @@ namespace py {
static PyObject* G_ERR = 0;
PyObject* newWindow(PyObject* self, PyObject* args) {
PyObject* buffer = 0;
const char* name = 0;
int width = 0;
int height = 0;
PyObject* buffer = 0;
const char* name = 0;
int width = 0;
int height = 0;
/*
if(PyArg_ParseTuple(args, "sO!ii", &name, &PyBuffer_Type, &buffer, &width, &height)) {
const void* buf = 0;
int len = 0;
/*
if(PyArg_ParseTuple(args, "sO!ii", &name, &PyBuffer_Type, &buffer, &width, &height)) {
const void* buf = 0;
int len = 0;
if(!PyObject_AsReadBuffer(buffer, &buf, &len)) {
// if(Database::instance().add(name, buf, width, height))
return Py_BuildValue("i", len);
if(!PyObject_AsReadBuffer(buffer, &buf, &len)) {
// if(Database::instance().add(name, buf, width, height))
return Py_BuildValue("i", len);
// else PyErr_SetString(G_ERR, "Couldn't add image to database.");
}
// else PyErr_SetString(G_ERR, "Couldn't add image to database.");
}
else PyErr_SetString(G_ERR, "Couldn't read buffer data.");
else PyErr_SetString(G_ERR, "Couldn't read buffer data.");
return 0;
}
*/
return 0;
}
*/
PyErr_SetString(G_ERR, "still testing...");
PyErr_SetString(G_ERR, "still testing...");
return 0;
return 0;
}
static PyMethodDef methods[] = {
{
"newWindow", newWindow, METH_VARARGS,
"docstring"
},
{ 0, 0, 0, 0 }
{
"newWindow", newWindow, METH_VARARGS,
"docstring"
},
{ 0, 0, 0, 0 }
};
#endif
@ -64,151 +64,151 @@ static PyMethodDef methods[] = {
// A helper function for all those cases where we need to inform the user that there isn't
// a LUA engine available.
bool noPythonFail(const std::string& err) {
warn() << err << "; Python not compiled in library." << std::endl;
warn() << err << "; Python not compiled in library." << std::endl;
return false;
return false;
}
// Our "private", internal data.
struct PythonEngineData {
#ifdef OSGWIDGET_USEPYTHON
PythonEngineData():
mod (0),
err (0),
main (0) {
}
PythonEngineData():
mod (0),
err (0),
main (0) {
}
bool valid() const {
return mod && err && main;
}
bool valid() const {
return mod && err && main;
}
PyObject* mod;
PyObject* err;
PyObject* main;
PyObject* mod;
PyObject* err;
PyObject* main;
#endif
};
PythonEngine::PythonEngine(WindowManager* wm):
_wm(wm) {
#ifdef OSGWIDGET_USEPYTHON
_data = new PythonEngineData();
_data = new PythonEngineData();
#else
_data = 0;
_data = 0;
#endif
}
bool PythonEngine::initialize() {
#ifdef OSGWIDGET_USEPYTHON
Py_InitializeEx(0);
Py_InitializeEx(0);
if(!_data->valid()) {
_data->mod = Py_InitModule3("osgwidget", py::methods, "main docstring");
_data->err = PyErr_NewException((char*)("osgwidget.error"), 0, 0);
_data->main = PyModule_GetDict(PyImport_AddModule("__main__"));
if(!_data->valid()) {
_data->mod = Py_InitModule3("osgwidget", py::methods, "main docstring");
_data->err = PyErr_NewException((char*)("osgwidget.error"), 0, 0);
_data->main = PyModule_GetDict(PyImport_AddModule("__main__"));
Py_INCREF(_data->err);
Py_INCREF(_data->err);
// TODO: ...sigh...
py::G_ERR = _data->err;
// TODO: ...sigh...
py::G_ERR = _data->err;
PyModule_AddObject(_data->mod, "error", _data->err);
}
PyModule_AddObject(_data->mod, "error", _data->err);
}
return true;
return true;
#else
return noPythonFail("Can't initialize the PythonEngine");
return noPythonFail("Can't initialize the PythonEngine");
#endif
}
bool PythonEngine::close() {
#ifdef OSGWIDGET_USEPYTHON
if(_data->valid()) {
Py_DECREF(_data->err);
if(_data->valid()) {
Py_DECREF(_data->err);
Py_Finalize();
}
Py_Finalize();
}
delete _data;
delete _data;
return true;
return true;
#else
return noPythonFail("Can't close the PythonEngine");
return noPythonFail("Can't close the PythonEngine");
#endif
}
bool PythonEngine::eval(const std::string& code) {
#ifdef OSGWIDGET_USEPYTHON
PyObject* r = PyRun_String(code.c_str(), Py_file_input, _data->main, _data->main);
PyObject* r = PyRun_String(code.c_str(), Py_file_input, _data->main, _data->main);
if(!r) {
r = PyErr_Occurred();
if(!r) {
r = PyErr_Occurred();
if(r) {
PyErr_Print();
PyErr_Clear();
}
if(r) {
PyErr_Print();
PyErr_Clear();
}
return false;
}
return false;
}
return true;
return true;
#else
return noPythonFail("Can't evaluate code in PythonEngine");
return noPythonFail("Can't evaluate code in PythonEngine");
#endif
}
bool PythonEngine::runFile(const std::string& filePath) {
#ifdef OSGWIDGET_USEPYTHON
if(!osgDB::fileExists(filePath)) {
warn()
<< "Couldn't find file \"" << filePath << "\" for PythonEngine."
<< std::endl
;
if(!osgDB::fileExists(filePath)) {
warn()
<< "Couldn't find file \"" << filePath << "\" for PythonEngine."
<< std::endl
;
return false;
}
return false;
}
FILE* f = fopen(filePath.c_str(), "r");
PyObject* r = PyRun_File(f, filePath.c_str(), Py_file_input, _data->main, _data->main);
FILE* f = fopen(filePath.c_str(), "r");
PyObject* r = PyRun_File(f, filePath.c_str(), Py_file_input, _data->main, _data->main);
fclose(f);
fclose(f);
if(!r) {
r = PyErr_Occurred();
if(!r) {
r = PyErr_Occurred();
if(r) {
// The following snippet lets us get the return code. That is: if the
// script is stopped with sys.exit() or similar. We could use this
// return code to do something sensible... later.
if(PyErr_ExceptionMatches(PyExc_SystemExit)) {
PyObject* ty = 0;
PyObject* er = 0;
PyObject* tr = 0;
if(r) {
// The following snippet lets us get the return code. That is: if the
// script is stopped with sys.exit() or similar. We could use this
// return code to do something sensible... later.
if(PyErr_ExceptionMatches(PyExc_SystemExit)) {
PyObject* ty = 0;
PyObject* er = 0;
PyObject* tr = 0;
PyErr_Fetch(&ty, &er, &tr);
PyErr_Fetch(&ty, &er, &tr);
Py_DECREF(ty);
Py_DECREF(er);
Py_DECREF(er);
}
Py_DECREF(ty);
Py_DECREF(er);
Py_DECREF(er);
}
else {
PyErr_Print();
PyErr_Clear();
}
}
else {
PyErr_Print();
PyErr_Clear();
}
}
return false;
}
return false;
}
return true;
return true;
#else
return noPythonFail("Can't evaluate code in PythonEngine");
return noPythonFail("Can't evaluate code in PythonEngine");
#endif
}

View File

@ -9,7 +9,7 @@ namespace osgWidget {
Style::Style(const std::string& name, const std::string& style):
_style(style) {
setName(name);
setName(name);
}
Style::Style(const Style& style, const osg::CopyOp& co):
@ -18,309 +18,309 @@ _style (style._style) {
}
bool Style::applyStyle(Widget* widget, Reader r) {
std::string str;
osg::Vec2 vec2;
osg::Vec3 vec3;
osg::Vec4 vec4;
float f;
std::string str;
osg::Vec2 vec2;
osg::Vec3 vec3;
osg::Vec4 vec4;
float f;
if(_match("pos %i %i", r) || _match("pos %f %f", r)) {
r.readSequence(vec2);
widget->setOrigin(vec2);
}
if(_match("pos %i %i", r) || _match("pos %f %f", r)) {
r.readSequence(vec2);
widget->setOrigin(vec2);
}
else if(_match("pos-x %i", r) || _match("pos-x %f", r)) {
r.readSequence(f);
widget->setX(f);
}
else if(_match("pos-x %i", r) || _match("pos-x %f", r)) {
r.readSequence(f);
widget->setX(f);
}
else if(_match("pos-y %i", r) || _match("pos-y %f", r)) {
r.readSequence(f);
widget->setY(f);
}
else if(_match("pos-y %i", r) || _match("pos-y %f", r)) {
r.readSequence(f);
widget->setY(f);
}
else if(_match("size %i %i", r) || _match("size %f %f", r)) {
r.readSequence(vec2);
widget->setSize(vec2);
}
else if(_match("size %i %i", r) || _match("size %f %f", r)) {
r.readSequence(vec2);
widget->setSize(vec2);
}
else if(_match("width %i", r) || _match("width %f", r)) {
r.readSequence(f);
widget->setWidth(f);
}
else if(_match("width %i", r) || _match("width %f", r)) {
r.readSequence(f);
widget->setWidth(f);
}
else if(_match("height %i", r) || _match("height %f", r)) {
r.readSequence(f);
widget->setHeight(f);
}
else if(_match("height %i", r) || _match("height %f", r)) {
r.readSequence(f);
widget->setHeight(f);
}
// Color using 4x 0-255 integers.
else if(_match("color %i %i %i %i", r)) {
r.readSequence(vec4);
widget->setColor(vec4 / 255.0f);
}
// Color using 4x 0-255 integers.
else if(_match("color %i %i %i %i", r)) {
r.readSequence(vec4);
widget->setColor(vec4 / 255.0f);
}
// Color using 3x 0-255 integers with a default alpha of 255.
else if(_match("color %i %i %i", r)) {
r.readSequence(vec3);
widget->setColor(osg::Vec4(vec3[0], vec3[1], vec3[2], 255.0f) / 255.0f);
}
// Color using 4x 0.0f-1.0f floats.
else if(_match("color %f %f %f %f", r)) {
r.readSequence(vec4);
widget->setColor(vec4);
}
// Color using 3x 0-255 integers with a default alpha of 255.
else if(_match("color %i %i %i", r)) {
r.readSequence(vec3);
widget->setColor(osg::Vec4(vec3[0], vec3[1], vec3[2], 255.0f) / 255.0f);
}
// Color using 4x 0.0f-1.0f floats.
else if(_match("color %f %f %f %f", r)) {
r.readSequence(vec4);
widget->setColor(vec4);
}
// Color using 3x 0.0f-1.0f floats with a default alpha of 1.0f.
else if(_match("color %f %f %f", r)) {
r.readSequence(vec3);
widget->setColor(osg::Vec4(vec3[0], vec3[1], vec3[2], 1.0f));
}
// Color using 3x 0.0f-1.0f floats with a default alpha of 1.0f.
else if(_match("color %f %f %f", r)) {
r.readSequence(vec3);
widget->setColor(osg::Vec4(vec3[0], vec3[1], vec3[2], 1.0f));
}
// Set padding uniformly.
else if(_match("padding %i", r)) {
r.readSequence(f);
widget->setPadding(f);
}
// Set padding uniformly.
else if(_match("padding %i", r)) {
r.readSequence(f);
widget->setPadding(f);
}
// Set left padding.
else if(_match("padding-left %i", r)) {
r.readSequence(f);
widget->setPadLeft(f);
}
// Set left padding.
else if(_match("padding-left %i", r)) {
r.readSequence(f);
widget->setPadLeft(f);
}
// Set right padding.
else if(_match("padding-right %i", r)) {
r.readSequence(f);
widget->setPadRight(f);
}
// Set right padding.
else if(_match("padding-right %i", r)) {
r.readSequence(f);
widget->setPadRight(f);
}
// Set top padding.
else if(_match("padding-top %i", r)) {
r.readSequence(f);
widget->setPadTop(f);
}
// Set top padding.
else if(_match("padding-top %i", r)) {
r.readSequence(f);
widget->setPadTop(f);
}
// Set bottom padding.
else if(_match("padding-bottom %i", r)) {
r.readSequence(f);
widget->setPadBottom(f);
}
// Set bottom padding.
else if(_match("padding-bottom %i", r)) {
r.readSequence(f);
widget->setPadBottom(f);
}
else if(_match("layer %w", r)) {
r.readSequence(str);
else if(_match("layer %w", r)) {
r.readSequence(str);
widget->setLayer(strToLayer(str));
}
widget->setLayer(strToLayer(str));
}
else if(_match("valign %w", r)) {
r.readSequence(str);
else if(_match("valign %w", r)) {
r.readSequence(str);
widget->setAlignVertical(strToVAlign(str));
}
widget->setAlignVertical(strToVAlign(str));
}
else if(_match("halign %w", r)) {
r.readSequence(str);
widget->setAlignHorizontal(strToHAlign(str));
}
else if(_match("halign %w", r)) {
r.readSequence(str);
widget->setAlignHorizontal(strToHAlign(str));
}
else if(_match("coordmode %w", r)) {
r.readSequence(str);
else if(_match("coordmode %w", r)) {
r.readSequence(str);
widget->setCoordinateMode(strToCoordMode(str));
}
widget->setCoordinateMode(strToCoordMode(str));
}
else if(_match("fill %w", r)) {
r.readSequence(str);
else if(_match("fill %w", r)) {
r.readSequence(str);
widget->setCanFill(strToFill(str));
}
widget->setCanFill(strToFill(str));
}
else if(_match("image %s", r)) {
r.readSequence(str);
else if(_match("image %s", r)) {
r.readSequence(str);
widget->setImage(str, true);
}
widget->setImage(str, true);
}
// Otherwise, increment the stream pointer.
else return false;
// Otherwise, increment the stream pointer.
else return false;
return true;
return true;
}
bool Style::applyStyle(Label* label, Reader r) {
return false;
return false;
}
bool Style::applyStyle(Input* input, Reader r) {
return false;
return false;
}
bool Style::applyStyle(Window* window, Reader r) {
osg::Vec2 vec2;
float f;
osg::Vec2 vec2;
float f;
if(_match("pos %i %i", r) || _match("pos %f %f", r)) {
r.readSequence(vec2);
window->setOrigin(vec2.x(), vec2.y());
}
if(_match("pos %i %i", r) || _match("pos %f %f", r)) {
r.readSequence(vec2);
window->setOrigin(vec2.x(), vec2.y());
}
else if(_match("pos-x %i", r) || _match("pos-x %f", r)) {
r.readSequence(f);
window->setX(f);
}
else if(_match("pos-x %i", r) || _match("pos-x %f", r)) {
r.readSequence(f);
window->setX(f);
}
else if(_match("pos-y %i", r) || _match("pos-y %f", r)) {
r.readSequence(f);
window->setY(f);
}
else if(_match("pos-y %i", r) || _match("pos-y %f", r)) {
r.readSequence(f);
window->setY(f);
}
else if(_match("size %i %i", r) || _match("size %f %f", r)) {
r.readSequence(vec2);
else if(_match("size %i %i", r) || _match("size %f %f", r)) {
r.readSequence(vec2);
window->resize(vec2.x(), vec2.y());
}
window->resize(vec2.x(), vec2.y());
}
else if(_match("width %i", r) || _match("width %f", r)) {
r.readSequence(f);
window->resize(f);
}
else if(_match("width %i", r) || _match("width %f", r)) {
r.readSequence(f);
window->resize(f);
}
else if(_match("height %i", r) || _match("height %f", r)) {
r.readSequence(f);
window->resize(0.0f, f);
}
else if(_match("height %i", r) || _match("height %f", r)) {
r.readSequence(f);
window->resize(0.0f, f);
}
else return false;
else return false;
return true;
return true;
}
bool Style::applyStyle(Window::EmbeddedWindow*, Reader r) {
return false;
return false;
}
bool Style::applyStyle(Box* box, Reader r) {
if(applyStyle(static_cast<Window*>(box), r)) return true;
if(applyStyle(static_cast<Window*>(box), r)) return true;
return false;
return false;
}
bool Style::applyStyle(Frame::Corner*, Reader r) {
return false;
return false;
}
bool Style::applyStyle(Frame::Border*, Reader r) {
return false;
return false;
}
Widget::Layer Style::strToLayer(const std::string& layer)
{
std::string l = lowerCase(layer);
std::string l = lowerCase(layer);
if(l == "top") return Widget::LAYER_TOP;
if(l == "top") return Widget::LAYER_TOP;
else if(l == "high") return Widget::LAYER_HIGH;
else if(l == "high") return Widget::LAYER_HIGH;
else if(l == "middle") return Widget::LAYER_MIDDLE;
else if(l == "middle") return Widget::LAYER_MIDDLE;
else if(l == "low") return Widget::LAYER_LOW;
else if(l == "bg") return Widget::LAYER_BG;
else if(l == "low") return Widget::LAYER_LOW;
else if(l == "bg") return Widget::LAYER_BG;
else {
warn() << "Unkown Layer name [" << layer << "]; using LAYER_MIDDLE." << std::endl;
else {
warn() << "Unkown Layer name [" << layer << "]; using LAYER_MIDDLE." << std::endl;
return Widget::LAYER_MIDDLE;
}
return Widget::LAYER_MIDDLE;
}
}
Widget::VerticalAlignment Style::strToVAlign(const std::string& valign) {
std::string va = lowerCase(valign);
std::string va = lowerCase(valign);
if(va == "center") return Widget::VA_CENTER;
if(va == "center") return Widget::VA_CENTER;
else if(va == "top") return Widget::VA_TOP;
else if(va == "top") return Widget::VA_TOP;
else if(va == "bottom") return Widget::VA_BOTTOM;
else if(va == "bottom") return Widget::VA_BOTTOM;
else {
warn() << "Unkown VAlign name [" << valign << "]; using VA_CENTER." << std::endl;
else {
warn() << "Unkown VAlign name [" << valign << "]; using VA_CENTER." << std::endl;
return Widget::VA_CENTER;
}
return Widget::VA_CENTER;
}
}
Widget::HorizontalAlignment Style::strToHAlign(const std::string& halign) {
std::string ha = lowerCase(halign);
std::string ha = lowerCase(halign);
if(ha == "center") return Widget::HA_CENTER;
if(ha == "center") return Widget::HA_CENTER;
else if(ha == "left") return Widget::HA_LEFT;
else if(ha == "left") return Widget::HA_LEFT;
else if(ha == "right") return Widget::HA_RIGHT;
else if(ha == "right") return Widget::HA_RIGHT;
else {
warn() << "Unkown HAlign name [" << halign << "]; using HA_CENTER." << std::endl;
else {
warn() << "Unkown HAlign name [" << halign << "]; using HA_CENTER." << std::endl;
return Widget::HA_CENTER;
}
return Widget::HA_CENTER;
}
}
Widget::CoordinateMode Style::strToCoordMode(const std::string& coordmode) {
std::string cm = lowerCase(coordmode);
std::string cm = lowerCase(coordmode);
if(cm == "absolute") return Widget::CM_ABSOLUTE;
if(cm == "absolute") return Widget::CM_ABSOLUTE;
else if(cm == "relative") return Widget::CM_RELATIVE;
else if(cm == "relative") return Widget::CM_RELATIVE;
else {
warn()
<< "Unkown CoordMode name [" << coordmode
<< "]; using CM_ABSOLUTE." << std::endl
;
else {
warn()
<< "Unkown CoordMode name [" << coordmode
<< "]; using CM_ABSOLUTE." << std::endl
;
return Widget::CM_ABSOLUTE;
}
return Widget::CM_ABSOLUTE;
}
}
bool Style::strToFill(const std::string& fill) {
std::string cm = lowerCase(fill);
if(cm == "true") return true;
std::string cm = lowerCase(fill);
if(cm == "true") return true;
else if(cm == "false") return false;
else if(cm == "false") return false;
else {
warn()
<< "Unkown Fill name [" << fill
<< "]; using false." << std::endl
;
else {
warn()
<< "Unkown Fill name [" << fill
<< "]; using false." << std::endl
;
return false;
}
return false;
}
}
StyleManager::StyleManager() {
@ -328,50 +328,50 @@ StyleManager::StyleManager() {
StyleManager::StyleManager(const StyleManager& manager, const osg::CopyOp& co):
osg::Object(manager, co) {
for(ConstIterator i = _styles.begin(); i != _styles.end(); i++) if(i->second.valid()) {
_styles[i->first] = new Style(*i->second.get(), osg::CopyOp::DEEP_COPY_ALL);
}
for(ConstIterator i = _styles.begin(); i != _styles.end(); i++) if(i->second.valid()) {
_styles[i->first] = new Style(*i->second.get(), osg::CopyOp::DEEP_COPY_ALL);
}
}
bool StyleManager::_applyStyleToObject(osg::Object* obj, const std::string& style) {
std::string c = obj->className();
std::string c = obj->className();
if(!std::string("Widget").compare(c)) return _coerceAndApply<Widget>(
obj,
style,
c
);
if(!std::string("Widget").compare(c)) return _coerceAndApply<Widget>(
obj,
style,
c
);
else if(!std::string("Label").compare(c)) return _coerceAndApply<Label>(
obj,
style,
c
);
else if(!std::string("Label").compare(c)) return _coerceAndApply<Label>(
obj,
style,
c
);
else if(!std::string("Box").compare(c)) return _coerceAndApply<Box>(
obj,
style,
c
);
else if(!std::string("Box").compare(c)) return _coerceAndApply<Box>(
obj,
style,
c
);
else warn()
<< "StyleManager does not support coercion of objects of type "
<< c << "." << std::endl
;
else warn()
<< "StyleManager does not support coercion of objects of type "
<< c << "." << std::endl
;
return false;
return false;
}
bool StyleManager::addStyle(Style* style) {
if(!style || style->getName().empty()) {
warn() << "Cannot add a NULL or nameless Style object." << std::endl;
if(!style || style->getName().empty()) {
warn() << "Cannot add a NULL or nameless Style object." << std::endl;
return false;
}
return false;
}
_styles[style->getName()] = style;
_styles[style->getName()] = style;
return true;
return true;
}
}

View File

@ -14,7 +14,7 @@ _rows (rows),
_cols (cols),
_lastRowAdd (0),
_lastColAdd (0) {
_objects.resize(_rows * _cols);
_objects.resize(_rows * _cols);
}
Table::Table(const Table& table, const osg::CopyOp& co):
@ -26,200 +26,200 @@ _lastColAdd (table._lastColAdd) {
}
unsigned int Table::_calculateIndex(unsigned int row, unsigned int col) const {
return (row * _cols) + col;
return (row * _cols) + col;
}
void Table::_getRows(CellSizes& rows, Getter get) const {
for(unsigned int i = 0; i < _rows; i++) rows.push_back(
_compare<Greater>(get, i * _cols, (i * _cols) + _cols)
);
for(unsigned int i = 0; i < _rows; i++) rows.push_back(
_compare<Greater>(get, i * _cols, (i * _cols) + _cols)
);
}
void Table::_getColumns(CellSizes& cols, Getter get) const {
for(unsigned int i = 0; i < _cols; i++) cols.push_back(
_compare<Greater>(get, i, 0, _cols)
);
for(unsigned int i = 0; i < _cols; i++) cols.push_back(
_compare<Greater>(get, i, 0, _cols)
);
}
void Table::_resizeImplementation(point_type width, point_type height) {
// We use these vectors so that we don't have to repeatedly call isFillable
// all the time. Usage such as this can really generate a lot of moronic,
// misinformed opposition, but until std::bit_vector is available, this is
// what we get. Deal with it.
std::vector<bool> rowFills;
std::vector<bool> colFills;
// We use these vectors so that we don't have to repeatedly call isFillable
// all the time. Usage such as this can really generate a lot of moronic,
// misinformed opposition, but until std::bit_vector is available, this is
// what we get. Deal with it.
std::vector<bool> rowFills;
std::vector<bool> colFills;
point_type numRowFills = 0.0f;
point_type numColFills = 0.0f;
point_type numRowFills = 0.0f;
point_type numColFills = 0.0f;
// Enumerate each row and determine whether it can fill. If so, increment
// our numRowFills variable and set the position in rowFills to "true."
for(unsigned int row = 0; row < _rows; row++) {
bool fill = isRowVerticallyFillable(row);
// Enumerate each row and determine whether it can fill. If so, increment
// our numRowFills variable and set the position in rowFills to "true."
for(unsigned int row = 0; row < _rows; row++) {
bool fill = isRowVerticallyFillable(row);
if(fill) numRowFills++;
if(fill) numRowFills++;
rowFills.push_back(fill);
}
rowFills.push_back(fill);
}
// Enumerate each column and determine whether it can fill. If so, increment
// our numColFills variable and set the position in colFills to "true."
for(unsigned int col = 0; col < _cols; col++) {
bool fill = isColumnHorizontallyFillable(col);
// Enumerate each column and determine whether it can fill. If so, increment
// our numColFills variable and set the position in colFills to "true."
for(unsigned int col = 0; col < _cols; col++) {
bool fill = isColumnHorizontallyFillable(col);
if(fill) numColFills++;
if(fill) numColFills++;
colFills.push_back(fill);
}
colFills.push_back(fill);
}
int wrem = 0;
int hrem = 0;
int wrem = 0;
int hrem = 0;
if(numRowFills > 0.0f) {
hrem = static_cast<int>(height) % static_cast<int>(numRowFills);
if(numRowFills > 0.0f) {
hrem = static_cast<int>(height) % static_cast<int>(numRowFills);
unsigned int cur = 0;
unsigned int cur = 0;
for(unsigned int row = 0; row < _rows; row++) {
point_type h = height / numRowFills;
if(cur >= _lastRowAdd && hrem) {
_lastRowAdd++;
h++;
hrem--;
}
for(unsigned int row = 0; row < _rows; row++) {
point_type h = height / numRowFills;
if(cur >= _lastRowAdd && hrem) {
_lastRowAdd++;
h++;
hrem--;
}
if(rowFills[row]) addHeightToRow(row, h);
if(rowFills[row]) addHeightToRow(row, h);
cur++;
}
}
cur++;
}
}
if(numColFills > 0.0f) {
wrem = static_cast<int>(width) % static_cast<int>(numColFills);
if(numColFills > 0.0f) {
wrem = static_cast<int>(width) % static_cast<int>(numColFills);
unsigned int cur = 0;
unsigned int cur = 0;
for(unsigned int col = 0; col < _cols; col++) {
point_type w = width / numColFills;
for(unsigned int col = 0; col < _cols; col++) {
point_type w = width / numColFills;
if(cur >= _lastColAdd && wrem) {
_lastColAdd++;
w++;
wrem--;
}
if(cur >= _lastColAdd && wrem) {
_lastColAdd++;
w++;
wrem--;
}
if(colFills[col]) addWidthToColumn(col, w);
if(colFills[col]) addWidthToColumn(col, w);
cur++;
}
}
cur++;
}
}
CellSizes rowHeights;
CellSizes colWidths;
CellSizes rowHeights;
CellSizes colWidths;
getRowHeights(rowHeights);
getColumnWidths(colWidths);
getRowHeights(rowHeights);
getColumnWidths(colWidths);
point_type y = 0.0f;
point_type y = 0.0f;
for(unsigned int row = 0; row < _rows; row++) {
point_type x = 0.0f;
for(unsigned int row = 0; row < _rows; row++) {
point_type x = 0.0f;
for(unsigned int col = 0; col < _cols; col++) {
Widget* widget = _objects[_calculateIndex(row, col)].get();
for(unsigned int col = 0; col < _cols; col++) {
Widget* widget = _objects[_calculateIndex(row, col)].get();
if(widget) {
widget->setOrigin(x, y);
if(widget) {
widget->setOrigin(x, y);
_positionWidget(widget, colWidths[col], rowHeights[row]);
}
_positionWidget(widget, colWidths[col], rowHeights[row]);
}
x += colWidths[col];
}
x += colWidths[col];
}
y += rowHeights[row];
}
y += rowHeights[row];
}
}
Window::Sizes Table::_getWidthImplementation() const {
CellSizes cols;
CellSizes minCols;
CellSizes cols;
CellSizes minCols;
getColumnWidths(cols);
getColumnMinWidths(minCols);
return Sizes(
std::accumulate(cols.begin(), cols.end(), 0.0f, Plus()),
std::accumulate(minCols.begin(), minCols.end(), 0.0f, Plus())
);
getColumnWidths(cols);
getColumnMinWidths(minCols);
return Sizes(
std::accumulate(cols.begin(), cols.end(), 0.0f, Plus()),
std::accumulate(minCols.begin(), minCols.end(), 0.0f, Plus())
);
}
Window::Sizes Table::_getHeightImplementation() const {
CellSizes rows;
CellSizes minRows;
CellSizes rows;
CellSizes minRows;
getRowHeights(rows);
getRowMinHeights(minRows);
getRowHeights(rows);
getRowMinHeights(minRows);
return Sizes(
std::accumulate(rows.begin(), rows.end(), 0.0f, Plus()),
std::accumulate(minRows.begin(), minRows.end(), 0.0f, Plus())
);
return Sizes(
std::accumulate(rows.begin(), rows.end(), 0.0f, Plus()),
std::accumulate(minRows.begin(), minRows.end(), 0.0f, Plus())
);
}
bool Table::addWidget(Widget* widget) {
return addWidget(widget, 0, 0);
return addWidget(widget, 0, 0);
}
bool Table::addWidget(Widget* widget, unsigned int row, unsigned int col) {
return Window::insertWidget(widget, _calculateIndex(row, col));
return Window::insertWidget(widget, _calculateIndex(row, col));
}
void Table::getRowHeights(CellSizes& rowHeights) const {
_getRows(rowHeights, &Widget::getHeightTotal);
_getRows(rowHeights, &Widget::getHeightTotal);
}
void Table::getRowMinHeights(CellSizes& rowMinHeights) const {
_getRows(rowMinHeights, &Widget::getMinHeightTotal);
_getRows(rowMinHeights, &Widget::getMinHeightTotal);
}
void Table::getColumnWidths(CellSizes& colWidths) const {
_getColumns(colWidths, &Widget::getWidthTotal);
_getColumns(colWidths, &Widget::getWidthTotal);
}
void Table::getColumnMinWidths(CellSizes& colMinWidths) const {
_getColumns(colMinWidths, &Widget::getMinWidthTotal);
_getColumns(colMinWidths, &Widget::getMinWidthTotal);
}
void Table::addHeightToRow(unsigned int row, point_type height) {
for(
Iterator i = begin() + (row * _cols);
i != begin() + ((row * _cols) + _cols);
i++
) if(i->valid()) i->get()->addHeight(height);
for(
Iterator i = begin() + (row * _cols);
i != begin() + ((row * _cols) + _cols);
i++
) if(i->valid()) i->get()->addHeight(height);
}
void Table::addWidthToColumn(unsigned int col, point_type width) {
// See the documentation in include/osgWidget/Window::_forEachApplyOrAssign if you want
// to know why we need this variable.
unsigned int c = col;
// See the documentation in include/osgWidget/Window::_forEachApplyOrAssign if you want
// to know why we need this variable.
unsigned int c = col;
for(Iterator i = begin() + col; i < end(); c += _cols) {
if(i->valid()) i->get()->addWidth(width);
for(Iterator i = begin() + col; i < end(); c += _cols) {
if(i->valid()) i->get()->addWidth(width);
if((c + _cols) < size()) i += _cols;
if((c + _cols) < size()) i += _cols;
else i = end();
}
else i = end();
}
}
bool Table::isRowVerticallyFillable(unsigned int row) const {
return static_cast<point_type>(_cols) == _getNumFill(row * _cols, (row * _cols) + _cols);
return static_cast<point_type>(_cols) == _getNumFill(row * _cols, (row * _cols) + _cols);
}
bool Table::isColumnHorizontallyFillable(unsigned int col) const {
return static_cast<point_type>(_rows) == _getNumFill(col, 0, _cols);
return static_cast<point_type>(_rows) == _getNumFill(col, 0, _cols);
}
}

View File

@ -15,162 +15,162 @@
namespace osgWidget {
std::string getFilePath(const std::string& filename) {
osgDB::FilePathList path;
osgDB::FilePathList path;
char* fp = getenv("OSGWIDGET_FILE_PATH");
osgDB::convertStringPathIntoFilePathList(fp ? fp : ".", path);
char* fp = getenv("OSGWIDGET_FILE_PATH");
osgDB::convertStringPathIntoFilePathList(fp ? fp : ".", path);
return osgDB::findFileInPath(filename, path);
return osgDB::findFileInPath(filename, path);
}
std::string generateRandomName(const std::string& base) {
static unsigned int count = 0;
std::stringstream ss;
static unsigned int count = 0;
std::stringstream ss;
ss << base << "_" << count;
count++;
ss << base << "_" << count;
count++;
return ss.str();
return ss.str();
}
osg::Matrix createInvertedYOrthoProjectionMatrix(matrix_type width, matrix_type height) {
osg::Matrix m = osg::Matrix::ortho2D(0.0f, width, 0.0f, height);
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
osg::Matrix t = osg::Matrix::translate(0.0f, -height, 0.0f);
osg::Matrix m = osg::Matrix::ortho2D(0.0f, width, 0.0f, height);
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
osg::Matrix t = osg::Matrix::translate(0.0f, -height, 0.0f);
return t * s * m;
return t * s * m;
}
osg::Camera* createOrthoCamera(matrix_type width, matrix_type height) {
osg::Camera* camera = new osg::Camera();
osg::Camera* camera = new osg::Camera();
camera->getOrCreateStateSet()->setMode(
GL_LIGHTING,
osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF
);
camera->getOrCreateStateSet()->setMode(
GL_LIGHTING,
osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF
);
camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, width, 0.0f, height));
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setRenderOrder(osg::Camera::POST_RENDER);
return camera;
camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, width, 0.0f, height));
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setRenderOrder(osg::Camera::POST_RENDER);
return camera;
}
osg::Camera* createInvertedYOrthoCamera(matrix_type width, matrix_type height) {
osg::Camera* camera = createOrthoCamera(width, height);
osg::Camera* camera = createOrthoCamera(width, height);
camera->setProjectionMatrix(createInvertedYOrthoProjectionMatrix(width, height));
return camera;
camera->setProjectionMatrix(createInvertedYOrthoProjectionMatrix(width, height));
return camera;
}
osg::Group* _createExampleCommon(osgViewer::View* view, WindowManager* wm, osg::Node* node) {
if(!wm) return 0;
if(!wm) return 0;
view->setUpViewInWindow(
0,
0,
static_cast<int>(wm->getWidth()),
static_cast<int>(wm->getHeight())
);
view->setUpViewInWindow(
0,
0,
static_cast<int>(wm->getWidth()),
static_cast<int>(wm->getHeight())
);
osg::Group* group = new osg::Group();
osg::Camera* camera = wm->createParentOrthoCamera();
osg::Group* group = new osg::Group();
osg::Camera* camera = wm->createParentOrthoCamera();
group->addChild(camera);
group->addChild(camera);
if(node) group->addChild(node);
if(node) group->addChild(node);
view->addEventHandler(new osgWidget::MouseHandler(wm));
view->addEventHandler(new osgWidget::KeyboardHandler(wm));
view->addEventHandler(new osgWidget::ResizeHandler(wm, camera));
view->addEventHandler(new osgViewer::StatsHandler());
view->addEventHandler(new osgViewer::WindowSizeHandler());
view->addEventHandler(new osgGA::StateSetManipulator(
view->getCamera()->getOrCreateStateSet()
));
view->addEventHandler(new osgWidget::MouseHandler(wm));
view->addEventHandler(new osgWidget::KeyboardHandler(wm));
view->addEventHandler(new osgWidget::ResizeHandler(wm, camera));
view->addEventHandler(new osgViewer::StatsHandler());
view->addEventHandler(new osgViewer::WindowSizeHandler());
view->addEventHandler(new osgGA::StateSetManipulator(
view->getCamera()->getOrCreateStateSet()
));
wm->resizeAllWindows();
return group;
wm->resizeAllWindows();
return group;
}
int createExample(osgViewer::Viewer& viewer, WindowManager* wm, osg::Node* node) {
osg::Group* group = _createExampleCommon(&viewer, wm, node);
osg::Group* group = _createExampleCommon(&viewer, wm, node);
viewer.setSceneData(group);
viewer.setSceneData(group);
return viewer.run();
return viewer.run();
}
// TODO: This function is totally broken; I don't really have any idea of how to do this.
// Incredibly frustrating stuff.
int createCompositeExample(
osgViewer::CompositeViewer& viewer,
osgViewer::View* view,
WindowManager* wm,
osg::Node* node
osgViewer::CompositeViewer& viewer,
osgViewer::View* view,
WindowManager* wm,
osg::Node* node
) {
osg::Group* group = _createExampleCommon(view, wm, node);
osg::MatrixTransform* watcher = new osg::MatrixTransform();
osg::Group* group = _createExampleCommon(view, wm, node);
osg::MatrixTransform* watcher = new osg::MatrixTransform();
watcher->addChild(wm);
watcher->addChild(wm);
// Setup the main 2D view.
viewer.addView(view);
// Setup the main 2D view.
viewer.addView(view);
view->setSceneData(group);
view->setSceneData(group);
// The view that "watches" the main view.
osgViewer::View* viewWatcher = new osgViewer::View();
// The view that "watches" the main view.
osgViewer::View* viewWatcher = new osgViewer::View();
viewer.addView(viewWatcher);
viewer.addView(viewWatcher);
int w = static_cast<int>(wm->getWidth());
int h = static_cast<int>(wm->getHeight());
viewWatcher->setUpViewInWindow(0, 0, w, h);
int w = static_cast<int>(wm->getWidth());
int h = static_cast<int>(wm->getHeight());
viewWatcher->setUpViewInWindow(0, 0, w, h);
// Setup our parent MatrixTransform so things look right in perspective.
watcher->setMatrix(
osg::Matrix::scale(1.0f, -1.0f, 1000.0f) *
osg::Matrix::rotate(osg::DegreesToRadians(90.0f), osg::Vec3d(1.0f, 0.0f, 0.0f))
);
// Setup our parent MatrixTransform so things look right in perspective.
watcher->setMatrix(
osg::Matrix::scale(1.0f, -1.0f, 1000.0f) *
osg::Matrix::rotate(osg::DegreesToRadians(90.0f), osg::Vec3d(1.0f, 0.0f, 0.0f))
);
watcher->getOrCreateStateSet()->setAttributeAndModes(
new osg::Scissor(0, 0, w, h),
osg::StateAttribute::OVERRIDE
);
watcher->getOrCreateStateSet()->setAttributeAndModes(
new osg::Scissor(0, 0, w, h),
osg::StateAttribute::OVERRIDE
);
osgGA::TrackballManipulator* tb = new osgGA::TrackballManipulator();
osgGA::TrackballManipulator* tb = new osgGA::TrackballManipulator();
warn() << watcher->getMatrix() << std::endl;
warn() << watcher->getMatrix() << std::endl;
/*
const osg::BoundingSphere& bs = watcher->getBound();
/*
const osg::BoundingSphere& bs = watcher->getBound();
tb->setHomePosition(
bs.center() + osg::Vec3(0.0f, -3.5f * bs.radius(), 0.0f),
bs.center(),
osg::Vec3(0.0f, 1.0f, 0.0f)
);
*/
tb->setHomePosition(
bs.center() + osg::Vec3(0.0f, -3.5f * bs.radius(), 0.0f),
bs.center(),
osg::Vec3(0.0f, 1.0f, 0.0f)
);
*/
viewWatcher->setSceneData(watcher);
viewWatcher->setCameraManipulator(tb);
viewWatcher->setSceneData(watcher);
viewWatcher->setCameraManipulator(tb);
return viewer.run();
return viewer.run();
}
bool writeWindowManagerNode(WindowManager* wm) {
osgDB::writeNodeFile(*wm->getParent(0), "osgWidget.osg");
osgDB::writeNodeFile(*wm->getParent(0), "osgWidget.osg");
return true;
return true;
}
}

View File

@ -13,7 +13,7 @@ const char* osgWidgetGetVersion()
const char* osgWidgetGetLibraryName()
{
return "OpenSceneGraph Widget Library";
return "OpenSceneGraph Widget Library";
}
}

View File

@ -10,121 +10,121 @@ _wm(wm) {
}
bool MouseHandler::handle(
const osgGA::GUIEventAdapter& gea,
osgGA::GUIActionAdapter& gaa,
osg::Object* obj,
osg::NodeVisitor* nv
const osgGA::GUIEventAdapter& gea,
osgGA::GUIActionAdapter& gaa,
osg::Object* obj,
osg::NodeVisitor* nv
) {
osgGA::GUIEventAdapter::EventType ev = gea.getEventType();
MouseAction ma = _isMouseEvent(ev);
osgGA::GUIEventAdapter::EventType ev = gea.getEventType();
MouseAction ma = _isMouseEvent(ev);
if(ma) {
// If we're scrolling, we need to inform the WindowManager of that.
_wm->setScrollingMotion(gea.getScrollingMotion());
if(ma) {
// If we're scrolling, we need to inform the WindowManager of that.
_wm->setScrollingMotion(gea.getScrollingMotion());
return (this->*ma)(gea.getX(), gea.getY(), gea.getButton());
}
return false;
return (this->*ma)(gea.getX(), gea.getY(), gea.getButton());
}
return false;
}
bool MouseHandler::_handleMousePush(float x, float y, int button) {
if(button == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mousePushedLeft
);
if(button == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mousePushedLeft
);
else if(button == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mousePushedRight
);
else if(button == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mousePushedRight
);
else if(button == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mousePushedMiddle
);
else if(button == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mousePushedMiddle
);
else return false;
else return false;
}
bool MouseHandler::_handleMouseRelease(float x, float y, int button) {
if(button == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mouseReleasedLeft
);
if(button == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mouseReleasedLeft
);
else if(button == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mouseReleasedRight
);
else if(button == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mouseReleasedRight
);
else if(button == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mouseReleasedMiddle
);
else if(button == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) return _doMouseEvent(
x,
y,
&WindowManager::mouseReleasedMiddle
);
else return false;
else return false;
}
bool MouseHandler::_handleMouseDoubleClick(float x, float y, int button) {
return false;
return false;
}
bool MouseHandler::_handleMouseDrag(float x, float y, int button) {
return _doMouseEvent(x, y, &WindowManager::pointerDrag);
return _doMouseEvent(x, y, &WindowManager::pointerDrag);
}
bool MouseHandler::_handleMouseMove(float x, float y, int button) {
return _doMouseEvent(x, y, &WindowManager::pointerMove);
return _doMouseEvent(x, y, &WindowManager::pointerMove);
}
bool MouseHandler::_handleMouseScroll(float x, float y, int) {
return _doMouseEvent(x, y, &WindowManager::mouseScroll);
return _doMouseEvent(x, y, &WindowManager::mouseScroll);
}
MouseHandler::MouseAction MouseHandler::_isMouseEvent(
osgGA::GUIEventAdapter::EventType ev
osgGA::GUIEventAdapter::EventType ev
) const {
if(ev == osgGA::GUIEventAdapter::PUSH) return
&MouseHandler::_handleMousePush
;
else if(ev == osgGA::GUIEventAdapter::RELEASE) return
&MouseHandler::_handleMouseRelease
;
else if(ev == osgGA::GUIEventAdapter::DOUBLECLICK) return
&MouseHandler::_handleMouseDoubleClick
;
else if(ev == osgGA::GUIEventAdapter::DRAG) return
&MouseHandler::_handleMouseDrag
;
else if(ev == osgGA::GUIEventAdapter::MOVE) return
&MouseHandler::_handleMouseMove
;
else if(ev == osgGA::GUIEventAdapter::SCROLL) return
&MouseHandler::_handleMouseScroll
;
if(ev == osgGA::GUIEventAdapter::PUSH) return
&MouseHandler::_handleMousePush
;
else if(ev == osgGA::GUIEventAdapter::RELEASE) return
&MouseHandler::_handleMouseRelease
;
else if(ev == osgGA::GUIEventAdapter::DOUBLECLICK) return
&MouseHandler::_handleMouseDoubleClick
;
else if(ev == osgGA::GUIEventAdapter::DRAG) return
&MouseHandler::_handleMouseDrag
;
else if(ev == osgGA::GUIEventAdapter::MOVE) return
&MouseHandler::_handleMouseMove
;
else if(ev == osgGA::GUIEventAdapter::SCROLL) return
&MouseHandler::_handleMouseScroll
;
else return 0;
else return 0;
}
bool MouseHandler::_doMouseEvent(float x, float y, MouseEvent me) {
bool handled = (_wm.get()->*me)(x, y);
bool handled = (_wm.get()->*me)(x, y);
// This is called LAST for things like drag, which needs to calculate a mouse difference.
_wm->setPointerXY(x, y);
// This is called LAST for things like drag, which needs to calculate a mouse difference.
_wm->setPointerXY(x, y);
return handled;
return handled;
}
KeyboardHandler::KeyboardHandler(WindowManager* wm):
@ -132,29 +132,29 @@ _wm(wm) {
}
bool KeyboardHandler::handle(
const osgGA::GUIEventAdapter& gea,
osgGA::GUIActionAdapter& gaa,
osg::Object* obj,
osg::NodeVisitor* nv
const osgGA::GUIEventAdapter& gea,
osgGA::GUIActionAdapter& gaa,
osg::Object* obj,
osg::NodeVisitor* nv
) {
osgGA::GUIEventAdapter::EventType ev = gea.getEventType();
osgGA::GUIEventAdapter::EventType ev = gea.getEventType();
if(
ev != osgGA::GUIEventAdapter::KEYDOWN &&
ev != osgGA::GUIEventAdapter::KEYUP
) return false;
if(
ev != osgGA::GUIEventAdapter::KEYDOWN &&
ev != osgGA::GUIEventAdapter::KEYUP
) return false;
int key = gea.getKey();
int keyMask = gea.getModKeyMask();
int key = gea.getKey();
int keyMask = gea.getModKeyMask();
// -1 is the "key invalid" return code.
if(key == -1) return false;
// -1 is the "key invalid" return code.
if(key == -1) return false;
if(ev == osgGA::GUIEventAdapter::KEYDOWN) return _wm->keyDown(key, keyMask);
if(ev == osgGA::GUIEventAdapter::KEYDOWN) return _wm->keyDown(key, keyMask);
else if(ev == osgGA::GUIEventAdapter::KEYUP) return _wm->keyUp(key, keyMask);
else if(ev == osgGA::GUIEventAdapter::KEYUP) return _wm->keyUp(key, keyMask);
return false;
return false;
}
ResizeHandler::ResizeHandler(WindowManager* wm, osg::Camera* camera):
@ -163,28 +163,28 @@ _camera (camera) {
}
bool ResizeHandler::handle(
const osgGA::GUIEventAdapter& gea,
osgGA::GUIActionAdapter& gaa,
osg::Object* obj,
osg::NodeVisitor* nv
const osgGA::GUIEventAdapter& gea,
osgGA::GUIActionAdapter& gaa,
osg::Object* obj,
osg::NodeVisitor* nv
) {
osgGA::GUIEventAdapter::EventType ev = gea.getEventType();
osgGA::GUIEventAdapter::EventType ev = gea.getEventType();
if(ev != osgGA::GUIEventAdapter::RESIZE) return false;
if(ev != osgGA::GUIEventAdapter::RESIZE) return false;
osg::Matrix::value_type w = gea.getWindowWidth();
osg::Matrix::value_type h = gea.getWindowHeight();
osg::Matrix::value_type w = gea.getWindowWidth();
osg::Matrix::value_type h = gea.getWindowHeight();
if(_wm->isInvertedY()) _camera->setProjectionMatrix(
createInvertedYOrthoProjectionMatrix(w, h)
);
if(_wm->isInvertedY()) _camera->setProjectionMatrix(
createInvertedYOrthoProjectionMatrix(w, h)
);
else _camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0f, w, 0.0f, h));
_wm->setSize(w, h);
_wm->resizeAllWindows();
else _camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0f, w, 0.0f, h));
_wm->setSize(w, h);
_wm->resizeAllWindows();
return true;
return true;
}
}

View File

@ -36,36 +36,36 @@ _isManaged (false),
_isStyled (false),
_minWidth (w),
_minHeight (h) {
_name = name.size() ? name : generateRandomName("Widget");
_name = name.size() ? name : generateRandomName("Widget");
if(!_norms.valid()) {
_norms = new PointArray(1);
if(!_norms.valid()) {
_norms = new PointArray(1);
(*_norms)[0].set(0.0f, 0.0f, 1.0f);
(*_norms)[0].normalize();
}
(*_norms)[0].set(0.0f, 0.0f, 1.0f);
(*_norms)[0].normalize();
}
TexCoordArray* texs = new TexCoordArray(4);
TexCoordArray* texs = new TexCoordArray(4);
// Fill our texture coordinates with null stuff for now, since we aren't using them
// until an Image is set at some later point.
std::fill(texs->begin(), texs->end(), osg::Vec2(0.0f, 0.0f));
// Fill our texture coordinates with null stuff for now, since we aren't using them
// until an Image is set at some later point.
std::fill(texs->begin(), texs->end(), osg::Vec2(0.0f, 0.0f));
setUseDisplayList(false);
setDataVariance(osg::Object::DYNAMIC);
setVertexArray(new PointArray(4));
setColorArray(new ColorArray(4));
setNormalArray(_norms.get());
setTexCoordArray(0, texs);
setNormalBinding(osg::Geometry::BIND_OVERALL);
setColorBinding(osg::Geometry::BIND_PER_VERTEX);
addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
setUseDisplayList(false);
setDataVariance(osg::Object::DYNAMIC);
setVertexArray(new PointArray(4));
setColorArray(new ColorArray(4));
setNormalArray(_norms.get());
setTexCoordArray(0, texs);
setNormalBinding(osg::Geometry::BIND_OVERALL);
setColorBinding(osg::Geometry::BIND_PER_VERTEX);
addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
setDimensions(0.0f, 0.0f, w, h);
setColor(1.0f, 1.0f, 1.0f, 1.0f);
setDimensions(0.0f, 0.0f, w, h);
setColor(1.0f, 1.0f, 1.0f, 1.0f);
getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
Widget::Widget(const Widget& widget, const osg::CopyOp& co):
@ -93,432 +93,432 @@ _minHeight (widget._minHeight) {
// This takes an integer value and translates it into a value that will be added to
// the parent window's Z value.
point_type Widget::_calculateZ(unsigned int layer) const {
point_type zRange = 0.0f;
point_type zRange = 0.0f;
if(_parent) zRange = _parent->getZRange();
if(_parent) zRange = _parent->getZRange();
return (static_cast<point_type>(layer) / static_cast<point_type>(LAYER_TOP + 1)) * zRange;
return (static_cast<point_type>(layer) / static_cast<point_type>(LAYER_TOP + 1)) * zRange;
}
WindowManager* Widget::_getWindowManager() const {
if(!_parent) return 0;
if(!_parent) return 0;
return _parent->getWindowManager();
return _parent->getWindowManager();
}
osg::Image* Widget::_getImage() const {
const osg::Texture2D* texture = _texture();
const osg::Texture2D* texture = _texture();
if(texture) return const_cast<osg::Image*>(texture->getImage(0));
if(texture) return const_cast<osg::Image*>(texture->getImage(0));
return 0;
return 0;
}
void Widget::managed(WindowManager* wm) {
if(!wm->isInvertedY()) return;
if(!wm->isInvertedY()) return;
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
osg::Matrix t = osg::Matrix::translate(0.0f, -1.0, 0.0f);
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
osg::Matrix t = osg::Matrix::translate(0.0f, -1.0, 0.0f);
getOrCreateStateSet()->setTextureAttributeAndModes(
0,
new osg::TexMat(t * s),
osg::StateAttribute::ON
);
getOrCreateStateSet()->setTextureAttributeAndModes(
0,
new osg::TexMat(t * s),
osg::StateAttribute::ON
);
}
void Widget::setDimensions(point_type x, point_type y, point_type w, point_type h, point_type z) {
if(w != -1.0f && w < _minWidth) {
warn()
<< "Widget [" << _name
<< "] was asked to set it's width to " << w
<< ", but the minimum width is " << _minWidth
<< "." << std::endl
;
if(w != -1.0f && w < _minWidth) {
warn()
<< "Widget [" << _name
<< "] was asked to set it's width to " << w
<< ", but the minimum width is " << _minWidth
<< "." << std::endl
;
w = _minWidth;
}
w = _minWidth;
}
if(h != -1.0f && h < _minHeight) {
warn()
<< "Widget [" << _name
<< "] was asked to set it's height to " << h
<< ", but the minimum height is " << _minHeight
<< "." << std::endl
;
if(h != -1.0f && h < _minHeight) {
warn()
<< "Widget [" << _name
<< "] was asked to set it's height to " << h
<< ", but the minimum height is " << _minHeight
<< "." << std::endl
;
h = _minHeight;
}
h = _minHeight;
}
PointArray* verts = _verts();
PointArray* verts = _verts();
if(_coordMode == CM_ABSOLUTE) {
// If any of our values are 0, replace them with the current value.
// We could just call getWidth(), etc., but all those dynamic_casts could eventually
// get expensive, so we just use the already-created verts() array directly.
if(x < 0.0f) x = MACRO_WIDGET_X(verts);
if(y < 0.0f) y = MACRO_WIDGET_Y(verts);
if(w < 0.0f) w = MACRO_WIDGET_W(verts);
if(h < 0.0f) h = MACRO_WIDGET_H(verts);
}
if(_coordMode == CM_ABSOLUTE) {
// If any of our values are 0, replace them with the current value.
// We could just call getWidth(), etc., but all those dynamic_casts could eventually
// get expensive, so we just use the already-created verts() array directly.
if(x < 0.0f) x = MACRO_WIDGET_X(verts);
if(y < 0.0f) y = MACRO_WIDGET_Y(verts);
if(w < 0.0f) w = MACRO_WIDGET_W(verts);
if(h < 0.0f) h = MACRO_WIDGET_H(verts);
}
else {
if(x < 0.0f) x = _relCoords[0];
if(y < 0.0f) y = _relCoords[1];
if(w < 0.0f) w = _relCoords[2];
if(h < 0.0f) h = _relCoords[3];
}
else {
if(x < 0.0f) x = _relCoords[0];
if(y < 0.0f) y = _relCoords[1];
if(w < 0.0f) w = _relCoords[2];
if(h < 0.0f) h = _relCoords[3];
}
if(z < 0.0f) z = _calculateZ(_layer);
if(z < 0.0f) z = _calculateZ(_layer);
// Now, we need to determine if the dimensions are actually percentage of the parent's
// size, rather than an absolute values. The Widget must be parented for this to be
// valid, however.
if(_coordMode == CM_RELATIVE) {
XYCoord size;
if(_parent) size = _parent->getSize();
// Now, we need to determine if the dimensions are actually percentage of the parent's
// size, rather than an absolute values. The Widget must be parented for this to be
// valid, however.
if(_coordMode == CM_RELATIVE) {
XYCoord size;
if(_parent) size = _parent->getSize();
if(x >= 0.0f && x <= 1.0f) {
_relCoords[0] = x;
x = size.x() * x;
}
if(x >= 0.0f && x <= 1.0f) {
_relCoords[0] = x;
x = size.x() * x;
}
if(y >= 0.0f && y <= 1.0f) {
_relCoords[1] = y;
if(y >= 0.0f && y <= 1.0f) {
_relCoords[1] = y;
y = size.y() * y;
}
if(w >= 0.0f && w <= 1.0f) {
_relCoords[2] = w;
w = size.x() * w;
}
if(h >= 0.0f && h <= 1.0f) {
_relCoords[3] = h;
h = size.y() * h;
}
}
y = size.y() * y;
}
if(w >= 0.0f && w <= 1.0f) {
_relCoords[2] = w;
w = size.x() * w;
}
if(h >= 0.0f && h <= 1.0f) {
_relCoords[3] = h;
h = size.y() * h;
}
}
(*verts)[LL].set(x, y, z);
(*verts)[LR].set(x + w, y, z);
(*verts)[UR].set(x + w, y + h, z);
(*verts)[UL].set(x, y + h, z);
(*verts)[LL].set(x, y, z);
(*verts)[LR].set(x + w, y, z);
(*verts)[UR].set(x + w, y + h, z);
(*verts)[UL].set(x, y + h, z);
}
void Widget::setColor(color_type r, color_type g, color_type b, color_type a, Corner p) {
ColorArray* cols = _cols();
ColorArray* cols = _cols();
if(p == ALL_CORNERS) {
(*cols)[LL].set(r, g, b, a);
(*cols)[LR].set(r, g, b, a);
(*cols)[UR].set(r, g, b, a);
(*cols)[UL].set(r, g, b, a);
}
if(p == ALL_CORNERS) {
(*cols)[LL].set(r, g, b, a);
(*cols)[LR].set(r, g, b, a);
(*cols)[UR].set(r, g, b, a);
(*cols)[UL].set(r, g, b, a);
}
else (*cols)[convertCorner(p)].set(r, g, b, a);
else (*cols)[convertCorner(p)].set(r, g, b, a);
}
void Widget::addColor(color_type r, color_type g, color_type b, color_type a, Corner p) {
ColorArray* cols = _cols();
if(p == ALL_CORNERS) {
(*cols)[LL] += Color(r, g, b, a);
(*cols)[LR] += Color(r, g, b, a);
(*cols)[UR] += Color(r, g, b, a);
(*cols)[UL] += Color(r, g, b, a);
}
ColorArray* cols = _cols();
if(p == ALL_CORNERS) {
(*cols)[LL] += Color(r, g, b, a);
(*cols)[LR] += Color(r, g, b, a);
(*cols)[UR] += Color(r, g, b, a);
(*cols)[UL] += Color(r, g, b, a);
}
else (*cols)[convertCorner(p)] += Color(r, g, b, a);
else (*cols)[convertCorner(p)] += Color(r, g, b, a);
}
void Widget::setTexCoord(texcoord_type tx, texcoord_type ty, Corner p) {
TexCoordArray* texs = _texs();
TexCoordArray* texs = _texs();
if(p == ALL_CORNERS) {
(*texs)[LL].set(tx, ty);
(*texs)[LR].set(tx, ty);
(*texs)[UR].set(tx, ty);
(*texs)[UL].set(tx, ty);
}
if(p == ALL_CORNERS) {
(*texs)[LL].set(tx, ty);
(*texs)[LR].set(tx, ty);
(*texs)[UR].set(tx, ty);
(*texs)[UL].set(tx, ty);
}
else (*texs)[convertCorner(p)].set(tx, ty);
else (*texs)[convertCorner(p)].set(tx, ty);
}
void Widget::setTexCoordRegion(point_type x, point_type y, point_type w, point_type h) {
osg::Image* image = _image();
osg::Image* image = _image();
if(!image) return;
if(!image) return;
point_type tw = image->s();
point_type th = image->t();
point_type tw = image->s();
point_type th = image->t();
TexCoordArray* texs = _texs();
TexCoordArray* texs = _texs();
// Set the LOWER_LEFT point.
XYCoord t(x / tw, y / tw);
// Set the LOWER_LEFT point.
XYCoord t(x / tw, y / tw);
(*texs)[UL] = t;
// Set the LOWER_RIGHT point.
t += XYCoord(w / tw, 0.0f);
(*texs)[UL] = t;
// Set the LOWER_RIGHT point.
t += XYCoord(w / tw, 0.0f);
(*texs)[UR] = t;
(*texs)[UR] = t;
// Set the UPPER_RIGHT point.
t += XYCoord(0.0f, h / th);
// Set the UPPER_RIGHT point.
t += XYCoord(0.0f, h / th);
(*texs)[LR] = t;
(*texs)[LR] = t;
// Set the UPPER_LEFT point.
t += XYCoord(-(w / tw), 0.0f);
// Set the UPPER_LEFT point.
t += XYCoord(-(w / tw), 0.0f);
(*texs)[LL] = t;
(*texs)[LL] = t;
}
void Widget::setTexCoordWrapHorizontal() {
osg::Image* image = _image();
osg::Texture2D* texture = _texture();
osg::Image* image = _image();
osg::Texture2D* texture = _texture();
if(!image || !texture || image->s() == 0.0f) return;
if(!image || !texture || image->s() == 0.0f) return;
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
setTexCoord(getWidth() / image->s(), 0.0f, LOWER_RIGHT);
setTexCoord(getWidth() / image->s(), 1.0f, UPPER_RIGHT);
setTexCoord(getWidth() / image->s(), 0.0f, LOWER_RIGHT);
setTexCoord(getWidth() / image->s(), 1.0f, UPPER_RIGHT);
}
void Widget::setTexCoordWrapVertical() {
osg::Image* image = _image();
osg::Texture2D* texture = _texture();
osg::Image* image = _image();
osg::Texture2D* texture = _texture();
if(!image || !texture || image->t() == 0.0f) return;
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
if(!image || !texture || image->t() == 0.0f) return;
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
setTexCoord(0.0f, getHeight() / image->t(), UPPER_LEFT);
setTexCoord(1.0f, getHeight() / image->t(), UPPER_RIGHT);
setTexCoord(0.0f, getHeight() / image->t(), UPPER_LEFT);
setTexCoord(1.0f, getHeight() / image->t(), UPPER_RIGHT);
}
XYCoord Widget::localXY(double _x, double _y) const {
if(!_parent) return XYCoord(_x, _y);
if(!_parent) return XYCoord(_x, _y);
return _parent->localXY(_x, _y) - getOrigin();
return _parent->localXY(_x, _y) - getOrigin();
}
bool Widget::setImage(osg::Image* image, bool setTexCoords) {
if(!image) {
warn() << "Widget [" << _name << "] cannot use a NULL image." << std::endl;
if(!image) {
warn() << "Widget [" << _name << "] cannot use a NULL image." << std::endl;
return false;
}
return false;
}
osg::Texture2D* texture = new osg::Texture2D();
texture->setDataVariance(osg::Object::DYNAMIC);
texture->setImage(0, image);
osg::Texture2D* texture = new osg::Texture2D();
texture->setDataVariance(osg::Object::DYNAMIC);
texture->setImage(0, image);
getOrCreateStateSet()->setTextureAttributeAndModes(
0,
texture,
osg::StateAttribute::ON
);
getOrCreateStateSet()->setTextureAttributeAndModes(
0,
texture,
osg::StateAttribute::ON
);
if(setTexCoords) {
setTexCoord(0.0f, 0.0f, LOWER_LEFT);
setTexCoord(1.0f, 0.0f, LOWER_RIGHT);
setTexCoord(1.0f, 1.0f, UPPER_RIGHT);
setTexCoord(0.0f, 1.0f, UPPER_LEFT);
}
if(setTexCoords) {
setTexCoord(0.0f, 0.0f, LOWER_LEFT);
setTexCoord(1.0f, 0.0f, LOWER_RIGHT);
setTexCoord(1.0f, 1.0f, UPPER_RIGHT);
setTexCoord(0.0f, 1.0f, UPPER_LEFT);
}
return true;
return true;
}
bool Widget::setImage(const std::string& filePath, bool setTexCoords) {
if(!osgDB::findDataFile(filePath).size()) {
warn()
<< "Widget [" << _name
<< "] cannot find file " << filePath
<< " to set as it's Image." << std::endl
;
if(!osgDB::findDataFile(filePath).size()) {
warn()
<< "Widget [" << _name
<< "] cannot find file " << filePath
<< " to set as it's Image." << std::endl
;
return false;
}
return false;
}
return setImage(osgDB::readImageFile(filePath), setTexCoords);
return setImage(osgDB::readImageFile(filePath), setTexCoords);
}
void Widget::setPadding(point_type pad) {
_padLeft = _padRight = _padTop = _padBottom = pad;
_padLeft = _padRight = _padTop = _padBottom = pad;
}
void Widget::addX(point_type x) {
if(_coordMode == CM_ABSOLUTE) setDimensions(MACRO_WIDGET_X(_verts()) + x);
if(_coordMode == CM_ABSOLUTE) setDimensions(MACRO_WIDGET_X(_verts()) + x);
else setDimensions(_relCoords[0] + x);
else setDimensions(_relCoords[0] + x);
}
void Widget::addY(point_type y) {
if(_coordMode == CM_ABSOLUTE) setDimensions(-1.0f, MACRO_WIDGET_Y(_verts()) + y);
if(_coordMode == CM_ABSOLUTE) setDimensions(-1.0f, MACRO_WIDGET_Y(_verts()) + y);
else setDimensions(-1.0f, _relCoords[1] + y);
else setDimensions(-1.0f, _relCoords[1] + y);
}
void Widget::addWidth(point_type w) {
if(_coordMode == CM_ABSOLUTE) setDimensions(-1.0f, -1.0f, MACRO_WIDGET_W(_verts()) + w);
if(_coordMode == CM_ABSOLUTE) setDimensions(-1.0f, -1.0f, MACRO_WIDGET_W(_verts()) + w);
else setDimensions(-1.0f, -1.0f, _relCoords[2] + w);
else setDimensions(-1.0f, -1.0f, _relCoords[2] + w);
}
void Widget::addHeight(point_type h) {
if(_coordMode == CM_ABSOLUTE) setDimensions(
-1.0f,
-1.0f,
-1.0f,
MACRO_WIDGET_H(_verts()) + h
);
if(_coordMode == CM_ABSOLUTE) setDimensions(
-1.0f,
-1.0f,
-1.0f,
MACRO_WIDGET_H(_verts()) + h
);
else setDimensions(-1.0f, -1.0f, -1.0f, _relCoords[3] + h);
else setDimensions(-1.0f, -1.0f, -1.0f, _relCoords[3] + h);
}
void Widget::addOrigin(point_type x, point_type y) {
if(_coordMode == CM_ABSOLUTE) {
PointArray* verts = _verts();
if(_coordMode == CM_ABSOLUTE) {
PointArray* verts = _verts();
setDimensions(
MACRO_WIDGET_X(verts) + x,
MACRO_WIDGET_Y(verts) + y
);
}
setDimensions(
MACRO_WIDGET_X(verts) + x,
MACRO_WIDGET_Y(verts) + y
);
}
else setDimensions(_relCoords[0] + x, _relCoords[1] + y);
else setDimensions(_relCoords[0] + x, _relCoords[1] + y);
}
void Widget::addSize(point_type w, point_type h) {
if(_coordMode == CM_ABSOLUTE) {
PointArray* verts = _verts();
if(_coordMode == CM_ABSOLUTE) {
PointArray* verts = _verts();
setDimensions(
-1.0f,
-1.0f,
MACRO_WIDGET_W(verts) + w,
MACRO_WIDGET_H(verts) + h
);
}
else setDimensions(-1.0f, -1.0f, _relCoords[2] + w, _relCoords[3] + h);
setDimensions(
-1.0f,
-1.0f,
MACRO_WIDGET_W(verts) + w,
MACRO_WIDGET_H(verts) + h
);
}
else setDimensions(-1.0f, -1.0f, _relCoords[2] + w, _relCoords[3] + h);
}
point_type Widget::getWidth() const {
const PointArray* verts = _verts();
return MACRO_WIDGET_W(verts);
const PointArray* verts = _verts();
return MACRO_WIDGET_W(verts);
}
point_type Widget::getHeight() const {
const PointArray* verts = _verts();
return MACRO_WIDGET_H(verts);
const PointArray* verts = _verts();
return MACRO_WIDGET_H(verts);
}
point_type Widget::getX() const {
return MACRO_WIDGET_X(_verts());
return MACRO_WIDGET_X(_verts());
}
point_type Widget::getY() const {
return MACRO_WIDGET_Y(_verts());
return MACRO_WIDGET_Y(_verts());
}
point_type Widget::getZ() const {
return (*_verts())[LL].z();
return (*_verts())[LL].z();
}
point_type Widget::getPadHorizontal() const {
return _padLeft + _padRight;
return _padLeft + _padRight;
}
point_type Widget::getPadVertical() const {
return _padTop + _padBottom;
return _padTop + _padBottom;
}
const Point& Widget::getPoint(Corner p) const {
Corner point = p;
Corner point = p;
if(p == ALL_CORNERS) point = UPPER_LEFT;
if(p == ALL_CORNERS) point = UPPER_LEFT;
return (*_verts())[convertCorner(point)];
return (*_verts())[convertCorner(point)];
}
const Color& Widget::getColor(Corner p) const {
Corner point = p;
Corner point = p;
if(p == ALL_CORNERS) point = UPPER_LEFT;
if(p == ALL_CORNERS) point = UPPER_LEFT;
return (*_cols())[convertCorner(point)];
return (*_cols())[convertCorner(point)];
}
const TexCoord& Widget::getTexCoord(Corner p) const {
Corner point = p;
Corner point = p;
if(p == ALL_CORNERS) point = UPPER_LEFT;
if(p == ALL_CORNERS) point = UPPER_LEFT;
return (*_texs())[convertCorner(point)];
return (*_texs())[convertCorner(point)];
}
// This converts our points back and forth depding on whether or not we're in an
// inverted-Y WindowManager.
Widget::Corner Widget::convertCorner(Corner p) const {
const WindowManager* wm = getWindowManager();
const WindowManager* wm = getWindowManager();
if(!wm || !wm->isInvertedY()) return p;
if(p == UPPER_LEFT) return LOWER_LEFT;
if(!wm || !wm->isInvertedY()) return p;
if(p == UPPER_LEFT) return LOWER_LEFT;
else if(p == UPPER_RIGHT) return LOWER_RIGHT;
else if(p == UPPER_RIGHT) return LOWER_RIGHT;
else if(p == LOWER_LEFT) return UPPER_LEFT;
else if(p == LOWER_LEFT) return UPPER_LEFT;
else if(p == LOWER_RIGHT) return UPPER_RIGHT;
else if(p == LOWER_RIGHT) return UPPER_RIGHT;
else return p;
else return p;
}
Color Widget::getImageColorAtXY(point_type x, point_type y) const {
const osg::Image* image = _image();
const osg::Image* image = _image();
if(!image) return Color();
if(!image) return Color();
const TexCoordArray* texs = _texs();
const TexCoordArray* texs = _texs();
/*
How do we do this? First we need to make sure our right side is larger
than our left side and that the top side is larger the bottom; otherwise,
they're using strange tex coords.
/*
How do we do this? First we need to make sure our right side is larger
than our left side and that the top side is larger the bottom; otherwise,
they're using strange tex coords.
Then, we find the percent area being used in both dimensions. We multiply
the XY values by those ratios and then add those values to the "offsets."
*/
Then, we find the percent area being used in both dimensions. We multiply
the XY values by those ratios and then add those values to the "offsets."
*/
point_type width = fabs((*texs)[LR].x() - (*texs)[LL].x());
point_type height = fabs((*texs)[LR].y() - (*texs)[UR].y());
point_type width = fabs((*texs)[LR].x() - (*texs)[LL].x());
point_type height = fabs((*texs)[LR].y() - (*texs)[UR].y());
point_type X = ((x / getWidth()) * width) + (*texs)[LL].x();
point_type Y = (((getHeight() - y) / getHeight()) * height) + (*texs)[UR].y();
return image->getColor(TexCoord(X, Y));
point_type X = ((x / getWidth()) * width) + (*texs)[LL].x();
point_type Y = (((getHeight() - y) / getHeight()) * height) + (*texs)[UR].y();
return image->getColor(TexCoord(X, Y));
}
bool Widget::isPaddingUniform() const {
return
_padLeft == _padRight &&
_padLeft == _padTop &&
_padLeft == _padBottom
;
return
_padLeft == _padRight &&
_padLeft == _padTop &&
_padLeft == _padBottom
;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -15,11 +15,11 @@
namespace osgWidget {
WindowManager::WindowManager(
osgViewer::View* view,
point_type width,
point_type height,
unsigned int nodeMask,
unsigned int flags
osgViewer::View* view,
point_type width,
point_type height,
unsigned int nodeMask,
unsigned int flags
):
_width (width),
_height (height),
@ -42,65 +42,65 @@ _middleDown (false),
_rightDown (false),
_scrolling (osgGA::GUIEventAdapter::SCROLL_NONE),
_styleManager (new StyleManager()) {
_name = generateRandomName("WindowManager");
_name = generateRandomName("WindowManager");
if(_flags & WM_USE_LUA) {
_lua = new LuaEngine(this);
if(_flags & WM_USE_LUA) {
_lua = new LuaEngine(this);
if(!_lua->initialize()) warn() << "Error creating LuaEngine." << std::endl;
}
if(!_lua->initialize()) warn() << "Error creating LuaEngine." << std::endl;
}
if(_flags & WM_USE_PYTHON) {
_python = new PythonEngine(this);
if(_flags & WM_USE_PYTHON) {
_python = new PythonEngine(this);
if(!_python->initialize()) warn() << "Error creating PythonEngine." << std::endl;
}
if(!_python->initialize()) warn() << "Error creating PythonEngine." << std::endl;
}
// Setup our picking debug (is debug the right word here?) Window...
if(_flags & WM_PICK_DEBUG) {
_pickWindow = new Box("PickWindow", Box::VERTICAL);
Label* label = new Label("PickLabel");
// Setup our picking debug (is debug the right word here?) Window...
if(_flags & WM_PICK_DEBUG) {
_pickWindow = new Box("PickWindow", Box::VERTICAL);
Label* label = new Label("PickLabel");
label->setFontSize(13);
label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
label->setFont("fonts/VeraMono.ttf");
label->setPadding(5.0f);
label->setCanFill(true);
label->setFontSize(13);
label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
label->setFont("fonts/VeraMono.ttf");
label->setPadding(5.0f);
label->setCanFill(true);
_pickWindow->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.85f);
_pickWindow->addWidget(label);
_pickWindow->setNodeMask(~_nodeMask);
_pickWindow->removeEventMask(EVENT_MASK_FOCUS);
_pickWindow->setStrata(Window::STRATA_FOREGROUND);
_pickWindow->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.85f);
_pickWindow->addWidget(label);
_pickWindow->setNodeMask(~_nodeMask);
_pickWindow->removeEventMask(EVENT_MASK_FOCUS);
_pickWindow->setStrata(Window::STRATA_FOREGROUND);
addChild(_pickWindow.get());
addChild(_pickWindow.get());
_updatePickWindow(0, 0, 0);
}
_updatePickWindow(0, 0, 0);
}
if(!(_flags & WM_NO_BETA_WARN)) {
Box* box = new Box("BetaWarningBox", Box::VERTICAL);
Label* label = new Label("BetaWarning");
if(!(_flags & WM_NO_BETA_WARN)) {
Box* box = new Box("BetaWarningBox", Box::VERTICAL);
Label* label = new Label("BetaWarning");
label->setFontSize(15);
label->setFontColor(0.0f, 0.0f, 1.0f, 1.0f);
label->setFont("fonts/arial.ttf");
label->setPadding(5.0f);
label->setCanFill(true);
label->setLabel("This is BETA software! Please see: http://osgwidget.googlecode.com");
label->setFontSize(15);
label->setFontColor(0.0f, 0.0f, 1.0f, 1.0f);
label->setFont("fonts/arial.ttf");
label->setPadding(5.0f);
label->setCanFill(true);
label->setLabel("This is BETA software! Please see: http://osgwidget.googlecode.com");
box->getBackground()->setColor(1.0f, 0.7f, 0.0f, 1.0f);
box->addWidget(label);
box->setNodeMask(~_nodeMask);
box->removeEventMask(EVENT_MASK_FOCUS);
box->setStrata(Window::STRATA_BACKGROUND);
box->setOrigin(0.0f, 0.0f);
box->getBackground()->setColor(1.0f, 0.7f, 0.0f, 1.0f);
box->addWidget(label);
box->setNodeMask(~_nodeMask);
box->removeEventMask(EVENT_MASK_FOCUS);
box->setStrata(Window::STRATA_BACKGROUND);
box->setOrigin(0.0f, 0.0f);
addChild(box);
box->resizePercent(100.0f, 0.0f);
}
addChild(box);
box->resizePercent(100.0f, 0.0f);
}
}
WindowManager::WindowManager(const WindowManager& wm, const osg::CopyOp& co):
@ -108,480 +108,480 @@ osg::Switch(wm, co) {
}
WindowManager::~WindowManager() {
if(_flags & WM_USE_LUA) _lua->close();
if(_flags & WM_USE_PYTHON) _python->close();
if(_flags & WM_USE_LUA) _lua->close();
if(_flags & WM_USE_PYTHON) _python->close();
}
void WindowManager::setEventFromInterface(Event& ev, EventInterface* ei) {
Widget* widget = dynamic_cast<Widget*>(ei);
Window* window = dynamic_cast<Window*>(ei);
Widget* widget = dynamic_cast<Widget*>(ei);
Window* window = dynamic_cast<Window*>(ei);
if(widget) {
ev._window = widget->getParent();
ev._widget = widget;
}
if(widget) {
ev._window = widget->getParent();
ev._widget = widget;
}
else if(window) ev._window = window;
else if(window) ev._window = window;
}
bool WindowManager::_handleMousePushed(float x, float y, bool& down) {
down = true;
down = true;
Event ev(this, EVENT_MOUSE_PUSH);
Event ev(this, EVENT_MOUSE_PUSH);
WidgetList widgetList;
WidgetList widgetList;
if(!pickAtXY(x, y, widgetList)) return false;
if(!pickAtXY(x, y, widgetList)) return false;
ev.makeMouse(x, y);
ev.makeMouse(x, y);
_lastPush = getFirstEventInterface(widgetList, ev);
_lastPush = getFirstEventInterface(widgetList, ev);
if(!_lastPush) return false;
if(!_lastPush) return false;
bool handled = _lastPush->callMethodAndCallbacks(ev);
bool handled = _lastPush->callMethodAndCallbacks(ev);
if(_focusMode != PFM_SLOPPY) {
if(ev._window) {
Window* topmostWindow = ev._window->getTopmostParent();
if(_focusMode != PFM_SLOPPY) {
if(ev._window) {
Window* topmostWindow = ev._window->getTopmostParent();
setFocused(topmostWindow);
if(ev._widget) topmostWindow->setFocused(ev._widget);
}
setFocused(topmostWindow);
if(ev._widget) topmostWindow->setFocused(ev._widget);
}
// If the user wants to be able to "unfocus" the last Window.
else if(_focusMode == PFM_UNFOCUS) setFocused(0);
}
// If the user wants to be able to "unfocus" the last Window.
else if(_focusMode == PFM_UNFOCUS) setFocused(0);
}
return handled;
return handled;
}
bool WindowManager::_handleMouseReleased(float x, float y, bool& down) {
down = false;
down = false;
// If were were in a drag state, reset our boolean flag.
// if(_lastDrag) _lastDrag = 0;
// If were were in a drag state, reset our boolean flag.
// if(_lastDrag) _lastDrag = 0;
if(!_lastPush) return false;
if(!_lastPush) return false;
// By design, we can only release an EventInterface we previously pressed.
// Whether or not we're ON the EventInterface when the release occurs isn't important.
Event ev(this, EVENT_MOUSE_RELEASE);
// By design, we can only release an EventInterface we previously pressed.
// Whether or not we're ON the EventInterface when the release occurs isn't important.
Event ev(this, EVENT_MOUSE_RELEASE);
setEventFromInterface(ev, _lastPush);
setEventFromInterface(ev, _lastPush);
bool handled = _lastPush->callMethodAndCallbacks(ev);
bool handled = _lastPush->callMethodAndCallbacks(ev);
_lastPush = 0;
_lastPush = 0;
return handled;
return handled;
}
void WindowManager::_getPointerXYDiff(float& x, float& y) {
x -= _lastX;
x -= _lastX;
if(isInvertedY()) y = -(y - _lastY);
if(isInvertedY()) y = -(y - _lastY);
else y -= _lastY;
else y -= _lastY;
}
void WindowManager::_updatePickWindow(const WidgetList* wl, point_type x, point_type y) {
Label* label = dynamic_cast<Label*>(_pickWindow->getByName("PickLabel"));
Label* label = dynamic_cast<Label*>(_pickWindow->getByName("PickLabel"));
if(!wl) {
setValue(0, false);
if(!wl) {
setValue(0, false);
return;
}
return;
}
setValue(0, true);
setValue(0, true);
std::stringstream ss;
std::stringstream ss;
point_type xdiff = x;
point_type ydiff = y;
point_type xdiff = x;
point_type ydiff = y;
_getPointerXYDiff(xdiff, ydiff);
_getPointerXYDiff(xdiff, ydiff);
ss
<< "At XY Coords: " << x << ", " << _height - y
<< " ( diff " << xdiff << ", " << ydiff << " )"
<< std::endl
;
ss
<< "At XY Coords: " << x << ", " << _height - y
<< " ( diff " << xdiff << ", " << ydiff << " )"
<< std::endl
;
const Window* parent = wl->back()->getParent();
const Window* parent = wl->back()->getParent();
ss
<< "Window: " << parent->getName()
<< " ( xyz " << parent->getPosition() << " )"
<< " { zRange " << parent->getZRange() << " }"
<< " < size " << parent->getSize() << " >"
<< " EventMask: " << std::hex << parent->getEventMask()
<< std::endl
;
ss
<< "Window: " << parent->getName()
<< " ( xyz " << parent->getPosition() << " )"
<< " { zRange " << parent->getZRange() << " }"
<< " < size " << parent->getSize() << " >"
<< " EventMask: " << std::hex << parent->getEventMask()
<< std::endl
;
for(WidgetList::const_iterator i = wl->begin(); i != wl->end(); i++) {
Widget* widget = i->get();
for(WidgetList::const_iterator i = wl->begin(); i != wl->end(); i++) {
Widget* widget = i->get();
ss
<< " - " << widget->getName()
<< " ( xyz " << widget->getPosition() << " )"
<< " [ XYZ " << widget->getPosition() * parent->getMatrix()
<< " ] < size " << widget->getSize() << " >"
<< " EventMask: " << std::hex << widget->getEventMask()
<< std::endl
;
}
ss
<< " - " << widget->getName()
<< " ( xyz " << widget->getPosition() << " )"
<< " [ XYZ " << widget->getPosition() * parent->getMatrix()
<< " ] < size " << widget->getSize() << " >"
<< " EventMask: " << std::hex << widget->getEventMask()
<< std::endl
;
}
label->setLabel(ss.str());
label->setLabel(ss.str());
XYCoord size = label->getTextSize();
XYCoord size = label->getTextSize();
_pickWindow->resize(size.x() + 10.0f, size.y() + 10.0f);
_pickWindow->setOrigin(5.0f, _height - _pickWindow->getHeight() - 5.0f);
_pickWindow->update();
_pickWindow->resize(size.x() + 10.0f, size.y() + 10.0f);
_pickWindow->setOrigin(5.0f, _height - _pickWindow->getHeight() - 5.0f);
_pickWindow->update();
}
void WindowManager::childInserted(unsigned int i) {
Window* window = dynamic_cast<Window*>(getChild(i));
Window* window = dynamic_cast<Window*>(getChild(i));
if(!window) return;
if(!window) return;
_objects.push_back(window);
_objects.push_back(window);
window->_index = i;
window->_index = i;
setFocused(window);
setFocused(window);
window->setNodeMask(_nodeMask);
window->managed(this);
window->setNodeMask(_nodeMask);
window->managed(this);
for(Window::Iterator w = window->begin(); w != window->end(); w++) if(w->valid()) {
_styleManager->applyStyles(w->get());
}
for(Window::Iterator w = window->begin(); w != window->end(); w++) if(w->valid()) {
_styleManager->applyStyles(w->get());
}
_styleManager->applyStyles(window);
_styleManager->applyStyles(window);
}
void WindowManager::childRemoved(unsigned int start, unsigned int end) {
while(start < end) {
Window* window = getByIndex(start);
while(start < end) {
Window* window = getByIndex(start);
if(!window) continue;
if(!window) continue;
if(_remove(window)) {
window->_index = -1;
if(_remove(window)) {
window->_index = -1;
window->unmanaged(this);
}
window->unmanaged(this);
}
start++;
}
start++;
}
}
// This method performs intersection testing at the given XY coords, and returns true if
// any intersections were found. It will break after processing the first pickable Window
// it finds.
bool WindowManager::pickAtXY(float x, float y, WidgetList& wl) {
Intersections intr;
Intersections intr;
if(_view->computeIntersections(x, y, intr, _nodeMask)) {
// Get the first Window at the XY coordinates; if you want a Window to be
// non-pickable, set the NodeMask to something else.
Window* activeWin = 0;
if(_view->computeIntersections(x, y, intr, _nodeMask)) {
// Get the first Window at the XY coordinates; if you want a Window to be
// non-pickable, set the NodeMask to something else.
Window* activeWin = 0;
// Iterate over every picked result and create a list of Widgets that belong
// to that Window.
for(Intersections::iterator i = intr.begin(); i != intr.end(); i++) {
Window* win = dynamic_cast<Window*>(i->nodePath.back()->getParent(0));
// Iterate over every picked result and create a list of Widgets that belong
// to that Window.
for(Intersections::iterator i = intr.begin(); i != intr.end(); i++) {
Window* win = dynamic_cast<Window*>(i->nodePath.back()->getParent(0));
// Make sure that our window is valid, and that our pick is within the
// "visible area" of the Window.
if(
(!win || win->getVisibilityMode() == Window::VM_PARTIAL) &&
!win->isPointerXYWithinVisible(x, y)
) continue;
// Make sure that our window is valid, and that our pick is within the
// "visible area" of the Window.
if(
(!win || win->getVisibilityMode() == Window::VM_PARTIAL) &&
!win->isPointerXYWithinVisible(x, y)
) continue;
// Set our activeWin, so that we know when we've got all the Widgets
// that belong to it.
if(!activeWin) activeWin = win;
// Set our activeWin, so that we know when we've got all the Widgets
// that belong to it.
if(!activeWin) activeWin = win;
// If we've found a new Widnow, break out!
else if(activeWin != win) break;
// If we've found a new Widnow, break out!
else if(activeWin != win) break;
Widget* widget = dynamic_cast<Widget*>(i->drawable.get());
Widget* widget = dynamic_cast<Widget*>(i->drawable.get());
if(!widget) continue;
if(!widget) continue;
// We need to return a list of every Widget that was picked, so
// that the handler can operate on it accordingly.
else wl.push_back(widget);
}
// We need to return a list of every Widget that was picked, so
// that the handler can operate on it accordingly.
else wl.push_back(widget);
}
if(wl.size()) {
// Potentially VERY expensive; only to be used for debugging. :)
if(_flags & WM_PICK_DEBUG) _updatePickWindow(&wl, x, y);
if(wl.size()) {
// Potentially VERY expensive; only to be used for debugging. :)
if(_flags & WM_PICK_DEBUG) _updatePickWindow(&wl, x, y);
return true;
}
}
return true;
}
}
if(_flags & WM_PICK_DEBUG) _updatePickWindow(0, x, y);
return false;
if(_flags & WM_PICK_DEBUG) _updatePickWindow(0, x, y);
return false;
}
bool WindowManager::setFocused(Window* window) {
Event ev(this);
Event ev(this);
ev._window = window;
// Inform the previously focused Window that it is going to be unfocused.
if(_focused.valid()) _focused->callMethodAndCallbacks(ev.makeType(EVENT_UNFOCUS));
ev._window = window;
// Inform the previously focused Window that it is going to be unfocused.
if(_focused.valid()) _focused->callMethodAndCallbacks(ev.makeType(EVENT_UNFOCUS));
_focused = window;
_focused = window;
if(!window || !window->canFocus()) return false;
if(!window || !window->canFocus()) return false;
// Build a vector of every Window that is focusable, in the foreground, and in the
// background. All these Windows are handled differently.
Vector focusable;
Vector bg;
Vector fg;
// Build a vector of every Window that is focusable, in the foreground, and in the
// background. All these Windows are handled differently.
Vector focusable;
Vector bg;
Vector fg;
for(ConstIterator it = begin(); it != end(); it++) if(it->valid()) {
Window* w = it->get();
for(ConstIterator it = begin(); it != end(); it++) if(it->valid()) {
Window* w = it->get();
if(w->getStrata() == Window::STRATA_FOREGROUND) fg.push_back(w);
if(w->getStrata() == Window::STRATA_FOREGROUND) fg.push_back(w);
else if(w->getStrata() == Window::STRATA_BACKGROUND) bg.push_back(w);
else focusable.push_back(w);
}
else if(w->getStrata() == Window::STRATA_BACKGROUND) bg.push_back(w);
else focusable.push_back(w);
}
// After this call to sort, the internal objects will be arranged such that the
// previously focused window is the first, followed by all other Windows in
// descending order.
std::sort(focusable.begin(), focusable.end(), WindowZCompare());
// After this call to sort, the internal objects will be arranged such that the
// previously focused window is the first, followed by all other Windows in
// descending order.
std::sort(focusable.begin(), focusable.end(), WindowZCompare());
// This is the depth range for each Window. Each Window object must be informed of
// the Z space allocated to it so that it can properly arrange it's children. We
// add 2 additional Windows here for anything that should appear in the background
// and foreground areas.
matrix_type zRange = (_zNear - _zFar) / (focusable.size() + 2.0f);
// This is the depth range for each Window. Each Window object must be informed of
// the Z space allocated to it so that it can properly arrange it's children. We
// add 2 additional Windows here for anything that should appear in the background
// and foreground areas.
matrix_type zRange = (_zNear - _zFar) / (focusable.size() + 2.0f);
// Our offset for the following for() loop.
unsigned int i = 3;
// Our offset for the following for() loop.
unsigned int i = 3;
// Handle all of our focusable Windows.
for(Iterator w = focusable.begin(); w != focusable.end(); w++) {
Window* win = w->get();
// Handle all of our focusable Windows.
for(Iterator w = focusable.begin(); w != focusable.end(); w++) {
Window* win = w->get();
// Set our newly focused Window as the topmost element.
if(*w == window) win->_z = -zRange * 2.0f;
// Set our newly focused Window as the topmost element.
if(*w == window) win->_z = -zRange * 2.0f;
// Set the current Z of the remaining Windows and set their zRange so that
// they can update their own children.
else {
win->_z = -zRange * i;
// Set the current Z of the remaining Windows and set their zRange so that
// they can update their own children.
else {
win->_z = -zRange * i;
i++;
}
}
i++;
}
}
// Handled our special BACKGROUND Windows.
for(Iterator w = bg.begin(); w != bg.end(); w++) w->get()->_z = -zRange * i;
// Handle our special FOREGOUND Windows.
for(Iterator w = fg.begin(); w != fg.end(); w++) w->get()->_z = -zRange;
// Update every window, regardless.
for(Iterator w = begin(); w != end(); w++) {
Window* win = w->get();
win->_zRange = zRange;
// Handled our special BACKGROUND Windows.
for(Iterator w = bg.begin(); w != bg.end(); w++) w->get()->_z = -zRange * i;
// Handle our special FOREGOUND Windows.
for(Iterator w = fg.begin(); w != fg.end(); w++) w->get()->_z = -zRange;
// Update every window, regardless.
for(Iterator w = begin(); w != end(); w++) {
Window* win = w->get();
win->_zRange = zRange;
win->update();
}
win->update();
}
_focused->callMethodAndCallbacks(ev.makeType(EVENT_FOCUS));
_focused->callMethodAndCallbacks(ev.makeType(EVENT_FOCUS));
return true;
return true;
}
void WindowManager::setPointerXY(float x, float y) {
float xdiff = x;
float ydiff = y;
float xdiff = x;
float ydiff = y;
_getPointerXYDiff(xdiff, ydiff);
_getPointerXYDiff(xdiff, ydiff);
// If ydiff isn't NEAR 0 (floating point booleans aren't 100% reliable, but that
// doesn't matter in our case), assume we have either up or down movement.
if(ydiff != 0.0f) _lastVertical = ydiff > 0.0f ? PD_UP : PD_DOWN;
else _lastVertical = PD_NONE;
// If ydiff isn't NEAR 0 (floating point booleans aren't 100% reliable, but that
// doesn't matter in our case), assume we have either up or down movement.
if(ydiff != 0.0f) _lastVertical = ydiff > 0.0f ? PD_UP : PD_DOWN;
else _lastVertical = PD_NONE;
// If xdiff isn't 0, assume we have either left or right movement.
if(xdiff != 0.0f) _lastHorizontal = xdiff > 0.0f ? PD_RIGHT : PD_LEFT;
// If xdiff isn't 0, assume we have either left or right movement.
if(xdiff != 0.0f) _lastHorizontal = xdiff > 0.0f ? PD_RIGHT : PD_LEFT;
else _lastHorizontal = PD_NONE;
else _lastHorizontal = PD_NONE;
_lastX = x;
_lastY = y;
_lastX = x;
_lastY = y;
}
void WindowManager::setStyleManager(StyleManager* sm) {
_styleManager = sm;
_styleManager = sm;
for(Iterator i = begin(); i != end(); i++) if(i->valid()) {
Window* window = i->get();
for(Iterator i = begin(); i != end(); i++) if(i->valid()) {
Window* window = i->get();
for(Window::Iterator w = window->begin(); w != window->end(); w++) {
if(!w->valid()) continue;
for(Window::Iterator w = window->begin(); w != window->end(); w++) {
if(!w->valid()) continue;
_styleManager->applyStyles(w->get());
}
_styleManager->applyStyles(w->get());
}
_styleManager->applyStyles(window);
}
_styleManager->applyStyles(window);
}
}
void WindowManager::resizeAllWindows(bool visible) {
for(Iterator i = begin(); i != end(); i++) if(i->valid()) {
if(visible && !getValue(i->get()->_index)) continue;
i->get()->resize();
}
for(Iterator i = begin(); i != end(); i++) if(i->valid()) {
if(visible && !getValue(i->get()->_index)) continue;
i->get()->resize();
}
}
// This is called by a ViewerEventHandler/MouseHandler (or whatever) as the pointer moves
// around and intersects with objects. It also resets our state data (_widget, _leftDown,
// etc.) The return value of this method is mostly useless.
bool WindowManager::pointerMove(float x, float y) {
WidgetList wl;
Event ev(this);
WidgetList wl;
Event ev(this);
if(!pickAtXY(x, y, wl)) {
if(_lastEvent) {
setEventFromInterface(ev.makeMouse(x, y, EVENT_MOUSE_LEAVE), _lastEvent);
if(!pickAtXY(x, y, wl)) {
if(_lastEvent) {
setEventFromInterface(ev.makeMouse(x, y, EVENT_MOUSE_LEAVE), _lastEvent);
_lastEvent->callMethodAndCallbacks(ev);
}
_lastEvent->callMethodAndCallbacks(ev);
}
if(_focusMode == PFM_SLOPPY) setFocused(0);
if(_focusMode == PFM_SLOPPY) setFocused(0);
_lastEvent = 0;
_leftDown = 0;
_middleDown = 0;
_rightDown = 0;
_lastEvent = 0;
_leftDown = 0;
_middleDown = 0;
_rightDown = 0;
return false;
}
return false;
}
EventInterface* ei = getFirstEventInterface(wl, ev.makeMouse(x, y, EVENT_MOUSE_OVER));
EventInterface* ei = getFirstEventInterface(wl, ev.makeMouse(x, y, EVENT_MOUSE_OVER));
if(!ei) return false;
if(!ei) return false;
if(_lastEvent != ei) {
if(_lastEvent) {
Event evLeave(this);
if(_lastEvent != ei) {
if(_lastEvent) {
Event evLeave(this);
evLeave.makeMouse(x, y, EVENT_MOUSE_LEAVE);
setEventFromInterface(evLeave, _lastEvent);
evLeave.makeMouse(x, y, EVENT_MOUSE_LEAVE);
setEventFromInterface(evLeave, _lastEvent);
_lastEvent->callMethodAndCallbacks(evLeave);
}
_lastEvent->callMethodAndCallbacks(evLeave);
}
_lastEvent = ei;
_lastEvent = ei;
if(_focusMode == PFM_SLOPPY && ev._window) setFocused(ev._window);
if(_focusMode == PFM_SLOPPY && ev._window) setFocused(ev._window);
_lastEvent->callMethodAndCallbacks(ev.makeMouse(x, y, EVENT_MOUSE_ENTER));
}
_lastEvent->callMethodAndCallbacks(ev.makeMouse(x, y, EVENT_MOUSE_ENTER));
}
ei->callMethodAndCallbacks(ev.makeMouse(x, y, EVENT_MOUSE_OVER));
ei->callMethodAndCallbacks(ev.makeMouse(x, y, EVENT_MOUSE_OVER));
return true;
return true;
}
bool WindowManager::pointerDrag(float x, float y) {
WidgetList widgetList;
Event ev(this);
WidgetList widgetList;
Event ev(this);
float xdiff = x;
float ydiff = y;
float xdiff = x;
float ydiff = y;
_getPointerXYDiff(xdiff, ydiff);
_getPointerXYDiff(xdiff, ydiff);
ev.makeMouse(xdiff, ydiff, EVENT_MOUSE_DRAG);
ev.makeMouse(xdiff, ydiff, EVENT_MOUSE_DRAG);
// If we're still in the drag state...
if(_lastPush) {
setEventFromInterface(ev, _lastPush);
// If we're still in the drag state...
if(_lastPush) {
setEventFromInterface(ev, _lastPush);
return _lastPush->callMethodAndCallbacks(ev);
}
return _lastPush->callMethodAndCallbacks(ev);
}
return false;
return false;
}
bool WindowManager::mouseScroll(float x, float y) {
WidgetList wl;
WidgetList wl;
if(!pickAtXY(x, y, wl)) return false;
if(!pickAtXY(x, y, wl)) return false;
Event ev(this, EVENT_MOUSE_SCROLL);
Event ev(this, EVENT_MOUSE_SCROLL);
EventInterface* ei = getFirstEventInterface(wl, ev);
EventInterface* ei = getFirstEventInterface(wl, ev);
if(!ei) return false;
if(!ei) return false;
return ei->callMethodAndCallbacks(ev);
return ei->callMethodAndCallbacks(ev);
}
// Keypresses only go the focused Window.
bool WindowManager::keyDown(int key, int mask) {
if(_focused.valid()) {
Event ev(this, EVENT_KEY_DOWN);
if(_focused.valid()) {
Event ev(this, EVENT_KEY_DOWN);
ev.makeKey(key, mask);
ev.makeKey(key, mask);
Widget* focusedWidget = _focused->getFocused();
Widget* focusedWidget = _focused->getFocused();
ev._window = _focused.get();
ev._widget = focusedWidget;
ev._window = _focused.get();
ev._widget = focusedWidget;
bool handled = false;
bool handled = false;
if(focusedWidget) handled = focusedWidget->callMethodAndCallbacks(ev);
if(focusedWidget) handled = focusedWidget->callMethodAndCallbacks(ev);
if(!handled) return _focused->callMethodAndCallbacks(ev);
if(!handled) return _focused->callMethodAndCallbacks(ev);
else return true;
}
else return true;
}
return false;
return false;
}
bool WindowManager::keyUp(int key, int mask) {
return true;
return true;
}
// A convenience wrapper for creating a proper orthographic camera using the current
// width and height.
osg::Camera* WindowManager::createParentOrthoCamera() {
osg::Camera* camera = 0;
osg::Camera* camera = 0;
if(isInvertedY()) camera = createInvertedYOrthoCamera(_width, _height);
if(isInvertedY()) camera = createInvertedYOrthoCamera(_width, _height);
else camera = createOrthoCamera(_width, _height);
else camera = createOrthoCamera(_width, _height);
camera->addChild(this);
camera->addChild(this);
return camera;
return camera;
}
}