From Jeremy Moles, import of the osgWidget NodeKit, sourced from the original http://osgwidget.googlecode.com/svn/trunk
Notes from Robert Osfield, I've merged osgWidget trunk, and added/changed CMakeLists.txt file to make it suitable for inclusion in the core OSG, and moved imagery/scripts/shaders out into OpenSceneGraph-Data
This commit is contained in:
194
src/osgWidget/Box.cpp
Normal file
194
src/osgWidget/Box.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Box.cpp 64 2008-06-30 21:32:00Z cubicool $
|
||||
|
||||
#include <osgWidget/Box>
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
Box::Box(const std::string& name, BOX_TYPE bt, bool uniform):
|
||||
Window (name),
|
||||
_boxType (bt),
|
||||
_uniform (uniform),
|
||||
_lastAdd (0) {
|
||||
}
|
||||
|
||||
Box::Box(const Box& box, const osg::CopyOp& co):
|
||||
Window (box, co),
|
||||
_boxType (box._boxType),
|
||||
_uniform (box._uniform),
|
||||
_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;
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
|
||||
// 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(h) addHeight += h;
|
||||
}
|
||||
|
||||
else {
|
||||
if(w) addWidth += w;
|
||||
|
||||
if(h) {
|
||||
addHeight += static_cast<point_type>(ih / inumFill);
|
||||
|
||||
if(cur >= _lastAdd && hrem) {
|
||||
_lastAdd++;
|
||||
addHeight++;
|
||||
hrem--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(addWidth != 0.0f) i->get()->addWidth(addWidth);
|
||||
|
||||
if(addHeight != 0.0f) i->get()->addHeight(addHeight);
|
||||
|
||||
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();
|
||||
|
||||
// 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();
|
||||
|
||||
// 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);
|
||||
|
||||
xadd = maxWidth;
|
||||
}
|
||||
|
||||
else {
|
||||
_positionWidget(widget, widget->getWidthTotal(), maxHeight);
|
||||
|
||||
xadd = widget->getWidthTotal();
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
widget->setOrigin(0.0f, yoff);
|
||||
|
||||
if(_uniform) {
|
||||
_positionWidget(widget, maxWidth, maxHeight);
|
||||
|
||||
yadd = maxHeight;
|
||||
}
|
||||
|
||||
else {
|
||||
_positionWidget(widget, maxWidth, widget->getHeightTotal());
|
||||
|
||||
yadd = widget->getHeightTotal();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
);
|
||||
|
||||
// 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()
|
||||
);
|
||||
}
|
||||
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
else return Sizes(
|
||||
_getMaxWidgetHeightTotal(),
|
||||
_getMaxWidgetMinHeightTotal()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user