Hi Nick,

However, I started the osgwidgetinput example and for some reason it is not getting my input from the keyboard.

This is the same problem I noticed in other osgWidget classes lately. Someone changed the signature of virtual methods in the EventInterface class (which Widget inherits and thus, all other Widgets too) adding a const, but didn't change the signature of methods that are supposed to overload those virtual methods in derived classes. So for example, EventInterface defines:

virtual bool keyDown (int, int, const WindowManager*) { return false; }
virtual bool keyUp   (int, int, const WindowManager*) { return false; }

but Input defines:

virtual bool keyUp   (int, int, WindowManager*);
virtual bool keyDown (int, int, WindowManager*);

So there is no compile error, but the base class methods are called instead of the derived class methods because their argument lists don't match.

Here's the change for Input. It would be nice to go across all osgWidget classes and fix this if you have the time. I already did it for Frame a week or so ago, and this fixes Input, but there are bound to be more.

Hope this helps,

J-S
--
______________________________________________________
Jean-Sebastien Guay    [email protected]
                               http://www.cm-labs.com/
                        http://whitestar02.webhop.org/
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/

// Code by: Jeremy Moles (cubicool) 2007-2008

#ifndef OSGWIDGET_INPUT
#define OSGWIDGET_INPUT

#include <osgWidget/Label>

namespace osgWidget {

// This is a string of values we use to try and determine the best Y
// descent value (yoffset); you're welcome to use what works best for
// your font.
const std::string DESCENT_STRING("qpl");

class OSGWIDGET_EXPORT Input: public Label
{
    public:

        Input(const std::string& = "", const std::string& = "", unsigned int = 
20);

        virtual void parented   (Window*);
        virtual void positioned ();

        virtual bool focus   (const WindowManager*);
        virtual bool unfocus (const WindowManager*);
        virtual bool keyUp   (int, int, const WindowManager*);
        virtual bool keyDown (int, int, const WindowManager*);

        void         setCursor            (Widget*);
        unsigned int calculateBestYOffset (const std::string& = "qgl");

        void setXOffset(point_type xo) {
            _xoff = xo;
        }

        void setYOffset(point_type yo) {
            _yoff = yo;
        }

        void setXYOffset(point_type xo, point_type yo) {
            _xoff = xo;
            _yoff = yo;
        }

        osg::Drawable* getCursor() {
            return _cursor.get();
        }

        const osg::Drawable* getCursor() const {
            return _cursor.get();
        }

        point_type getXOffset() const {
            return _xoff;
        }

        point_type getYOffset() const {
            return _yoff;
        }

        XYCoord getXYOffset() const {
            return XYCoord(_xoff, _yoff);
        }

    protected:
        virtual void _calculateSize(const XYCoord&);

        void _calculateCursorOffsets();

        point_type _xoff;
        point_type _yoff;

        unsigned int _index;
        unsigned int _size;
        unsigned int _cursorIndex;
        unsigned int _maxSize;

        std::vector<point_type> _offsets;
        osg::ref_ptr<Widget>    _cursor;
};

}

#endif
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008

#include <osg/io_utils>
#include <osgWidget/WindowManager>
#include <osgWidget/Input>

namespace osgWidget {

Input::Input(const std::string& name, const std::string& label, unsigned int 
size):
Label        (name, label),
_xoff        (0.0f), 
_yoff        (0.0f),
_index       (0),
_size        (0),
_cursorIndex (0),
_maxSize     (size),
_cursor      (new Widget("cursor")) {
    _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, 1.0f);

    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);

    _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();

#if 0
    point_type width  = size.x() + _cursor->getWidth();
    point_type height = _cursor->getHeight();

    if(width > getWidth()) setWidth(osg::round(width));

    if(height > getHeight()) setHeight(osg::round(height));
#endif
}

void Input::_calculateCursorOffsets() {
    // 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;

    osg::Vec3 pos = _text->getPosition();

    for(unsigned int i = 0; i < _maxSize; i++) {
        osg::Vec3 ul = gq.getTransformedCoords(0)[0 + (i * 4)];
        osg::Vec3 ll = gq.getTransformedCoords(0)[1 + (i * 4)];
        osg::Vec3 lr = gq.getTransformedCoords(0)[2 + (i * 4)];
        osg::Vec3 ur = gq.getTransformedCoords(0)[3 + (i * 4)];
        
        _offsets[i] = lr.x() - pos.x();
 
        // warn() << "vb: " << gq.getGlyphs()[i]->getHorizontalBearing() << 
std::endl;
    }
}

bool Input::focus(const WindowManager*) {
    _cursor->setColor(0.0f, 0.0f, 0.0f, 1.0f);

    return true;
}

bool Input::unfocus(const WindowManager*) {
    _cursor->setColor(0.0f, 0.0f, 0.0f, 0.0f);

    return true;
}

void Input::parented(Window* parent) {
    Label::parented(parent);

    _cursor->setSize(2.0f, _text->getCharacterHeight());

    if(_cursorIndex) parent->getGeode()->setDrawable(_cursorIndex, 
_cursor.get());

    else _cursorIndex = parent->addDrawableAndGetIndex(_cursor.get());
}

void Input::positioned() {
    point_type ln = static_cast<point_type>(_text->getLineCount());

    ln = ln == 0.0f ? 1.0f : ln;

    // point_type th = (_text->getCharacterHeight() * ln) + 
(_text->getLineSpacing() * (ln - 1.0f));

    point_type x = getX() + _xoff;
    point_type y = getY() + _yoff;

    // XYCoord size = getTextSize();

    _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 + 1.0f);
    _cursor->setZ(_calculateZ(LAYER_MIDDLE));
}

bool Input::keyUp(int key, int mask, const WindowManager*) {
    return false;
}

bool Input::keyDown(int key, int mask, const WindowManager*) {
    osgText::String& s = _text->getText();

    if(key == osgGA::GUIEventAdapter::KEY_BackSpace) {
        if(_index >= 1) {
            // s.erase(s.begin() + (_index - 1));

            s[_index - 1] = ' ';

            _text->update();
            
            _calculateCursorOffsets();

            _index--;
        }
    }

    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);

        s[_index] = key;
        
        _text->update();
        
        _calculateCursorOffsets();

        _index++;
    }

    // _text->update();

    _calculateSize(getTextSize());

    getParent()->resize();

    return false;
}

void Input::setCursor(Widget*) {
}

unsigned int Input::calculateBestYOffset(const std::string& s)
{

    const osgText::FontResolution fr(static_cast<unsigned 
int>(_text->getCharacterHeight()),
                                     static_cast<unsigned 
int>(_text->getCharacterHeight()));

    osgText::String utf(s);

    unsigned int descent = 0;

    for(osgText::String::iterator i = utf.begin(); i != utf.end(); i++) {
        osgText::Font*        font  = 
const_cast<osgText::Font*>(_text->getFont());
        osgText::Font::Glyph* glyph = font->getGlyph(fr, *i);
        unsigned int          d     = 
abs((int)glyph->getHorizontalBearing().y());

        if(d > descent) descent = d;
    }

    return descent;
}

}

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to