Пример #1
0
	void LineEditor::_render( GfxDevice * pDevice, const Rect& _canvas, const Rect& _window, const Rect& _clip )
	{
		Widget::_render(pDevice,_canvas,_window,_clip);
	
		LegacyTextItem * pText = &m_text;
	
	//TODO: Get password mode working again!
	/*
		if( m_bPasswordMode )
		{
			int nChars = m_text.length();
			uint16_t * pContent = new uint16_t[nChars+1];
			for( int i = 0 ; i < nChars ; i++ )
				pContent[i] = m_pwGlyph;
			pContent[nChars] = 0;
			pText = new LegacyTextItem( pContent );
			delete [] pContent;
	
			pText->setWrap(false);
			pText->setAutoEllipsis(false);
			pText->setAlignment(m_text.alignment());
			pText->setProperties(m_text.properties());
			pText->setSelectionProperties(m_text.selectionProperties());
			pText->setState(m_text.state());
	
			pText->setEditMode(m_text.editMode());
			pText->showCaret();
			pText->gotoSoftPos( m_text.line(), m_text.column() );
			pText->incTime( m_text.time() );
	
			int sl, sc, el, ec;
			if( m_text.getSelection(sl, sc, el, ec) )
				pText->selectText(sl, sc, el, ec);
		}
	*/
	
		Rect canvas;
		if( m_pSkin )
			canvas = m_pSkin->sizeForContent(_canvas);
		else
			canvas = _canvas;
	
		Rect	textClip( _clip, canvas );
	
		canvas.x -= m_viewOfs;
		canvas.w += m_viewOfs;
	
		if( m_state.isFocused() && _isEditable() )
			pText->showCaret();
		else
			pText->hideCaret();
	
		pDevice->printText( textClip, pText, canvas );
	
		if( pText != &m_text )
			delete pText;
	}
Пример #2
0
void WgLineEditor::_onRender( WgGfxDevice * pDevice, const WgRect& _canvas, const WgRect& _window, const WgRect& _clip )
{
    WgWidget::_onRender(pDevice,_canvas,_window,_clip);

    WgLegacyTextField * pText = &m_text;

//TODO: Get password mode working again!
    /*
    	if( m_bPasswordMode )
    	{
    		int nChars = m_text.Length();
    		Uint16 * pContent = new Uint16[nChars+1];
    		for( int i = 0 ; i < nChars ; i++ )
    			pContent[i] = m_pwGlyph;
    		pContent[nChars] = 0;
    		pText = new WgLegacyTextField( pContent );
    		delete [] pContent;

    		pText->SetWrap(false);
    		pText->SetAutoEllipsis(false);
    		pText->SetAlignment(m_text.Alignment());
    		pText->SetProperties(m_text.Properties());
    		pText->SetSelectionProperties(m_text.SelectionProperties());
    		pText->setState(m_text.State());

    		pText->SetEditMode(m_text.EditMode());
    		pText->showCursor();
    		pText->gotoSoftPos( m_text.line(), m_text.column() );
    		pText->incTime( m_text.time() );

    		int sl, sc, el, ec;
    		if( m_text.getSelection(sl, sc, el, ec) )
    			pText->selectText(sl, sc, el, ec);
    	}
    */

    WgRect canvas;
    if( m_pSkin )
        canvas = m_pSkin->SizeForContent(_canvas);
    else
        canvas = _canvas;

    WgRect	textClip( _clip, canvas );

    canvas.x -= m_viewOfs;
    canvas.w += m_viewOfs;

    if( m_state.IsFocused() && _isEditable() )
        pText->showCursor();
    else
        pText->hideCursor();

    pDevice->PrintText( textClip, pText, canvas );

    if( pText != &m_text )
        delete pText;
}
Пример #3
0
	void LineEditor::_setState( State state )
	{
		State oldState = m_state;
		
		Widget::_setState(state);
		
		m_text.setState(state);
		_requestRender();				//TODO: Only request render if text appearance has changed.
	
		if( state.isFocused() && !oldState.isFocused() )
		{
			if( _isEditable() )
			{
				m_tickRouteId = Base::msgRouter()->addRoute( MsgType::Tick, this );
				if( m_bResetCaretOnFocus )
					m_text.goEol();
				_requestRender(); // render with cursor on
			}
		}
	
		if( !state.isFocused() && oldState.isFocused() )
		{
			if( _isSelectable() )
			{
				m_text.clearSelection();
				m_text.setSelectionMode(false);
				m_bResetCaretOnFocus = false;
			}
	
			if( _isEditable() || m_viewOfs != 0 )
			{
				Base::msgRouter()->deleteRoute( m_tickRouteId );
				m_tickRouteId = 0;
				Base::msgRouter()->post( new TextEditMsg(text.ptr(),true) );
	
				m_viewOfs = 0;
				_requestRender();
			}
		}
	}
Пример #4
0
void WgLineEditor::_onStateChanged( WgState oldState )
{
    WgWidget::_onStateChanged(oldState);

    m_text.setState(m_state);
    _requestRender();				//TODO: Only request render if text appearance has changed.

    if( m_state.IsFocused() && !oldState.IsFocused() )
    {
        if( _isEditable() )
        {
            _startReceiveTicks();
            if( m_bResetCursorOnFocus )
                m_text.GoEOL();
            _requestRender(); // render with cursor on
        }
    }

    if( !m_state.IsFocused() && oldState.IsFocused() )
    {
        if( _isSelectable() )
        {
            m_text.ClearSelection();
            m_text.setSelectionMode(false);
            m_bResetCursorOnFocus = false;
        }

        if( _isEditable() || m_viewOfs != 0 )
        {
            _stopReceiveTicks();
            _queueEvent( new WgTextEditEvent(this, &text,true) );

            m_viewOfs = 0;
            _requestRender();
        }
    }
}
Пример #5
0
	bool LineEditor::insertCharAtCaret( uint16_t c )
	{
		if( !_isEditable() )
			return false;
	
		if( !m_state.isFocused() )
			if( !grabFocus() )
				return false;				// Couldn't get input focus...
	
		if( !m_text.putChar( c ) )
			return false;
	
		Base::msgRouter()->post( new TextEditMsg(text.ptr(),false) );
	
		_adjustViewOfs();
		return true;
	}
Пример #6
0
	int LineEditor::insertTextAtCaret( const CharSeq& str )
	{
		if( !_isEditable() )
			return 0;
	
		if( !m_state.isFocused() )
			if( !grabFocus() )
				return 0;				// Couldn't get input focus...
	
		int retVal = m_text.putText( str );
	
		Base::msgRouter()->post( new TextEditMsg(text.ptr(),false) );
	
		_adjustViewOfs();
	
		return retVal;
	}
Пример #7
0
bool WgLineEditor::InsertCharAtCursor( Uint16 c )
{
    if( !_isEditable() )
        return false;

    if( !m_state.IsFocused() )
        if( !GrabFocus() )
            return false;				// Couldn't get input focus...

    if( !m_text.putChar( c ) )
        return false;

    _queueEvent( new WgTextEditEvent(this,&text,false) );

    _adjustViewOfs();
    return true;
}
Пример #8
0
int WgLineEditor::InsertTextAtCursor( const WgCharSeq& str )
{
    if( !_isEditable() )
        return 0;

    if( !m_state.IsFocused() )
        if( !GrabFocus() )
            return 0;				// Couldn't get input focus...

    int retVal = m_text.putText( str );

    _queueEvent( new WgTextEditEvent(this,&text,false) );

    _adjustViewOfs();

    return retVal;
}
Пример #9
0
	void LineEditor::_receive( const Msg_p& pMsg )
	{
		Widget::_receive(pMsg);
	
		MsgRouter_p	pHandler = Base::msgRouter();
		MsgType event = pMsg->type();
	
		if( event == MsgType::Tick )
		{
			if( _isSelectable() && m_state.isFocused() )
			{
				m_text.incTime( TickMsg::cast(pMsg)->timediff() );
				_requestRender();					//TODO: Should only render the cursor and selection!
			}
			return;
		}
	
		if( (event == MsgType::MousePress || event == MsgType::MouseDrag) && MouseButtonMsg::cast(pMsg)->button() == MouseButton::Left )
		{
			MouseButtonMsg_p pButtonMsg = MouseButtonMsg::cast(pMsg);
			
			if( !m_state.isFocused() )
				grabFocus();
	
			if( m_state.isFocused() )
			{
				if( _isSelectable() && (pButtonMsg->modKeys() & MODKEY_SHIFT) )
				{
					m_text.setSelectionMode(true);
				}
	
				Coord ofs = pButtonMsg->pointerPos() - globalPos();
				int x = ofs.x + m_viewOfs;
				int y = 0;
	
				if( m_bPasswordMode )
				{
					TextAttr	attr;
					m_text.getBaseAttr( attr );
	
					Pen	pen;
					pen.setAttributes( attr );
					pen.setChar(m_pwGlyph);
					pen.advancePos();
	
					int spacing = pen.getPosX();
					int height = pen.getLineSpacing();
	
					int line = y/height;
					int col = (x+spacing/2)/spacing;
					if(col < 0)
					{
						col = 0;
						line = 0;
					}
					m_text.gotoSoftPos(line,col);
				}
				else
				{
					m_text.cursorGotoCoord( Coord(x, 0), Rect(0,0,1000000,1000000) );
				}
	
				if(_isSelectable() && event == MsgType::MousePress && !(pButtonMsg->modKeys() & MODKEY_SHIFT))
				{
					m_text.clearSelection();
					m_text.setSelectionMode(true);
				}
			}
			_adjustViewOfs();
		}
	
		if( event == MsgType::MouseRelease )
		{
			if( m_state.isFocused() && MouseButtonMsg::cast(pMsg)->button() == MouseButton::Left )
				m_text.setSelectionMode(false);
		}		
	
		if( event == MsgType::TextInput )
		{
			String str = TextInputMsg::cast(pMsg)->text();
	
			if( _isEditable() && m_state.isFocused() )
			{
				if(m_text.hasSelection())
					m_text.delSelection();
				m_text.setSelectionMode(false);

				bool bModified = false;
				for( int i = 0 ; i < str.length() ; i++ )
				{
					unsigned short ch = str.chars()[i].getGlyph();
					
					if( ch >= 32 && ch != 127 )
					{
						if( m_text.putChar( ch ) )
							bModified = true;
					}
				}

				if( bModified )
				{
					if( pHandler )
						pHandler->post( new TextEditMsg(text.ptr(),false) );

					_adjustViewOfs();
				}
	
			}
		}
	
		if( event == MsgType::KeyRelease && m_state.isFocused() )
		{
			Key key = KeyMsg::cast(pMsg)->translatedKeyCode();
			switch( key )
			{
				case Key::Shift:
					if(!Base::inputHandler()->isButtonPressed(MouseButton::Left))
						m_text.setSelectionMode(false);
				break;
			}
		}
	
		if( (event == MsgType::KeyPress || event == MsgType::KeyRepeat) && _isEditable() && m_state.isFocused() )
		{
			KeyMsg_p pKeyMsg = KeyMsg::cast(pMsg);
			Key key = pKeyMsg->translatedKeyCode();
			switch( key )
			{
				case Key::Left:
					if( pKeyMsg->modKeys() & MODKEY_SHIFT )
						m_text.setSelectionMode(true);
	
					if( pKeyMsg->modKeys() & MODKEY_CTRL )
					{
						if( m_bPasswordMode )
							m_text.goBol();
						else
							m_text.gotoPrevWord();
					}
					else
					{
						m_text.goLeft();
					}
					break;
				case Key::Right:
					if( pKeyMsg->modKeys() & MODKEY_SHIFT )
						m_text.setSelectionMode(true);
	
					if( pKeyMsg->modKeys() & MODKEY_CTRL )
					{
						if( m_bPasswordMode )
							m_text.goEol();
						else
							m_text.gotoNextWord();
					}
					else
					{
						m_text.goRight();
					}
					break;
	
				case Key::Backspace:
				{
					if(m_text.hasSelection())
						m_text.delSelection();
					else if( (pKeyMsg->modKeys() & MODKEY_CTRL) && !m_bPasswordMode)
						m_text.delPrevWord();
					else
						m_text.delPrevChar();
	
					if( pHandler )
						pHandler->post( new TextEditMsg(text.ptr(),false) );
					break;
				}
	
				case Key::Delete:
				{
					if(m_text.hasSelection())
						m_text.delSelection();
					else if( (pKeyMsg->modKeys() & MODKEY_CTRL) && !m_bPasswordMode)
						m_text.delNextWord();
					else
						m_text.delNextChar();
	
					if( pHandler )
						pHandler->post( new TextEditMsg(text.ptr(),false) );
					break;
				}
	
				case Key::Home:
	
					/*
					 *	I am not sure if this is the proper way to this, but in my opinion, the default
					 *	"actions" has to be separated from any modifier key action combination
					 */
					switch( pKeyMsg->modKeys() )
					{
	
					case MODKEY_CTRL:
						break;
	
					default: // no modifier key was pressed
						if(pKeyMsg->modKeys() & MODKEY_SHIFT )
							m_text.setSelectionMode(true);
	
						m_text.goBol();
						break;
					}
	
					break;
	
				case Key::End:
	
					/*
				 	 *	I am not sure if this is the proper way to this, but in my opinion, the default
			 		 *	"actions" has to be separated from any modifier key action combination
					 */
					switch( pKeyMsg->modKeys() )
					{
	
					case MODKEY_CTRL:
						break;
	
					default: // no modifier key was pressed
						if( pKeyMsg->modKeys() & MODKEY_SHIFT )
							m_text.setSelectionMode(true);
	
						m_text.goEol();
						break;
					}
	
					break;
	
				default:
					break;
			}
			_adjustViewOfs();
		}
	
		// Swallow message depending on rules.
	
		if( pMsg->isMouseButtreceive() )
		{
			if( MouseButtonMsg::cast(pMsg)->button() == MouseButton::Left )
				pMsg->swallow();
		}
		else if( pMsg->isKeyMsg() )
		{
			Key key = KeyMsg::cast(pMsg)->translatedKeyCode();
			if( KeyMsg::cast(pMsg)->isMovementKey() == true ||
				key == Key::Delete || key == Key::Backspace )
					pMsg->swallow();
			
			//TODO: Would be good if we didn't forward any character-creating keys either...
		}
	}
Пример #10
0
void WgLineEditor::_onEvent( const WgEventPtr& pEvent, WgEventHandler * pHandler )
{
    WgWidget::_onEvent(pEvent,pHandler);

    WgEventType event = pEvent->Type();

    if( event == WG_EVENT_TICK )
    {
        if( _isSelectable() && m_state.IsFocused() )
        {
            m_text.incTime( WgTickEvent::Cast(pEvent)->Millisec() );
            _requestRender();					//TODO: Should only render the cursor and selection!
        }
        return;
    }

    if( (event == WG_EVENT_MOUSE_PRESS || event == WG_EVENT_MOUSE_DRAG) && WgMouseButtonEvent::Cast(pEvent)->Button() == WG_BUTTON_LEFT )
    {
        if( !m_state.IsFocused() )
            GrabFocus();

        if( m_state.IsFocused() )
        {
            if( _isSelectable() && (pEvent->ModKeys() & WG_MODKEY_SHIFT) )
            {
                m_text.setSelectionMode(true);
            }

            WgCoord ofs = pEvent->PointerPos();
            int x = ofs.x + m_viewOfs;
            int y = 0;

            if( m_bPasswordMode )
            {
                WgTextAttr	attr;
                m_text.GetBaseAttr( attr );

                WgPen	pen;
                pen.SetAttributes( attr );
                pen.SetChar(m_pwGlyph);
                pen.AdvancePos();

                int spacing = pen.GetPosX();
                int height = pen.GetLineSpacing();

                int line = y/height;
                int col = (x+spacing/2)/spacing;
                if(col < 0)
                {
                    col = 0;
                    line = 0;
                }
                m_text.gotoSoftPos(line,col);
            }
            else
            {
                m_text.CursorGotoCoord( WgCoord(x, 0), WgRect(0,0,1000000,1000000) );
            }

            if(_isSelectable() && event == WG_EVENT_MOUSE_PRESS && !(pEvent->ModKeys() & WG_MODKEY_SHIFT))
            {
                m_text.ClearSelection();
                m_text.setSelectionMode(true);
            }
        }
        _adjustViewOfs();
    }

    if( event == WG_EVENT_MOUSE_RELEASE )
    {
        if( m_state.IsFocused() && WgMouseButtonEvent::Cast(pEvent)->Button() == WG_BUTTON_LEFT )
            m_text.setSelectionMode(false);
    }

    if( event == WG_EVENT_CHARACTER )
    {
        int ch = WgCharacterEvent::Cast(pEvent)->Char();

        if( _isEditable() && m_state.IsFocused() && ch >= 32 && ch != 127)
        {

            if(m_text.hasSelection())
                m_text.delSelection();
            m_text.setSelectionMode(false);

            if( m_text.putChar( ch ) )
            {
                if( pHandler )
                    pHandler->QueueEvent( new WgTextEditEvent(this,&text,false) );

                _adjustViewOfs();
            }
        }
    }

    if( event == WG_EVENT_KEY_RELEASE && m_state.IsFocused() )
    {
        int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode();
        switch( key )
        {
        case WG_KEY_SHIFT:
            if(!pHandler->IsMouseButtonPressed(1))
                m_text.setSelectionMode(false);
            break;
        }
    }

    if( (event == WG_EVENT_KEY_PRESS || event == WG_EVENT_KEY_REPEAT) && _isEditable() && m_state.IsFocused() )
    {
        int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode();
        switch( key )
        {
        case WG_KEY_LEFT:
            if( pEvent->ModKeys() & WG_MODKEY_SHIFT )
                m_text.setSelectionMode(true);

            if( pEvent->ModKeys() & WG_MODKEY_CTRL )
            {
                if( m_bPasswordMode )
                    m_text.GoBOL();
                else
                    m_text.gotoPrevWord();
            }
            else
            {
                m_text.goLeft();
            }
            break;
        case WG_KEY_RIGHT:
            if( pEvent->ModKeys() & WG_MODKEY_SHIFT )
                m_text.setSelectionMode(true);

            if( pEvent->ModKeys() & WG_MODKEY_CTRL )
            {
                if( m_bPasswordMode )
                    m_text.GoEOL();
                else
                    m_text.gotoNextWord();
            }
            else
            {
                m_text.goRight();
            }
            break;

        case WG_KEY_BACKSPACE:
        {
            if(m_text.hasSelection())
                m_text.delSelection();
            else if( (pEvent->ModKeys() & WG_MODKEY_CTRL) && !m_bPasswordMode)
                m_text.delPrevWord();
            else
                m_text.delPrevChar();

            if( pHandler )
                pHandler->QueueEvent( new WgTextEditEvent(this,&text,false) );
            break;
        }

        case WG_KEY_DELETE:
        {
            if(m_text.hasSelection())
                m_text.delSelection();
            else if( (pEvent->ModKeys() & WG_MODKEY_CTRL) && !m_bPasswordMode)
                m_text.delNextWord();
            else
                m_text.delNextChar();

            if( pHandler )
                pHandler->QueueEvent( new WgTextEditEvent(this,&text,false) );
            break;
        }

        case WG_KEY_HOME:

            /*
             *	I am not sure if this is the proper way to this, but in my opinion, the default
             *	"actions" has to be separated from any modifier key action combination
             */
            switch( pEvent->ModKeys() )
            {

            case WG_MODKEY_CTRL:
                break;

            default: // no modifier key was pressed
                if(pEvent->ModKeys() & WG_MODKEY_SHIFT )
                    m_text.setSelectionMode(true);

                m_text.GoBOL();
                break;
            }

            break;

        case WG_KEY_END:

            /*
             *	I am not sure if this is the proper way to this, but in my opinion, the default
             *	"actions" has to be separated from any modifier key action combination
             */
            switch( pEvent->ModKeys() )
            {

            case WG_MODKEY_CTRL:
                break;

            default: // no modifier key was pressed
                if( pEvent->ModKeys() & WG_MODKEY_SHIFT )
                    m_text.setSelectionMode(true);

                m_text.GoEOL();
                break;
            }

            break;

        default:
            break;
        }
        _adjustViewOfs();
    }

    // Forward event depending on rules.

    if( pEvent->IsMouseButtonEvent() )
    {
        if( WgMouseButtonEvent::Cast(pEvent)->Button() == WG_BUTTON_LEFT )
            pHandler->SwallowEvent(pEvent);
    }
    else if( pEvent->IsKeyEvent() )
    {
        int key = WgKeyEvent::Cast(pEvent)->TranslatedKeyCode();
        if( WgKeyEvent::Cast(pEvent)->IsMovementKey() == true ||
                key == WG_KEY_DELETE || key == WG_KEY_BACKSPACE )
            pHandler->SwallowEvent(pEvent);

        //TODO: Would be good if we didn't forward any character-creating keys either...
    }
}