diff --git a/include/osgDB/DataTypes b/include/osgDB/DataTypes index b53575fd9..7397fa495 100644 --- a/include/osgDB/DataTypes +++ b/include/osgDB/DataTypes @@ -25,53 +25,53 @@ namespace osgDB #define OSG_HEADER_HIGH 0x1AFB4545 // Reader/writer plugin version -#define PLUGIN_VERSION 2 +const unsigned int PLUGIN_VERSION = 2; -#define BOOL_SIZE 1 -#define CHAR_SIZE 1 -#define SHORT_SIZE 2 -#define INT_SIZE 4 -#define LONG_SIZE 4 -#define FLOAT_SIZE 4 -#define DOUBLE_SIZE 8 -#define GLENUM_SIZE 4 +const int BOOL_SIZE = 1; +const int CHAR_SIZE = 1; +const int SHORT_SIZE = 2; +const int INT_SIZE = 4; +const int LONG_SIZE = 4; +const int FLOAT_SIZE = 4; +const int DOUBLE_SIZE = 8; +const int GLENUM_SIZE = 4; -#define ID_BYTE_ARRAY 0 -#define ID_UBYTE_ARRAY 1 -#define ID_SHORT_ARRAY 2 -#define ID_USHORT_ARRAY 3 -#define ID_INT_ARRAY 4 -#define ID_UINT_ARRAY 5 -#define ID_FLOAT_ARRAY 6 -#define ID_DOUBLE_ARRAY 7 -#define ID_VEC2B_ARRAY 8 -#define ID_VEC3B_ARRAY 9 -#define ID_VEC4B_ARRAY 10 -#define ID_VEC4UB_ARRAY 11 -#define ID_VEC2S_ARRAY 12 -#define ID_VEC3S_ARRAY 13 -#define ID_VEC4S_ARRAY 14 -#define ID_VEC2_ARRAY 15 -#define ID_VEC3_ARRAY 16 -#define ID_VEC4_ARRAY 17 -#define ID_VEC2D_ARRAY 18 -#define ID_VEC3D_ARRAY 19 -#define ID_VEC4D_ARRAY 20 +const int ID_BYTE_ARRAY = 0; +const int ID_UBYTE_ARRAY = 1; +const int ID_SHORT_ARRAY = 2; +const int ID_USHORT_ARRAY = 3; +const int ID_INT_ARRAY = 4; +const int ID_UINT_ARRAY = 5; +const int ID_FLOAT_ARRAY = 6; +const int ID_DOUBLE_ARRAY = 7; +const int ID_VEC2B_ARRAY = 8; +const int ID_VEC3B_ARRAY = 9; +const int ID_VEC4B_ARRAY = 10; +const int ID_VEC4UB_ARRAY = 11; +const int ID_VEC2S_ARRAY = 12; +const int ID_VEC3S_ARRAY = 13; +const int ID_VEC4S_ARRAY = 14; +const int ID_VEC2_ARRAY = 15; +const int ID_VEC3_ARRAY = 16; +const int ID_VEC4_ARRAY = 17; +const int ID_VEC2D_ARRAY = 18; +const int ID_VEC3D_ARRAY = 19; +const int ID_VEC4D_ARRAY = 20; -#define ID_DRAWARRAYS 50 -#define ID_DRAWARRAY_LENGTH 51 -#define ID_DRAWELEMENTS_UBYTE 52 -#define ID_DRAWELEMENTS_USHORT 53 -#define ID_DRAWELEMENTS_UINT 54 +const int ID_DRAWARRAYS = 50; +const int ID_DRAWARRAY_LENGTH = 51; +const int ID_DRAWELEMENTS_UBYTE = 52; +const int ID_DRAWELEMENTS_USHORT = 53; +const int ID_DRAWELEMENTS_UINT = 54; // Used by BEGIN_BRACKET and END_BRACKET -#define INDENT_VALUE 2 +const int INDENT_VALUE = 2; // Used by the writeImage/readImage parameter -#define IMAGE_INLINE_DATA 0 -#define IMAGE_INLINE_FILE 1 -#define IMAGE_EXTERNAL 2 -#define IMAGE_WRITE_OUT 3 +const int IMAGE_INLINE_DATA = 0; +const int IMAGE_INLINE_FILE = 1; +const int IMAGE_EXTERNAL = 2; +const int IMAGE_WRITE_OUT = 3; struct ObjectGLenum { diff --git a/include/osgWidget/Input b/include/osgWidget/Input index ede5fe2be..6d4cb3b9a 100644 --- a/include/osgWidget/Input +++ b/include/osgWidget/Input @@ -27,83 +27,84 @@ const std::string DESCENT_STRING("qpl"); class OSGWIDGET_EXPORT Input: public Label { - public: + public: - Input(const std::string& = "", const std::string& = "", unsigned int = 20); + Input(const std::string& = "", const std::string& = "", unsigned int = 20); - virtual void parented (Window*); - virtual void positioned (); + 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*); - virtual bool mouseDrag (double, double, const WindowManager*); - virtual bool mousePush (double x, double y, const WindowManager*); + virtual bool focus (const WindowManager*); + virtual bool unfocus (const WindowManager*); + virtual bool keyUp (int, int, const WindowManager*); + virtual bool keyDown (int, int, const WindowManager*); + virtual bool mouseDrag (double, double, const WindowManager*); + virtual bool mousePush (double x, double y, const WindowManager*); + virtual bool mouseRelease (double, double, const WindowManager*); - void setCursor (Widget*); - unsigned int calculateBestYOffset (const std::string& = "qgl"); + void setCursor (Widget*); + unsigned int calculateBestYOffset (const std::string& = "qgl"); + void clear(); - void setXOffset(point_type xo) { - _xoff = xo; - } + void setXOffset(point_type xo) { + _xoff = xo; + } - void setYOffset(point_type yo) { - _yoff = yo; - } + void setYOffset(point_type yo) { + _yoff = yo; + } - void setXYOffset(point_type xo, point_type yo) { - _xoff = xo; - _yoff = yo; - } + void setXYOffset(point_type xo, point_type yo) { + _xoff = xo; + _yoff = yo; + } - osg::Drawable* getCursor() { - return _cursor.get(); - } + osg::Drawable* getCursor() { + return _cursor.get(); + } - const osg::Drawable* getCursor() const { - return _cursor.get(); - } + const osg::Drawable* getCursor() const { + return _cursor.get(); + } - point_type getXOffset() const { - return _xoff; - } + point_type getXOffset() const { + return _xoff; + } - point_type getYOffset() const { - return _yoff; - } + point_type getYOffset() const { + return _yoff; + } - XYCoord getXYOffset() const { - return XYCoord(_xoff, _yoff); - } + XYCoord getXYOffset() const { + return XYCoord(_xoff, _yoff); + } - protected: - virtual void _calculateSize(const XYCoord&); + protected: + virtual void _calculateSize(const XYCoord&); - void _calculateCursorOffsets(); + void _calculateCursorOffsets(); - point_type _xoff; - point_type _yoff; + point_type _xoff; + point_type _yoff; - unsigned int _index; - unsigned int _size; - unsigned int _cursorIndex; - unsigned int _maxSize; - unsigned int _textLength; + unsigned int _index; + unsigned int _size; + unsigned int _cursorIndex; + unsigned int _maxSize; - std::vector _offsets; - std::vector _wordsOffsets; - std::vector _widths; - osg::ref_ptr _cursor; + std::vector _offsets; + std::vector _wordsOffsets; + std::vector _widths; + osg::ref_ptr _cursor; - bool _insertMode; + bool _insertMode; // Insert was pressed --> true --> typing will overwrite existing text - osg::ref_ptr _selection; - unsigned int _selectionStartIndex; - unsigned int _selectionEndIndex; - unsigned int _selectionIndex; + osg::ref_ptr _selection; + unsigned int _selectionStartIndex; + unsigned int _selectionEndIndex; + unsigned int _selectionIndex; - point_type _mouseClickX; + point_type _mouseClickX; }; } diff --git a/src/osgPlugins/osg/BinaryStreamOperator.h b/src/osgPlugins/osg/BinaryStreamOperator.h index 6b3cdce13..77541444d 100644 --- a/src/osgPlugins/osg/BinaryStreamOperator.h +++ b/src/osgPlugins/osg/BinaryStreamOperator.h @@ -12,42 +12,42 @@ public: virtual bool isBinary() const { return true; } virtual void writeBool( bool b ) - { char c = b?1:0; _out->write( &c, CHAR_SIZE ); } + { char c = b?1:0; _out->write( &c, osgDB::CHAR_SIZE ); } virtual void writeChar( char c ) - { _out->write( &c, CHAR_SIZE ); } + { _out->write( &c, osgDB::CHAR_SIZE ); } virtual void writeUChar( unsigned char c ) - { _out->write( (char*)&c, CHAR_SIZE ); } + { _out->write( (char*)&c, osgDB::CHAR_SIZE ); } virtual void writeShort( short s ) - { _out->write( (char*)&s, SHORT_SIZE ); } + { _out->write( (char*)&s, osgDB::SHORT_SIZE ); } virtual void writeUShort( unsigned short s ) - { _out->write( (char*)&s, SHORT_SIZE ); } + { _out->write( (char*)&s, osgDB::SHORT_SIZE ); } virtual void writeInt( int i ) - { _out->write( (char*)&i, INT_SIZE ); } + { _out->write( (char*)&i, osgDB::INT_SIZE ); } virtual void writeUInt( unsigned int i ) - { _out->write( (char*)&i, INT_SIZE ); } + { _out->write( (char*)&i, osgDB::INT_SIZE ); } virtual void writeLong( long l ) - { _out->write( (char*)&l, LONG_SIZE ); } + { _out->write( (char*)&l, osgDB::LONG_SIZE ); } virtual void writeULong( unsigned long l ) - { _out->write( (char*)&l, LONG_SIZE ); } + { _out->write( (char*)&l, osgDB::LONG_SIZE ); } virtual void writeFloat( float f ) - { _out->write( (char*)&f, FLOAT_SIZE ); } + { _out->write( (char*)&f, osgDB::FLOAT_SIZE ); } virtual void writeDouble( double d ) - { _out->write((char*)&d, DOUBLE_SIZE); } + { _out->write((char*)&d, osgDB::DOUBLE_SIZE); } virtual void writeString( const std::string& s ) { int size = s.size(); - _out->write( (char*)&size, INT_SIZE ); + _out->write( (char*)&size, osgDB::INT_SIZE ); _out->write( s.c_str(), s.size() ); } @@ -56,10 +56,10 @@ public: virtual void writeBase( std::ios_base& (*fn)(std::ios_base&) ) {} virtual void writeGLenum( const osgDB::ObjectGLenum& value ) - { GLenum e = value.get(); _out->write((char*)&e, GLENUM_SIZE); } + { GLenum e = value.get(); _out->write((char*)&e, osgDB::GLENUM_SIZE); } virtual void writeProperty( const osgDB::ObjectProperty& prop ) - { if (prop._mapProperty) _out->write((char*)&(prop._value), INT_SIZE); } + { if (prop._mapProperty) _out->write((char*)&(prop._value), osgDB::INT_SIZE); } virtual void writeMark( const osgDB::ObjectMark& mark ) {} @@ -81,65 +81,65 @@ public: virtual void readBool( bool& b ) { char c = 0; - _in->read( &c, CHAR_SIZE ); + _in->read( &c, osgDB::CHAR_SIZE ); b = (c!=0); } virtual void readChar( char& c ) - { _in->read( &c, CHAR_SIZE ); } + { _in->read( &c, osgDB::CHAR_SIZE ); } virtual void readSChar( signed char& c ) - { _in->read( (char*)&c, CHAR_SIZE ); } + { _in->read( (char*)&c, osgDB::CHAR_SIZE ); } virtual void readUChar( unsigned char& c ) - { _in->read( (char*)&c, CHAR_SIZE ); } + { _in->read( (char*)&c, osgDB::CHAR_SIZE ); } virtual void readShort( short& s ) { - _in->read( (char*)&s, SHORT_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE ); + _in->read( (char*)&s, osgDB::SHORT_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&s, osgDB::SHORT_SIZE ); } virtual void readUShort( unsigned short& s ) { - _in->read( (char*)&s, SHORT_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE ); + _in->read( (char*)&s, osgDB::SHORT_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&s, osgDB::SHORT_SIZE ); } virtual void readInt( int& i ) { - _in->read( (char*)&i, INT_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE ); + _in->read( (char*)&i, osgDB::INT_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&i, osgDB::INT_SIZE ); } virtual void readUInt( unsigned int& i ) { - _in->read( (char*)&i, INT_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE ); + _in->read( (char*)&i, osgDB::INT_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&i, osgDB::INT_SIZE ); } virtual void readLong( long& l ) { - _in->read( (char*)&l, LONG_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE ); + _in->read( (char*)&l, osgDB::LONG_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&l, osgDB::LONG_SIZE ); } virtual void readULong( unsigned long& l ) { - _in->read( (char*)&l, LONG_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE ); + _in->read( (char*)&l, osgDB::LONG_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&l, osgDB::LONG_SIZE ); } virtual void readFloat( float& f ) { - _in->read( (char*)&f, FLOAT_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&f, FLOAT_SIZE ); + _in->read( (char*)&f, osgDB::FLOAT_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&f, osgDB::FLOAT_SIZE ); } virtual void readDouble( double& d ) { - _in->read( (char*)&d, DOUBLE_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&d, DOUBLE_SIZE ); + _in->read( (char*)&d, osgDB::DOUBLE_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&d, osgDB::DOUBLE_SIZE ); } virtual void readString( std::string& s ) @@ -159,8 +159,8 @@ public: virtual void readGLenum( osgDB::ObjectGLenum& value ) { GLenum e = 0; - _in->read( (char*)&e, GLENUM_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&e, GLENUM_SIZE ); + _in->read( (char*)&e, osgDB::GLENUM_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&e, osgDB::GLENUM_SIZE ); value.set( e ); } @@ -169,8 +169,8 @@ public: int value = 0; if ( prop._mapProperty ) { - _in->read( (char*)&value, INT_SIZE ); - if ( _byteSwap ) osg::swapBytes( (char*)&value, INT_SIZE ); + _in->read( (char*)&value, osgDB::INT_SIZE ); + if ( _byteSwap ) osg::swapBytes( (char*)&value, osgDB::INT_SIZE ); } prop.set( value ); } diff --git a/src/osgWidget/Input.cpp b/src/osgWidget/Input.cpp index efa850af3..464a03a4a 100644 --- a/src/osgWidget/Input.cpp +++ b/src/osgWidget/Input.cpp @@ -44,7 +44,6 @@ Input::Input(const std::string& name, const std::string& label, unsigned int siz _size(0), _cursorIndex(0), _maxSize(size), - _textLength(0), _cursor(new Widget("cursor")), _insertMode(false), _selection(new Widget("selection")), @@ -74,10 +73,9 @@ Input::Input(const std::string& name, const std::string& label, unsigned int siz EVENT_MASK_MOUSE_DRAG ); - _offsets.resize(size+1, 0.0f); - _widths.resize(size+1, 1.0f); + _offsets.resize(_text->getText().size()+1, 0.0f); + _widths.resize(_text->getText().size()+1, 1.0f); - _text->getText().resize(size, ' '); _text->update(); _cursor->setDrawCallback( new BlinkCursorCallback(_insertMode) ); @@ -101,10 +99,13 @@ void Input::_calculateSize(const XYCoord& size) { void Input::_calculateCursorOffsets() { // Determine the "offset" + _offsets.resize(_text->getText().size()+1, 0.0f); + _widths.resize(_text->getText().size()+1, 1.0f); + if (_text->getText().size()==0) { _offsets[0] = 0; - _widths[0] = 0; + _widths[0] = 1.f; return; } @@ -182,7 +183,7 @@ void Input::_calculateCursorOffsets() { } _offsets[idx] = lr.x() + pos.x(); - _widths[idx]= 1.f; + _widths[idx] = 1.f; _wordsOffsets.clear(); for ( unsigned int i=0; i<_text->getText().size(); ++i ) @@ -221,43 +222,62 @@ void Input::parented(Window* parent) { else _selectionIndex = parent->addDrawableAndGetIndex(_selection.get()); } -void Input::positioned() { - point_type ln = static_cast(_text->getLineCount()); +void Input::positioned() +{ + point_type ln = static_cast(_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() + _yoff; + point_type x = getX() + _xoff; + point_type y = getY() + _yoff; - // XYCoord size = getTextSize(); + // XYCoord size = getTextSize(); - _text->setPosition(osg::Vec3(x, y, _calculateZ(LAYER_MIDDLE))); + _text->setPosition(osg::Vec3(x, y, _calculateZ(LAYER_MIDDLE))); - point_type xoffset = _index > 0 ? _offsets[_index - 1] : 0.0f; + point_type xoffset = _index > 0 ? _offsets[_index - 1] : 0.0f; - _cursor->setSize(_widths[_index], getHeight()); - _cursor->setOrigin(getX() + xoffset, getY() ); - _cursor->setZ(_calculateZ(LAYER_MIDDLE-1)); + if (_insertMode) + { + if (_index < _text->getText().size()) + { + _cursor->setSize(_widths[_index], getHeight()); + } + else + { + // We're at the end of the string, perhaps the string is empty, + // so get the advance for any character, perhaps a large one, I chose 'A'. + osgText::Glyph* glyph = const_cast(_text->getFont())->getGlyph(osgText::FontResolution(_text->getFontWidth(), _text->getFontHeight()), 'A'); + _cursor->setSize(glyph->getHorizontalAdvance(), getHeight()); + } + } + else + { + _cursor->setSize(1.f, getHeight()); + } + + _cursor->setOrigin(getX() + xoffset, getY() ); + _cursor->setZ(_calculateZ(LAYER_MIDDLE-1)); - unsigned int _selectionMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); - unsigned int _selectionMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); + unsigned int selectionMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); + unsigned int selectionMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); - if (_selectionMax-_selectionMin>0) - { - point_type xstart = _selectionMin > 0 ? _offsets[_selectionMin - 1] : 0.0f; - point_type xend = (_selectionMax > 0 ? _offsets[_selectionMax - 1] : 0.0f) + _widths[_selectionMax]; + if (selectionMax - selectionMin > 0) + { + point_type xstart = selectionMin > 0 ? _offsets[selectionMin - 1] : 0.0f; + point_type xend = selectionMax > 0 ? _offsets[selectionMax - 1] : 0.0f; - _selection->setSize(xend-xstart, getHeight()); - _selection->setOrigin(getX() + xstart, getY()); - _selection->setZ(_calculateZ(LAYER_MIDDLE-2)); - } - else - { - _selection->setSize(0, getHeight()); - } + _selection->setSize(xend-xstart, getHeight()); + _selection->setOrigin(getX() + xstart, getY()); + _selection->setZ(_calculateZ(LAYER_MIDDLE-2)); + } + else + { + _selection->setSize(0, getHeight()); + } } bool Input::keyUp(int key, int mask, const WindowManager*) { @@ -269,11 +289,12 @@ bool Input::mouseDrag (double x, double y, const WindowManager*) _mouseClickX += x; x = _mouseClickX; - for ( unsigned int i=0; i< _offsets.size()-1; ++i ) + for ( unsigned int i = 0; i < _offsets.size(); ++i ) { point_type offset1 = i > 0 ? _offsets.at(i-1) : 0; point_type offset2 = _offsets.at(i); - if (x >= offset1 && x <= offset2) + if ((x >= offset1 && x <= offset2) || + i == _offsets.size() - 1) // If we're at the last one, obviously it will be there. { _selectionEndIndex = _index = i; positioned(); @@ -281,7 +302,7 @@ bool Input::mouseDrag (double x, double y, const WindowManager*) } } - return false; + return true; } bool Input::mousePush (double x, double y, const WindowManager* wm) @@ -296,21 +317,28 @@ bool Input::mousePush (double x, double y, const WindowManager* wm) x -= offset; _mouseClickX = x; - for ( unsigned int i=0; i< _offsets.size()-1; ++i ) + for ( unsigned int i = 0; i < _offsets.size(); ++i ) { point_type offset1 = i > 0 ? _offsets.at(i-1) : 0; - point_type offset2 = i == 0 ? _offsets.at(1) : _offsets.at(i); - if (x >= offset1 && x <= offset2) + point_type offset2 = _offsets.at(i); + if ((x >= offset1 && x <= offset2) || + i == _offsets.size() - 1) // If we're at the last one, obviously it will be there. { _selectionStartIndex = _selectionEndIndex = _index = i; positioned(); break; } } - return false; + return true; } -bool Input::keyDown(int key, int mask, const WindowManager*) { +bool Input::mouseRelease(double, double, const WindowManager*) +{ + return true; +} + +bool Input::keyDown(int key, int mask, const WindowManager*) +{ osgText::String& s = _text->getText(); switch (key) @@ -319,7 +347,7 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { if (mask & osgGA::GUIEventAdapter::MODKEY_CTRL) { bool found = false; - for (unsigned int i=0; i<_wordsOffsets.size()-1; ++i) + for (unsigned int i = 0; i < _wordsOffsets.size() - 1; ++i) { if (_wordsOffsets.at(i) < _index && _index <= _wordsOffsets.at(i+1)) { @@ -334,7 +362,7 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { } } else - if (_index>0) + if (_index > 0) { --_index; } @@ -351,7 +379,7 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { if (mask & osgGA::GUIEventAdapter::MODKEY_CTRL) { bool found = false; - for (unsigned int i=0; i<_wordsOffsets.size()-1; ++i) + for (unsigned int i = 0; i < _wordsOffsets.size() - 1; ++i) { if (_wordsOffsets.at(i) <= _index && _index < _wordsOffsets.at(i+1)) { @@ -366,7 +394,7 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { } } else - if (_index<_textLength) + if (_index < s.size()) { ++_index; } @@ -392,7 +420,7 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { } break; case osgGA::GUIEventAdapter::KEY_End: - _index = _textLength; + _index = s.size(); if (mask & osgGA::GUIEventAdapter::MODKEY_SHIFT) { _selectionEndIndex = _index; @@ -407,108 +435,66 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { break; case osgGA::GUIEventAdapter::KEY_Delete: { - unsigned int _selectionMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); - unsigned int _selectionMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); + unsigned int deleteMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); + unsigned int deleteMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); - if (_selectionMax-_selectionMin>0) + if (deleteMax - deleteMin > 0) { - unsigned int deleteToIdx = _selectionMax; - for (unsigned int i=0; i < s.size()-_selectionMin; ++i) - { - s[_selectionMin+i] = deleteToIdx+i+1 < s.size() ? s[deleteToIdx+i+1] : ' '; - } - - _text->update(); - - _calculateCursorOffsets(); - - _textLength -= deleteToIdx-_selectionMin; - _index = _selectionMin; - _selectionStartIndex = _selectionEndIndex = _index; } - else - if (mask & osgGA::GUIEventAdapter::MODKEY_CTRL) + else if (mask & osgGA::GUIEventAdapter::MODKEY_CTRL) { - unsigned int deleteToIdx = _textLength; - for (unsigned int i=0; i<_wordsOffsets.size()-1; ++i) + deleteMin = 0; + deleteMax = 0; + for (unsigned int i =0; i < _wordsOffsets.size() - 1; ++i) { if (_wordsOffsets.at(i) <= _index && _index < _wordsOffsets.at(i+1)) { - deleteToIdx = _wordsOffsets.at(i+1); + deleteMin = _wordsOffsets.at(i); + deleteMax = _wordsOffsets.at(i+1); break; } } - for (unsigned int i=0; i < s.size()-_index; ++i) - { - s[_index+i] = deleteToIdx+i < s.size() ? s[deleteToIdx+i] : ' '; - } - - _text->update(); - - _calculateCursorOffsets(); - - _textLength -= deleteToIdx-_index; } - else - if (_index < s.size()-1) + else if (_index < s.size()) { - for (unsigned int i=_index; i < s.size()-1; ++i) - { - s[i] = s[i+1]; - } - - _text->update(); - - _calculateCursorOffsets(); - - --_textLength; + deleteMin = _index; + deleteMax = _index + 1; } + + if (deleteMin != deleteMax) + s.erase(s.begin() + deleteMin, s.begin() + deleteMax); + + _text->update(); + + _calculateCursorOffsets(); + + _index = deleteMin; + _selectionStartIndex = _selectionEndIndex = _index; } break; case osgGA::GUIEventAdapter::KEY_BackSpace: { - unsigned int _selectionMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); - unsigned int _selectionMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); + unsigned int deleteMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); + unsigned int deleteMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); - if (_selectionMax-_selectionMin>0) + if (deleteMax - deleteMin > 0) { - unsigned int deleteToIdx = _selectionMax; - for (unsigned int i=0; i < s.size()-_selectionMin; ++i) - { - s[_selectionMin+i] = deleteToIdx+i+1 < s.size() ? s[deleteToIdx+i+1] : ' '; - } - - _text->update(); - - _calculateCursorOffsets(); - - _textLength -= deleteToIdx-_selectionMin; - _index = _selectionMin; - _selectionStartIndex = _selectionEndIndex = _index; } - else - if(_index >= 1) { + else if(_index >= 1) + { + deleteMin = _index - 1; + deleteMax = _index; + } - _index--; - if (_index< s.size()-1) - { - for (unsigned int i=_index; i < s.size()-1; ++i) - { - s[i] = s[i+1]; - s[i+1] = ' '; - } - } - else - { - s[s.size()-1] = ' '; - } + if (deleteMin != deleteMax) + s.erase(s.begin() + deleteMin, s.begin() + deleteMax); - _text->update(); + _text->update(); - _calculateCursorOffsets(); + _calculateCursorOffsets(); - --_textLength; - } + _index = deleteMin; + _selectionStartIndex = _selectionEndIndex = _index; } break; default: @@ -516,7 +502,6 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { if (((key=='v' || key=='V') && (mask & osgGA::GUIEventAdapter::MODKEY_CTRL)) || (key==22)) { - _selectionStartIndex = _selectionEndIndex = _index; std::string data; // Data from clipboard #ifdef WIN32 @@ -531,15 +516,27 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { #endif if (!data.empty()) { - data = data.substr(0,_maxSize-_index); - _textLength += data.size(); - _selectionEndIndex = _textLength; + unsigned int deleteMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); + unsigned int deleteMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); - std::string::iterator itr = data.begin(); - for ( ; itr != data.end(); ++itr ) + if (deleteMax - deleteMin > 0) { - s[_index++] = *itr; + data = data.substr(0, _maxSize-s.size()-(deleteMax - deleteMin)); + + s.erase(s.begin() + deleteMin, s.begin() + deleteMax); + s.insert(s.begin() + deleteMin, data.begin(), data.end()); + + _index = deleteMin + data.size(); } + else + { + data = data.substr(0, _maxSize-s.size()); + + s.insert(s.begin() + _index, data.begin(), data.end()); + _index += data.length(); + } + + _selectionStartIndex = _selectionEndIndex = _index; _text->update(); @@ -550,23 +547,19 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { getParent()->resize(); return false; - } - } else - if (((key=='c' || key=='C') && (mask & osgGA::GUIEventAdapter::MODKEY_CTRL)) || (key==3)) + if (((key=='c' || key=='C' || key=='x' || key=='X') && (mask & osgGA::GUIEventAdapter::MODKEY_CTRL)) || (key==3) || (key==24)) { - unsigned int _selectionMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); - unsigned int _selectionMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); + unsigned int selectionMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); + unsigned int selectionMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); - if (_selectionMax-_selectionMin>0) + if (selectionMax - selectionMin > 0) { std::string data; - for (unsigned int i=_selectionMin; i<=_selectionMax; ++i) - { - data.push_back(s[i]); - } + data.insert(data.begin(), s.begin() + selectionMin, s.begin() + selectionMax); + // Data to clipboard #ifdef WIN32 if(::OpenClipboard(NULL)) @@ -580,61 +573,69 @@ bool Input::keyDown(int key, int mask, const WindowManager*) { ::CloseClipboard(); } #endif - + + if (key=='x' || key=='X' || key == 24) + { + s.erase(s.begin() + selectionMin, s.begin() + selectionMax); + + _index = selectionMin; + + _selectionStartIndex = _selectionEndIndex = _index; + + _text->update(); + + _calculateCursorOffsets(); + + _calculateSize(getTextSize()); + + getParent()->resize(); + } } return false; } - { - unsigned int _selectionMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); - unsigned int _selectionMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); - if (_selectionMax-_selectionMin>0) + { + // If something is selected, we need to delete it and insert the character there. + unsigned int deleteMin = osg::minimum(_selectionStartIndex,_selectionEndIndex); + unsigned int deleteMax = osg::maximum(_selectionStartIndex,_selectionEndIndex); + + if (deleteMax - deleteMin > 0) { - unsigned int deleteToIdx = _selectionMax; - for (unsigned int i=0; i < s.size()-_selectionMin; ++i) - { - s[_selectionMin+i] = (deleteToIdx+i+1 < s.size()) ? s[deleteToIdx+i+1] : ' '; - } + s.erase(s.begin() + deleteMin, s.begin() + deleteMax); _text->update(); _calculateCursorOffsets(); - _textLength -= deleteToIdx-_selectionMin; - _index = _selectionMin; + _index = deleteMin; _selectionStartIndex = _selectionEndIndex = _index; } } - - - if (!_insertMode) + + if (_insertMode && _index < s.size()) { - for (unsigned int i=s.size()-1; i>_index; --i) - { - s[i] = s[i-1]; - } + s[_index] = key; + } + else + { + if (_index < _maxSize) + s.insert(s.begin() + _index, key); } - s[_index] = key; + _text->update(); - _text->update(); + _calculateCursorOffsets(); - _calculateCursorOffsets(); + _index++; - _index++; + _selectionStartIndex = _selectionEndIndex = _index; + } - if (!_insertMode) ++_textLength; + _calculateSize(getTextSize()); - _selectionStartIndex = _selectionEndIndex = _index; - } + getParent()->resize(); - // _text->update(); - - _calculateSize(getTextSize()); - - getParent()->resize(); - - return false; + return true; } void Input::setCursor(Widget*) { @@ -662,4 +663,21 @@ unsigned int Input::calculateBestYOffset(const std::string& s) return descent; } +void Input::clear() +{ + setLabel(""); + _text->update(); + _calculateCursorOffsets(); + + _index = 0; + _selectionStartIndex = _selectionEndIndex = _index; + _selectionIndex = _index; + _cursorIndex = _index; + + _calculateSize(getTextSize()); + + getParent()->resize(); +} + + } diff --git a/src/osgWidget/WindowManager.cpp b/src/osgWidget/WindowManager.cpp index 11df694dc..9f3520a34 100644 --- a/src/osgWidget/WindowManager.cpp +++ b/src/osgWidget/WindowManager.cpp @@ -615,7 +615,26 @@ bool WindowManager::keyDown(int key, int mask) { } bool WindowManager::keyUp(int key, int mask) { - return true; + if(_focused.valid()) { + Event ev(this, EVENT_KEY_UP); + + ev.makeKey(key, mask); + + Widget* focusedWidget = _focused->getFocused(); + + ev._window = _focused.get(); + ev._widget = focusedWidget; + + bool handled = false; + + if(focusedWidget) handled = focusedWidget->callMethodAndCallbacks(ev); + + if(!handled) return _focused->callMethodAndCallbacks(ev); + + else return true; + } + + return false; } // A convenience wrapper for creating a proper orthographic camera using the current