Thanks J-S, fix now merged and submitted to svn/trunk.
On Mon, Sep 21, 2009 at 3:17 PM, Jean-Sébastien Guay <[email protected]> wrote: > Hi Robert, > > osgWidget::Window::setWindow() calls parented() (which does an addChild()) > on the new window, but it does not call unparented() (which does a > removeChild()) on the old window before. So it works fine if there was no > window previously, but if an app creates new windows and calls setWindow() > to replace the previous one, they will all add up instead and be on top of > each other... > > This is fixed in the file attached. > > Thanks, > > J-S > -- > ______________________________________________________ > Jean-Sebastien Guay [email protected] > http://www.cm-labs.com/ > http://whitestar02.webhop.org/ > > // -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008 > // $Id: Window.cpp 66 2008-07-14 21:54:09Z cubicool $ > > #include <algorithm> > #include <osgGA/GUIEventAdapter> > #include <osgWidget/WindowManager> > > namespace osgWidget { > > bool callbackWindowMove(Event& ev) { > if(!ev.getWindow() || !ev.getWindowManager()->isLeftMouseButtonDown()) > return false; > > ev.getWindow()->addOrigin(ev.x, ev.y); > ev.getWindow()->update(); > > return true; > } > > bool callbackWindowRotate(Event& ev) { > if(!ev.getWindow() || !ev.getWindowManager()->isRightMouseButtonDown()) > return false; > > ev.getWindow()->addRotate(ev.y); > ev.getWindow()->update(); > > return true; > } > > bool callbackWindowScale(Event& ev) { > if(!ev.getWindow() || !ev.getWindowManager()->isMiddleMouseButtonDown()) > return false; > > ev.getWindow()->addScale(ev.y); > ev.getWindow()->update(); > > return true; > } > > bool callbackWindowTabFocus(Event& ev) { > if(!ev.getWindow() || ev.key != osgGA::GUIEventAdapter::KEY_Tab) return > false; > > return ev.getWindow()->setNextFocusable(); > } > > Window::EmbeddedWindow::EmbeddedWindow(const std::string& name, point_type > w, point_type h): > Widget(name, w, h) { > } > > Window::EmbeddedWindow::EmbeddedWindow(const EmbeddedWindow& wiw, const > osg::CopyOp& co): > Widget(wiw, co) { > // TODO: Get this! > // _window = 0; > } > > void Window::EmbeddedWindow::parented(Window* parent) { > if(!_window.valid()) return; > > if(!_window->_parent) { > _window->_parent = parent; > > // Add this Window to the Window, on the same level as a Window's > // internal Geode. This will require special handling of events! > parent->addChild(_window.get()); > } > > else warn() > << "EmbeddedWindow Widget [" << _name > << "] cannot embed itself in Window [" << _window->getName() > << "], since it is already a child of [" << > _window->_parent->getName() > << "]" << std::endl > ; > } > > void Window::EmbeddedWindow::unparented(Window*) { > if(_window.valid()) { > _window->_parent = 0; > > if(_parent) _parent->removeChild(_window.get()); > } > } > > void Window::EmbeddedWindow::managed(WindowManager* wm) { > if(!_window.valid()) return; > > _window->setNodeMask(wm->getNodeMask()); > _window->managed(wm); > } > > void Window::EmbeddedWindow::unmanaged(WindowManager* wm) { > _window->unmanaged(wm); > } > > void Window::EmbeddedWindow::positioned() { > if(!_window.valid()) return; > > point_type x = getX(); > point_type y = getY(); > point_type w = getWidth(); > point_type h = getHeight(); > > // If the widget is fillable, ask the internal Window to resize itself. > // Whether or not the Window honors this reqest will be up to it. > _window->setOrigin(x, y); > _window->setZ(_calculateZ(getLayer() + 1)); > _window->setZRange(_calculateZ(LAYER_TOP - (getLayer() + 1))); > _window->setVisibleArea(0, 0, static_cast<int>(w), static_cast<int>(h)); > _window->resize(w, h); > } > > bool Window::EmbeddedWindow::setWindow(Window* win) { > if(!win) { > warn() > << "EmbeddedWindow [" << _name > << "] attempted to set a NULL Window." << std::endl > ; > > return false; > } > > if (_window.valid() && _parent) > unparented(_parent); > > _window = win; > > _window->resize(); > _window->setVisibilityMode(VM_PARTIAL); > > if(_parent) parented(_parent); > > WindowManager* wm = _getWindowManager(); > > if(wm) managed(wm); > > return true; > } > > void Window::EmbeddedWindow::updateSizeFromWindow() { > setSize(_window->getSize()); > > if(_parent) _parent->resize(); > } > > Window::Window(const std::string& name): > _parent (0), > _wm (0), > _index (0), > _x (0.0f), > _y (0.0f), > _z (0.0f), > _zRange (0.0f), > _strata (STRATA_NONE), > _vis (VM_FULL), > _r (0.0f), > _s (1.0f), > _scaleDenom (100.0f), > _vAnchor (VA_NONE), > _hAnchor (HA_NONE) { > _name = name.size() ? name : generateRandomName("Window"); > > // TODO: Fix the "bg" name. > osg::Geode* geode = new osg::Geode(); > Widget* bg = new Widget(name + "bg", 0.0f, 0.0f); > > bg->setLayer(Widget::LAYER_BG); > bg->setColor(1.0f, 1.0f, 1.0f, 1.0f); > > _setParented(bg); > > geode->addDrawable(bg); > > addChild(geode); > setDataVariance(osg::Object::DYNAMIC); > setEventMask(EVENT_ALL); > > getOrCreateStateSet()->setAttributeAndModes( > new osg::Scissor(0, 0, 0, 0), > osg::StateAttribute::ON > ); > } > > Window::Window(const Window& window, const osg::CopyOp& co): > MatrixTransform (window, co), > EventInterface (window), > StyleInterface (window), > _parent (0), > _wm (0), > _x (window._x), > _y (window._y), > _z (window._z), > _zRange (window._zRange), > _strata (window._strata), > _vis (window._vis), > _r (window._r), > _s (window._s), > _scaleDenom (window._scaleDenom), > _width (window._width), > _height (window._height), > _vAnchor (window._vAnchor), > _hAnchor (window._hAnchor), > _visibleArea (window._visibleArea) { > // Construct our vector of Widgets for easier use. :) > // TODO: I almost certainly will need to use the getPosition() thing here > eventually > // for things to work 100% properly. For example, some Geodes may contain > labels, > // etc. Also, any widget that doesn't support simple addWidget probably > won't > // work (Table?) > osg::Geode* geode = _geode(); > > Widget* bg = dynamic_cast<Widget*>(geode->getDrawable(0)); > > if(bg) { > _setParented(bg); > > // TODO: This is silly... > bg->setName(_name + "bg"); > } > > for(unsigned int i = 1; i < geode->getNumDrawables(); i++) { > Widget* widget = dynamic_cast<Widget*>(geode->getDrawable(i)); > > if(!widget) continue; > > // TODO: Properly test this... > if(!widget->canClone()) { > // geode->removeDrawable(widget); > > continue; > } > > _setParented(widget); > > _objects.push_back(widget); > } > > geode->setName(_name); > } > > // This is the method by which all Windows are redrawn/resized. Keep in mind > that not all > // Windows are required to absolutely honor a resize request, which is why > we call the > // _getWidthImplementation() and _getHeightImplementation() functions > instead of using the > // values passed in. > bool Window::resize(point_type width, point_type height) { > // First, we query and store what sizes the Window currently is. > _setWidthAndHeight(); > > // Second, we determine if there is a difference between what the size > currently > // is and what the user has requested. > point_type diffWidth = width > 0.0f ? width - _width.current : 0.0f; > point_type diffHeight = height > 0.0f ? height - _height.current : 0.0f; > > return resizeAdd(diffWidth, diffHeight); > } > > bool Window::resizeAdd(point_type diffWidth, point_type diffHeight) { > if( > _width.current + diffWidth < _width.minimum || > _height.current + diffHeight < _height.minimum > ) { > warn() > << "Window [" << _name << "] can't call resizeAdd() with the " > << "values " << diffWidth << " and " << diffHeight << std::endl > ; > > return false; > } > > // Now we initiate the resize, which may or may not succeed. > _resizeImplementation(diffWidth, diffHeight); > > // Inform each widget that it has been positioned. > for(Iterator i = begin(); i != end(); i++) if(i->valid()) { > i->get()->dirtyBound(); > i->get()->setDimensions(); > i->get()->positioned(); > } > > _setWidthAndHeight(); > > Widget* bg = _bg(); > > bg->setSize(_width.current, _height.current); > bg->dirtyBound(); > bg->positioned(); > > update(); > > return true; > } > > bool Window::resizePercent(point_type width, point_type height) { > if(!_parent && !_wm) { > warn() > << "Window [" << _name > << "] cannot resizePercent without being managed or parented." > << std::endl > ; > > return false; > } > > if(!_parent) return resize( > _wm->getWidth() * (width / 100.0f), > _wm->getHeight() * (height / 100.0f) > ); > > else return resize( > _parent->getWidth() * (width / 100.0f), > _parent->getHeight() * (height / 100.0f) > ); > } > > void Window::update() { > WindowList wl; > > getEmbeddedList(wl); > > for(WindowList::iterator w = wl.begin(); w != wl.end(); w++) > w->get()->update(); > > matrix_type x = _x; > matrix_type y = _y; > XYCoord xy = getAbsoluteOrigin(); > > // We only honor ANCHOR requests on topmost Windows, not embedded ones. > if((_vAnchor != VA_NONE || _hAnchor != HA_NONE) && !_parent && _wm) { > if(_vAnchor == VA_TOP) y = _wm->getHeight() - _height.current; > else if(_vAnchor == VA_CENTER) y = osg::round(_wm->getHeight() / > 2.0f); > else if(_vAnchor == VA_BOTTOM) y = 0.0f; > > if(_hAnchor == HA_LEFT) x = 0.0f; > else if(_hAnchor == HA_CENTER) x = osg::round(_wm->getWidth() / > 2.0f); > else if(_hAnchor == HA_RIGHT) x = _wm->getWidth() - _width.current + > _visibleArea[2]; > > xy.set(x, y); > } > > matrix_type z = _z; > > // We can't do proper scissoring until we have access to our parent > WindowManager, and > // we need to determine the sorting method we want to use. > if(_wm) { > if(_wm->isUsingRenderBins()) { > getOrCreateStateSet()->setRenderBinDetails( > static_cast<int>((1.0f - fabs(_z)) * > OSGWIDGET_RENDERBIN_MOD), > "RenderBin" > ); > > z = 0.0f; > } > > int sx = static_cast<int>(xy.x()); > int sy = static_cast<int>(xy.y()); > int sw = static_cast<int>(_width.current); > int sh = static_cast<int>(_height.current); > > // This sets the Scissor area to some offset defined by the user. > if(_vis == VM_PARTIAL) { > sw = static_cast<int>(_visibleArea[2]); > sh = static_cast<int>(_visibleArea[3]); > } > > // Otherwise, use the size of the WindowManager itself. > else if(_vis == VM_ENTIRE) { > sx = 0; > sy = 0; > sw = static_cast<int>(_wm->getWidth()); > sh = static_cast<int>(_wm->getHeight()); > } > > _scissor()->setScissor(sx, sy, sw, sh); > } > > // Update the Window itself, setting it's matrix according to translate, > rotate, and > // scale values. > osg::Matrix r = osg::Matrix::rotate( > osg::DegreesToRadians(_r), > osg::Vec3d(0.0f, 0.0f, 1.0f) > ); > > osg::Matrix s = osg::Matrix::scale(_s, _s, 1.0f); > osg::Matrix t = osg::Matrix::translate(x - _visibleArea[0], y - > _visibleArea[1], z); > > setMatrix(r * s * t); > } > > void Window::_setWidthAndHeightUnknownSizeError(const std::string& size, > point_type val) { > warn() > << "Window [" << _name << "] doesn't know its " << size > << " (" << val << ")." << std::endl > ; > } > > void Window::_setWidthAndHeightNotPAError(const std::string& size, > point_type val) { > warn() > << "Window [" << _name > << "] should be pixel-aligned, but a remainder was detected for it's > " > << size << " (" << val << ")." << std::endl > ; > } > > // Since there is so much error-checking associated with setting the width > and height properly > // of a Window, this function attempts to abstract some of that tedium. > void Window::_setWidthAndHeight() { > _width = _getWidthImplementation(); > _height = _getHeightImplementation(); > > if(_width.current < 0.0f) _setWidthAndHeightUnknownSizeError("current > width", _width.current); > > if(_width.minimum < 0.0f) _setWidthAndHeightUnknownSizeError("minimum > width", _width.minimum); > > if(_height.current < 0.0f) _setWidthAndHeightUnknownSizeError("current > height", _height.current); > > if(_height.minimum < 0.0f) _setWidthAndHeightUnknownSizeError("minimum > height", _height.minimum); > > if(hasDecimal(_width.current)) _setWidthAndHeightNotPAError("current > width", _width.current); > > if(hasDecimal(_width.minimum)) _setWidthAndHeightNotPAError("minimum > width", _width.minimum); > > if(hasDecimal(_height.current)) _setWidthAndHeightNotPAError("current > height", _height.current); > > if(hasDecimal(_height.minimum)) _setWidthAndHeightNotPAError("minimum > height", _height.minimum); > } > > void Window::_removeFromGeode(Widget* widget) { > if(!widget) return; > > widget->_index = 0; > > _setParented(widget, true); > > _geode()->removeDrawable(widget); > } > > // This is a somewhat complicated function designed to only be called by > derived classes, > // allowing them to insert Widgets (which can be added to the Window in any > way the derived > // class sees fit) into the REAL internal _objects container. > // TODO: This doesn't handle insertion properly!!! > bool Window::_setWidget(Widget* widget, int index) { > if(!widget) { > warn() << "Window [" << _name << "] called addWidget with NULL." << > std::endl; > > return false; > } > > if(widget->_parent) { > warn() > << "Window [" << _name > << "] attempted to parent Widget [" << widget->getName() > << "], which is already parented by [" << > widget->_parent->getName() > << "]." << std::endl > ; > > return false; > } > > if(index >= 0 && index >= static_cast<int>(size())) { > warn() > << "Window [" << _name > << "] attempted to manually insert the Widget [" << > widget->getName() > << "] at position " << index > << ", but there is not enough space available." > << std::endl > ; > > return false; > } > > // If we're just appending another widget... > if(index < 0) _objects.push_back(widget); > > // Otherwise, we're inserting and need to call removeWidget on the old > // one (if valid)... > else { > if(_objects[index].valid()) _removeFromGeode(_objects[index].get()); > > _objects[index] = widget; > } > > osg::Geode* geode = _geode(); > > widget->_index = geode->getNumDrawables(); > > geode->addDrawable(widget); > > _setParented(widget); > _setManaged(widget); > _setStyled(widget); > > // We make sure and resize after every added Widget. This ensures the > most > // accurate geometry... > resize(); > > return true; > } > > bool Window::_setVisible(bool visible) { > if(!_wm) return false; > > _wm->setValue(_index, visible); > > return true; > } > > void Window::_setFocused(Widget* widget) { > if(widget && _wm) { > Event ev(_wm); > > ev._window = this; > > if(_focused.valid()) { > ev._widget = _focused.get(); > > _focused->callMethodAndCallbacks(ev.makeType(EVENT_UNFOCUS)); > } > > _focused = widget; > ev._widget = widget; > > _focused->callMethodAndCallbacks(ev.makeType(EVENT_FOCUS)); > } > } > > void Window::_setStyled(Widget* widget) { > if(!widget || !_wm) return; > > if(!widget->_isStyled) return; > > widget->_isStyled = true; > > _wm->getStyleManager()->applyStyles(widget); > } > > void Window::_setParented(Widget* widget, bool setUnparented) { > if(!widget) return; > > if(!setUnparented) { > widget->_parent = this; > > widget->parented(this); > } > > else { > widget->unparented(this); > > widget->_parent = 0; > } > } > > void Window::_setManaged(Widget* widget, bool setUnmanaged) { > if(!widget || !_wm) return; > > // Tell the widget it's managed if it isn't already... > if(!setUnmanaged) { > if(widget->_isManaged) return; > > widget->_isManaged = true; > > widget->managed(_wm); > } > > // Otherwise, make sure it IS managed and tell it that it no longer will > be. :) > else { > if(!widget->_isManaged) return; > > widget->_isManaged = false; > > widget->unmanaged(_wm); > } > } > > Widget* Window::_getBackground() const { > const osg::Geode* geode = _geode(); > > // lol... > if(geode) return > dynamic_cast<Widget*>(const_cast<osg::Drawable*>(geode->getDrawable(0))); > > return 0; > } > > Window* Window::_getTopmostParent() const { > WindowList windowList; > > getParentList(windowList); > > return windowList.back().get(); > } > > // This will position a widget based on the amount of width and height it > has > // to fill. The x/y values should already be set, since we will be adding > here. > // However, the width and height can be anything and will be adjusted > accordingly. > void Window::_positionWidget(Widget* widget, point_type width, point_type > height) { > point_type w = widget->getWidth(); > point_type h = widget->getHeight(); > point_type pl = widget->getPadLeft(); > point_type pr = widget->getPadRight(); > point_type pt = widget->getPadTop(); > point_type pb = widget->getPadBottom(); > > if(widget->canFill()) { > point_type nw = osg::round(width - pr - pl); > point_type nh = osg::round(height - pt - pb); > > widget->addOrigin(pl, pb); > > if(w != nw) widget->setWidth(nw); > if(h != nh) widget->setHeight(nh); > > return; > } > > point_type ha = osg::round((width - w - pl - pr) / 2.0f); > point_type va = osg::round((height - h - pt - pb) / 2.0f); > > // Handle HORIZONTAL alignment. > if(widget->getAlignHorizontal() == Widget::HA_LEFT) widget->addX(pl); > > else if(widget->getAlignHorizontal() == Widget::HA_RIGHT) > widget->addX(width - w - pr); > > else widget->addX(ha + pl); > > // Handle VERTICAL alignment. > if(widget->getAlignVertical() == Widget::VA_BOTTOM) widget->addY(height - > h - pt); > > else if(widget->getAlignVertical() == Widget::VA_TOP) widget->addY(pb); > > else widget->addY(va + pb); > } > > bool Window::isVisible() const { > if(!_wm) return false; > > return _wm->getValue(_index); > } > > bool Window::isXYWithinVisible(float x, float y) const { > return > (x >= _visibleArea[0] && x <= (_visibleArea[0] + _visibleArea[2])) && > (y >= _visibleArea[1] && y <= (_visibleArea[1] + _visibleArea[3])) > ; > } > > void Window::setVisibleArea(int x, int y, int w, int h) { > _visibleArea[0] = x; > _visibleArea[1] = y; > _visibleArea[2] = w; > _visibleArea[3] = h; > } > > void Window::addVisibleArea(int x, int y, int w, int h) { > _visibleArea[0] += x; > _visibleArea[1] += y; > _visibleArea[2] += w; > _visibleArea[3] += h; > } > > // The topmost Window always has this method called, instead of the embedded > window directly. > bool Window::setFocused(const Widget* widget) { > // TODO: I've turned on the warn() here, but perhaps I shouldn't? I need > to define > // the conditions under which it's okay to call setFocus() with a NULL > widget. > if(!widget) { > warn() << "Window [" << _name << "] can't focus a NULL Widget." << > std::endl; > > return false; > } > > ConstIterator i = std::find(begin(), end(), widget); > > bool found = false; > > if(i == end()) { > // We couldn't find the widget in the toplevel, so lets see if one of > our > // EmbeddedWindow objects has it. > WindowList wl; > > getEmbeddedList(wl); > > for(WindowList::iterator w = wl.begin(); w != wl.end(); w++) { > ConstIterator ii = std::find(w->get()->begin(), w->get()->end(), > widget); > > if(ii != w->get()->end()) { > found = true; > i = ii; > } > } > } > > else found = true; > > if(!found) { > warn() > << "Window [" << _name > << "] couldn't find the Widget [" << widget->getName() > << "] in it's object list." << std::endl > ; > > return false; > } > > _setFocused(i->get()); > > return true; > } > > bool Window::setFocused(const std::string& name) { > Widget* w1 = getByName(name); > > bool found = false; > > if(!w1) { > // Just like above, we couldn't find the widget in the toplevel, so > lets see if > // one of our EmbeddedWindow objects has it. The difference here is > that we > // search by name. > WindowList wl; > > getEmbeddedList(wl); > > for(WindowList::iterator w = wl.begin(); w != wl.end(); w++) { > Widget* w2 = w->get()->getByName(name); > > if(w2) { > found = true; > w1 = w2; > } > } > } > > else found = true; > > if(!found) { > warn() > << "Window [" << _name > << "] couldn't find a Widget named [" << name > << "] to set as it's focus." << std::endl > ; > > return false; > } > > _setFocused(w1); > > return true; > } > > bool Window::grabFocus() { > if(!_wm) return false; > > return _wm->setFocused(this); > } > > bool Window::setFirstFocusable() { > WidgetList focusList; > > if(getFocusList(focusList)) { > _setFocused(focusList.front().get()); > > return true; > } > > return false; > } > > bool Window::setNextFocusable() { > WidgetList focusList; > > if(!getFocusList(focusList)) return false; > > WidgetList::iterator w = focusList.begin(); > > // TODO: This needs to be a more complicated object, since the focus may > be > // in a child Window instead of a Widget. > unsigned int focusedIndex = 0; > > for(unsigned int i = 0; w != focusList.end(); w++, i++) if(*w == > _focused) { > focusedIndex = i; > > break; > } > > if(focusedIndex < focusList.size() - 1) _setFocused((++w)->get()); > > else _setFocused(focusList.front().get()); > > return true; > } > > XYCoord Window::localXY(double absx, double absy) const { > XYCoord xy = getAbsoluteOrigin(); > double x = absx - xy.x(); > double y = absy - xy.y(); > > return XYCoord(x + _visibleArea[0], y + _visibleArea[1]); > } > > XYCoord Window::getAbsoluteOrigin() const { > XYCoord xy(0, 0); > > WindowList windowList; > > getParentList(windowList); > > for(WindowList::iterator i = windowList.begin(); i != windowList.end(); > i++) { > if(!i->valid()) continue; > > xy.x() += static_cast<int>(i->get()->getX()); > xy.y() += static_cast<int>(i->get()->getY()); > } > > return xy; > } > > Window::EmbeddedWindow* Window::embed( > const std::string& newName, > Widget::Layer layer, > unsigned int layerOffset > ) { > EmbeddedWindow* ew = new EmbeddedWindow( > newName.size() > 0 ? newName : _name + "Embedded", > getWidth(), > getHeight() > ); > > ew->setWindow(this); > ew->setSize(getWidth(), getHeight()); > ew->setCanFill(true); > ew->setLayer(layer, layerOffset); > > return ew; > } > > bool Window::getFocusList(WidgetList& wl) const { > for(ConstIterator i = begin(); i != end(); i++) if(i->valid()) { > EmbeddedWindow* ew = dynamic_cast<EmbeddedWindow*>(i->get()); > > if(!ew) { > if(i->get()->canFocus()) wl.push_back(i->get()); > } > > else { > if(ew->getWindow()) ew->getWindow()->getFocusList(wl); > } > } > > return wl.size() != 0; > } > > bool Window::getEmbeddedList(WindowList& wl) const { > for(ConstIterator i = begin(); i != end(); i++) if(i->valid()) { > EmbeddedWindow* ew = dynamic_cast<EmbeddedWindow*>(i->get()); > > if(!ew || !ew->getWindow()) continue; > > else { > wl.push_back(ew->getWindow()); > > ew->getWindow()->getEmbeddedList(wl); > } > } > > return wl.size() != 0; > } > > void Window::getParentList(WindowList& wl) const { > const Window* current = this; > > while(current) { > wl.push_back(const_cast<Window*>(current)); > > if(current->_parent) current = current->_parent; > > else current = 0; > } > } > > void Window::managed(WindowManager* wm) { > _wm = wm; > > for(Iterator i = begin(); i != end(); i++) { > _setManaged(i->get()); > _setStyled(i->get()); > } > > setFirstFocusable(); > resize(); > update(); > } > > void Window::unmanaged(WindowManager* wm) { > for(Iterator i = begin(); i != end(); i++) _setManaged(i->get(), true); > > _wm = 0; > } > > bool Window::addWidget(Widget* widget) { > return _setWidget(widget); > } > > bool Window::insertWidget(Widget* widget, unsigned int pos) { > return _setWidget(widget, pos); > } > > bool Window::removeWidget(Widget* widget) { > if(!widget) return false; > > if(_remove(widget)) { > _removeFromGeode(widget); > > resize(); > > return true; > } > > return false; > } > > bool Window::replaceWidget(Widget* oldWidget, Widget* newWidget) { > return false; > } > > unsigned int Window::addDrawableAndGetIndex(osg::Drawable* drawable) { > osg::Geode* geode = _geode(); > > if(geode->addDrawable(drawable)) return > geode->getDrawableIndex(drawable); > > // 0 is a valid error return code here, since our background widget > should be > // the first child. > return 0; > } > > unsigned int Window::addChildAndGetIndex(osg::Node* node) { > if(addChild(node)) return getChildIndex(node); > > return 0; > } > > // All of the subsequent functions are very boring and uninteresting, > although hopefully > // self-explanatory. They simply wrap calls to _compare<>() with the proper > templates, and > // forward the optional iteration ranges... > > point_type Window::_getMinWidgetWidth(int begin, int end, int add) const { > return _compare<Less>(&Widget::getWidth, begin, end, add); > } > > point_type Window::_getMinWidgetHeight(int begin, int end, int add) const { > return _compare<Less>(&Widget::getHeight, begin, end, add); > } > > point_type Window::_getMaxWidgetWidth(int begin, int end, int add) const { > return _compare<Greater>(&Widget::getWidth, begin, end, add); > } > > point_type Window::_getMaxWidgetHeight(int begin, int end, int add) const { > return _compare<Greater>(&Widget::getHeight, begin, end, add); > } > > point_type Window::_getMinWidgetMinWidth(int begin, int end, int add) const > { > return _compare<Less>(&Widget::getMinWidth, begin, end, add); > } > > point_type Window::_getMinWidgetMinHeight(int begin, int end, int add) const > { > return _compare<Less>(&Widget::getMinHeight, begin, end, add); > } > > point_type Window::_getMaxWidgetMinWidth(int begin, int end, int add) const > { > return _compare<Greater>(&Widget::getMinWidth, begin, end, add); > } > > point_type Window::_getMaxWidgetMinHeight(int begin, int end, int add) const > { > return _compare<Greater>(&Widget::getMinHeight, begin, end, add); > } > > point_type Window::_getMinWidgetWidthTotal(int begin, int end, int add) > const { > return _compare<Less>(&Widget::getWidthTotal, begin, end, add); > } > > point_type Window::_getMinWidgetHeightTotal(int begin, int end, int add) > const { > return _compare<Less>(&Widget::getHeightTotal, begin, end, add); > } > > point_type Window::_getMaxWidgetWidthTotal(int begin, int end, int add) > const { > return _compare<Greater>(&Widget::getWidthTotal, begin, end, add); > } > > point_type Window::_getMaxWidgetHeightTotal(int begin, int end, int add) > const { > return _compare<Greater>(&Widget::getHeightTotal, begin, end, add); > } > > point_type Window::_getMinWidgetMinWidthTotal(int begin, int end, int add) > const { > return _compare<Less>(&Widget::getMinWidthTotal, begin, end, add); > } > > point_type Window::_getMinWidgetMinHeightTotal(int begin, int end, int add) > const { > return _compare<Less>(&Widget::getMinHeightTotal, begin, end, add); > } > > point_type Window::_getMaxWidgetMinWidthTotal(int begin, int end, int add) > const { > return _compare<Greater>(&Widget::getMinWidthTotal, begin, end, add); > } > > point_type Window::_getMaxWidgetMinHeightTotal(int begin, int end, int add) > const { > return _compare<Greater>(&Widget::getMinHeightTotal, begin, end, add); > } > > point_type Window::_getMinWidgetPadHorizontal(int begin, int end, int add) > const { > return _compare<Less>(&Widget::getPadHorizontal, begin, end, add); > } > > point_type Window::_getMinWidgetPadVertical(int begin, int end, int add) > const { > return _compare<Less>(&Widget::getPadVertical, begin, end, add); > } > > point_type Window::_getMaxWidgetPadHorizontal(int begin, int end, int add) > const { > return _compare<Greater>(&Widget::getPadHorizontal, begin, end, add); > } > > point_type Window::_getMaxWidgetPadVertical(int begin, int end, int add) > const { > return _compare<Greater>(&Widget::getPadVertical, begin, end, add); > } > > point_type Window::_getNumFill(int begin, int end, int add) const { > return _accumulate<Plus>(&Widget::getFillAsNumeric, begin, end, add); > } > > Window::Sizes Window::_getWidthImplementation() const { > osg::BoundingBox bb = getGeode()->getBoundingBox(); > > point_type w = osg::round(bb.xMax() - bb.xMin()); > > return Sizes(w, 0.0f); > } > > Window::Sizes Window::_getHeightImplementation() const { > osg::BoundingBox bb = getGeode()->getBoundingBox(); > > point_type h = osg::round(bb.yMax() - bb.yMin()); > > return Sizes(h, 0.0f); > } > > } > > _______________________________________________ > osg-submissions mailing list > [email protected] > http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org > > _______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
