예제 #1
0
//----------------------------------------------------------------------------//
void Editbox::handleDelete(void)
{
    if (!isReadOnly())
    {
        String tmp(getText());

        if (getSelectionLength() != 0)
        {
            tmp.erase(getSelectionStartIndex(), getSelectionLength());

            if (handleValidityChangeForString(tmp))
            {
                // erase selection using mode that does not modify getText()
                // (we just want to update state)
                eraseSelectedText(false);

                // set text to the newly modified string
                setText(tmp);
            }
        }
        else if (getCaretIndex() < tmp.length())
        {
            tmp.erase(d_caretPos, 1);

            if (handleValidityChangeForString(tmp))
            {
                // set text to the newly modified string
                setText(tmp);
            }
        }

    }

}
예제 #2
0
void Editbox::eraseSelectedText(bool modify_text)
{
    if (getSelectionLength() != 0)
    {
        // setup new caret position and remove selection highlight.
        setCaretIndex(d_selectionStart);
        clearSelection();

        // erase the selected characters (if required)
        if (modify_text)
        {
            String newText = getText();
            UndoHandler::UndoAction undo;
            undo.d_type = UndoHandler::UAT_DELETE;
            undo.d_startIdx = getSelectionStart();
            undo.d_text = newText.substr(getSelectionStart(), getSelectionLength());
            d_undoHandler->addUndoHistory(undo);

            newText.erase(getSelectionStart(), getSelectionLength());
            setText(newText);

            // trigger notification that text has changed.
            WindowEventArgs args(this);
            onTextChanged(args);
        }

    }

}
예제 #3
0
//----------------------------------------------------------------------------//
bool Editbox::performCopy(Clipboard& clipboard)
{
    if (getSelectionLength() == 0)
        return false;

    const String selectedText = getText().substr(
                                    getSelectionStartIndex(), getSelectionLength());

    clipboard.setText(selectedText);
    return true;
}
예제 #4
0
void Editbox::handleDelete(void)
{
    if (!isReadOnly())
    {
        String tmp(getText());

        if (getSelectionLength() != 0)
        {
            UndoHandler::UndoAction undoSelection;
            undoSelection.d_type = UndoHandler::UAT_DELETE;
            undoSelection.d_startIdx = getSelectionStart();
            undoSelection.d_text = tmp.substr(getSelectionStart(), getSelectionLength());

            tmp.erase(getSelectionStart(), getSelectionLength());

            if (handleValidityChangeForString(tmp))
            {
                // erase selection using mode that does not modify getText()
                // (we just want to update state)
                eraseSelectedText(false);

                // set text to the newly modified string
                setText(tmp);
                d_undoHandler->addUndoHistory(undoSelection);
            }
        }
        else if (getCaretIndex() < tmp.length())
        {
            UndoHandler::UndoAction undo;
            undo.d_type = UndoHandler::UAT_DELETE;
            undo.d_startIdx = d_caretPos;

#if CEGUI_STRING_CLASS != CEGUI_STRING_CLASS_UTF_8
            size_t eraseLength = 1;
#else
            size_t eraseLength = String::getCodePointSize(tmp[d_caretPos]);
#endif

            undo.d_text = tmp.substr(d_caretPos, eraseLength);

            tmp.erase(d_caretPos, eraseLength);

            if (handleValidityChangeForString(tmp))
            {
                // set text to the newly modified string
                setText(tmp);
                d_undoHandler->addUndoHistory(undo);
            }
        }

    }

}
예제 #5
0
bool Editbox::performPaste(Clipboard& clipboard)
{
    if (isReadOnly())
        return false;

    String clipboardText = clipboard.getText();

    if (clipboardText.empty())
        return false;

    // backup current text
    String tmp(getText());

    UndoHandler::UndoAction undoSelection;
    undoSelection.d_type = UndoHandler::UAT_DELETE;
    undoSelection.d_startIdx = getSelectionStart();
    undoSelection.d_text = tmp.substr(getSelectionStart(), getSelectionLength());

    tmp.erase(getSelectionStart(), getSelectionLength());

    // if there is room
    if (tmp.length() < d_maxTextLen)
    {
        UndoHandler::UndoAction undo;
        undo.d_type = UndoHandler::UAT_INSERT;
        undo.d_startIdx = getCaretIndex();
        undo.d_text = clipboardText;

        tmp.insert(getSelectionStart(), clipboardText);

        if (handleValidityChangeForString(tmp))
        {
            // erase selection using mode that does not modify getText()
            // (we just want to update state)
            eraseSelectedText(false);

            // advance caret (done first so we can "do stuff" in event
            // handlers!)
            d_caretPos += clipboardText.length();

            // set text to the newly modified string
            setText(tmp);
            d_undoHandler->addUndoHistory(undo);
            if (getSelectionLength() > 0)
                d_undoHandler->addUndoHistory(undoSelection);

            return true;
        }
    }

    return false;
}
예제 #6
0
	void TextField::copy()
	{
		if(getSelectionLength() > 0)
		{
			Clipboard::copy(getSelectedText());
		}
	}
예제 #7
0
/*************************************************************************
	Clear the current selection setting
*************************************************************************/
void MultiLineEditbox::clearSelection(void)
{
	// perform action only if required.
	if (getSelectionLength() != 0)
	{
		setSelection(0, 0);
	}

}
예제 #8
0
/*************************************************************************
	Erase the currently selected text.
*************************************************************************/
void MultiLineEditbox::eraseSelectedText(bool modify_text)
{
	if (getSelectionLength() != 0)
	{
		// setup new carat position and remove selection highlight.
		setCaratIndex(getSelectionStartIndex());

		// erase the selected characters (if required)
		if (modify_text)
		{
			d_text.erase(getSelectionStartIndex(), getSelectionLength());

			// trigger notification that text has changed.
			WindowEventArgs args(this);
			onTextChanged(args);
		}

		clearSelection();
	}

}
예제 #9
0
	const std::string TextField::getSelectedText() const
	{
		if(getSelectionStart() == getSelectionEnd())
		{
			return std::string("");
		}
		else
		{
			return unicodeFunctions.subStr(getText(),
				getSelectionStart(),getSelectionLength());
		}
	}
예제 #10
0
//----------------------------------------------------------------------------//
void Editbox::onCharacter(KeyEventArgs& e)
{
    // NB: We are not calling the base class handler here because it propogates
    // inputs back up the window hierarchy, whereas, as a consumer of key
    // events, we want such propogation to cease with us regardless of whether
    // we actually handle the event.

    // fire event.
    fireEvent(EventCharacterKey, e, Window::EventNamespace);

    // only need to take notice if we have focus
    if (e.handled == 0 && hasInputFocus() && !isReadOnly() &&
            getFont()->isCodepointAvailable(e.codepoint))
    {
        // backup current text
        String tmp(getText());
        tmp.erase(getSelectionStartIndex(), getSelectionLength());

        // if there is room
        if (tmp.length() < d_maxTextLen)
        {
            tmp.insert(getSelectionStartIndex(), 1, e.codepoint);

            if (handleValidityChangeForString(tmp))
            {
                // erase selection using mode that does not modify getText()
                // (we just want to update state)
                eraseSelectedText(false);

                // advance caret (done first so we can "do stuff" in event
                // handlers!)
                d_caretPos++;

                // set text to the newly modified string
                setText(tmp);

                // char was accepted into the Editbox - mark event as handled.
                ++e.handled;
            }
        }
        else
        {
            // Trigger text box full event
            WindowEventArgs args(this);
            onEditboxFullEvent(args);
        }

    }

    // event was (possibly) not handled
}
예제 #11
0
/*************************************************************************
	Processing for backspace key
*************************************************************************/
void MultiLineEditbox::handleBackspace(void)
{
	if (!isReadOnly())
	{
		if (getSelectionLength() != 0)
		{
			eraseSelectedText();
		}
		else if (d_caratPos > 0)
		{
			d_text.erase(d_caratPos - 1, 1);
			setCaratIndex(d_caratPos - 1);

			WindowEventArgs args(this);
			onTextChanged(args);
		}

	}
}
예제 #12
0
	void TextField::paste()
	{
		if(isReadOnly())
		{
			return;
		}


		std::string pasteResult = Clipboard::paste();

		if(pasteResult.length() == 0 || getTextLength() - getSelectionLength() == getMaxLength())
		{
			return;
		}

		deleteSelection();
		int start = getCaretPosition();
		
		std::string noNewLine;

		for(size_t i = 0; i < pasteResult.size(); ++i)
		{
			if(pasteResult[i] != '\n')
			{
				noNewLine += pasteResult[i];
			}
		}

		int length = int(unicodeFunctions.length(noNewLine));
		int numRemainingChar = getMaxLength() - getTextLength();
		if(numRemainingChar < length)
		{
			noNewLine = unicodeFunctions.subStr(noNewLine,0,numRemainingChar);
			length = numRemainingChar;
		}
		if(length > 0)
		{
			std::string* cText = (std::string*)&getText();
			unicodeFunctions.insert(*cText,start,noNewLine);
			setThisText(*cText);
			positionCaret(caretPosition + length);
		}
	}
예제 #13
0
/*************************************************************************
	Processing for Delete key
*************************************************************************/
void MultiLineEditbox::handleDelete(void)
{
	if (!isReadOnly())
	{
		if (getSelectionLength() != 0)
		{
			eraseSelectedText();
		}
		else if (getCaratIndex() < d_text.length() - 1)
		{
			d_text.erase(d_caratPos, 1);
			ensureCaratIsVisible();

			WindowEventArgs args(this);
			onTextChanged(args);
		}

	}

}
예제 #14
0
	void TextField::appendText( const std::string& text, bool atCurrentPosition /*= true*/ )
	{
		if(text.length() == 0 || getTextLength() - getSelectionLength() == getMaxLength())
		{
			return;
		}

		deleteSelection();
		if(!atCurrentPosition)
		{
			positionCaret(getTextLength());
		}
		int start = getCaretPosition();

		std::string noNewLine;

		for(size_t i = 0; i < text.size(); ++i)
		{
			if(text[i] != '\n')
			{
				noNewLine += text[i];
			}
		}

		int length = int(unicodeFunctions.length(noNewLine));
		int numRemainingChar = getMaxLength() - getTextLength();
		if(numRemainingChar < length)
		{
			noNewLine = unicodeFunctions.subStr(noNewLine,0,numRemainingChar);
			length = numRemainingChar;
		}
		if(length > 0)
		{
			std::string* cText = (std::string*)&getText();
			unicodeFunctions.insert(*cText,start,noNewLine);
			setThisText(*cText);
			positionCaret(caretPosition + length);
		}
	}
예제 #15
0
//----------------------------------------------------------------------------//
bool Editbox::performPaste(Clipboard& clipboard)
{
    if (isReadOnly())
        return false;

    String clipboardText = clipboard.getText();

    if (clipboardText.empty())
        return false;

    // backup current text
    String tmp(getText());
    tmp.erase(getSelectionStartIndex(), getSelectionLength());

    // if there is room
    if (tmp.length() < d_maxTextLen)
    {
        tmp.insert(getSelectionStartIndex(), clipboardText);

        if (handleValidityChangeForString(tmp))
        {
            // erase selection using mode that does not modify getText()
            // (we just want to update state)
            eraseSelectedText(false);

            // advance caret (done first so we can "do stuff" in event
            // handlers!)
            d_caretPos += clipboardText.length();

            // set text to the newly modified string
            setText(tmp);

            return true;
        }
    }

    return false;
}
예제 #16
0
    void FalagardEditbox::populateRenderCache()
    {
        const StateImagery* imagery;

        // draw container etc
        // get WidgetLookFeel for the assigned look.
        const WidgetLookFeel& wlf = WidgetLookManager::getSingleton().getWidgetLook(d_lookName);
        // try and get imagery for the approprite state.
        imagery = &wlf.getStateImagery(isDisabled() ? "Disabled" : (isReadOnly() ? "ReadOnly" : "Enabled"));

        // peform the rendering operation for the container.
        imagery->render(*this);

        // get destination area for text
        const Rect textArea(wlf.getNamedArea("TextArea").getArea().getPixelRect(*this));

        //
        // Required preliminary work for text rendering operations
        //
        const Font* font = getFont();

        // no font == no more rendering
        if (!font)
            return;

        // This will point to the final string to be used for rendering.  Useful because it means we
        // do not have to have duplicate code or be copying d_text for handling masked/unmasked text.
        String* editText;

        // Create a 'masked' version of the string if needed.
        String maskedText;
        if (isTextMasked())
        {
            maskedText.insert(0, d_text.length(), getMaskCodePoint());
            editText = &maskedText;
        }
        // text not masked to editText will be the windows d_text String.
        else
        {
            editText = &d_text;
        }

        // calculate best position to render text to ensure carat is always visible
        float textOffset;
        float extentToCarat = font->getTextExtent(editText->substr(0, getCaratIndex()));

        // get carat imagery
        const ImagerySection& caratImagery = wlf.getImagerySection("Carat");
        // store carat width
        float caratWidth = caratImagery.getBoundingRect(*this, textArea).getWidth();

        // if box is inactive
        if (!hasInputFocus())
        {
            textOffset = d_lastTextOffset;
        }
        // if carat is to the left of the box
        else if ((d_lastTextOffset + extentToCarat) < 0)
        {
            textOffset = -extentToCarat;
        }
        // if carat is off to the right.
        else if ((d_lastTextOffset + extentToCarat) >= (textArea.getWidth() - caratWidth))
        {
            textOffset = textArea.getWidth() - extentToCarat - caratWidth;
        }
        // else carat is already within the box
        else
        {
            textOffset = d_lastTextOffset;
        }

        ColourRect colours;
        float alpha_comp = getEffectiveAlpha();

        //
        // Draw label text
        //
        // setup initial rect for text formatting
        Rect text_part_rect(textArea);
        // allow for scroll position
        text_part_rect.d_left += textOffset;
        // centre text vertically within the defined text area
        text_part_rect.d_top += (textArea.getHeight() - font->getLineSpacing()) * 0.5f;

        // draw pre-highlight text
        String sect = editText->substr(0, getSelectionStartIndex());
        colours.setColours(d_normalTextColour);
        colours.modulateAlpha(alpha_comp);
        d_renderCache.cacheText(sect, font, LeftAligned, text_part_rect, 0, colours, &textArea);

        // adjust rect for next section
        text_part_rect.d_left += font->getTextExtent(sect);

        // draw highlight text
        sect = editText->substr(getSelectionStartIndex(), getSelectionLength());
        colours.setColours(d_selectTextColour);
        colours.modulateAlpha(alpha_comp);
        d_renderCache.cacheText(sect, font, LeftAligned, text_part_rect, 0, colours, &textArea);

        // adjust rect for next section
        text_part_rect.d_left += font->getTextExtent(sect);

        // draw post-highlight text
        sect = editText->substr(getSelectionEndIndex());
        colours.setColours(d_normalTextColour);
        colours.modulateAlpha(alpha_comp);
        d_renderCache.cacheText(sect, font, LeftAligned, text_part_rect, 0, colours, &textArea);

        // remember this for next time.
        d_lastTextOffset = textOffset;

        // see if the editbox is active or inactive.
        bool active = (!isReadOnly()) && hasInputFocus();

        //
        // Render selection imagery.
        //
        if (getSelectionLength() != 0)
        {
            // calculate required start and end offsets of selection imagery.
            float selStartOffset = font->getTextExtent(editText->substr(0, getSelectionStartIndex()));
            float selEndOffset   = font->getTextExtent(editText->substr(0, getSelectionEndIndex()));

            // calculate area for selection imagery.
            Rect hlarea(textArea);
            hlarea.d_left += textOffset + selStartOffset;
            hlarea.d_right = hlarea.d_left + (selEndOffset - selStartOffset);

            // render the selection imagery.
            wlf.getStateImagery(active ? "ActiveSelection" : "InactiveSelection").render(*this, hlarea, 0, &textArea);
        }

        //
        // Render carat
        //
        if (active)
        {
            Rect caratRect(textArea);
            caratRect.d_left += extentToCarat + textOffset;

            caratImagery.render(*this, caratRect, 0, 0, &textArea);
        }
    }
예제 #17
0
void Editbox::handleBackspace(void)
{
    if (!isReadOnly())
    {
        String tmp(getText());

        if (getSelectionLength() != 0)
        {
            UndoHandler::UndoAction undoSelection;
            undoSelection.d_type = UndoHandler::UAT_DELETE;
            undoSelection.d_startIdx = getSelectionStart();
            undoSelection.d_text = tmp.substr(getSelectionStart(), getSelectionLength());

            tmp.erase(getSelectionStart(), getSelectionLength());

            if (handleValidityChangeForString(tmp))
            {
                // erase selection using mode that does not modify getText()
                // (we just want to update state)
                eraseSelectedText(false);

                // set text to the newly modified string
                setText(tmp);
                d_undoHandler->addUndoHistory(undoSelection);
            }
        }
        else if (getCaretIndex() > 0)
        {
            UndoHandler::UndoAction undo;
            undo.d_type = UndoHandler::UAT_DELETE;

#if CEGUI_STRING_CLASS != CEGUI_STRING_CLASS_UTF_8
            size_t deleteStartPos = d_caretPos - 1;
            size_t deleteLength = 1;
#else
            String::codepoint_iterator caretIter(tmp.begin() + d_caretPos,
                                                 tmp.begin(), tmp.end());
            --caretIter;

            size_t deleteStartPos = caretIter.getCodeUnitIndexFromStart();
            size_t deleteLength = d_caretPos - deleteStartPos;
#endif

            undo.d_startIdx = deleteStartPos;
            undo.d_text = tmp.substr(deleteStartPos, deleteLength);

            tmp.erase(deleteStartPos, deleteLength);

            if (handleValidityChangeForString(tmp))
            {
                setCaretIndex(deleteStartPos);

                // set text to the newly modified string
                setText(tmp);
                d_undoHandler->addUndoHistory(undo);
            }
        }

    }

}
예제 #18
0
//----------------------------------------------------------------------------//
void Editbox::onKeyDown(KeyEventArgs& e)
{
    // fire event.
    fireEvent(EventKeyDown, e, Window::EventNamespace);

    if (e.handled == 0 && hasInputFocus())
    {
        if (isReadOnly())
        {
            Window::onKeyDown(e);
            return;
        }

        WindowEventArgs args(this);
        switch (e.scancode)
        {
        case Key::LeftShift:
        case Key::RightShift:
            if (getSelectionLength() == 0)
                d_dragAnchorIdx = d_caretPos;
            break;

        case Key::Backspace:
            handleBackspace();
            break;

        case Key::Delete:
            handleDelete();
            break;

        case Key::Tab:
        case Key::Return:
        case Key::NumpadEnter:
            // Fire 'input accepted' event
            onTextAcceptedEvent(args);
            break;

        case Key::ArrowLeft:
            if (e.sysKeys & Control)
                handleWordLeft(e.sysKeys);
            else
                handleCharLeft(e.sysKeys);
            break;

        case Key::ArrowRight:
            if (e.sysKeys & Control)
                handleWordRight(e.sysKeys);
            else
                handleCharRight(e.sysKeys);
            break;

        case Key::Home:
            handleHome(e.sysKeys);
            break;

        case Key::End:
            handleEnd(e.sysKeys);
            break;

        default:
            Window::onKeyDown(e);
            return;
        }

        ++e.handled;
    }

}
예제 #19
0
void Editbox::onSemanticInputEvent(SemanticEventArgs& e)
{
    if (isDisabled())
        return;

    if (e.d_semanticValue == SV_SelectAll && e.d_payload.source == CIS_Left)
    {
        d_dragAnchorIdx = 0;
        setCaretIndex(getText().length());
        setSelection(d_dragAnchorIdx, d_caretPos);
        ++e.handled;
    }
    else if (e.d_semanticValue == SV_SelectWord && e.d_payload.source == CIS_Left)
    {
        // if masked, set up to select all
        if (isTextMaskingEnabled())
        {
            d_dragAnchorIdx = 0;
            setCaretIndex(getText().length());
        }
        // not masked, so select the word that was double-clicked.
        else
        {
            d_dragAnchorIdx = TextUtils::getWordStartIdx(getText(),
                (d_caretPos == getText().length()) ? d_caretPos :
                d_caretPos + 1);
            d_caretPos = TextUtils::getNextWordStartIdx(getText(), d_caretPos);
        }

        // perform actual selection operation.
        setSelection(d_dragAnchorIdx, d_caretPos);

        ++e.handled;
    }

    if (e.handled == 0 && hasInputFocus())
    {
        if (isReadOnly())
        {
            Window::onSemanticInputEvent(e);
            return;
        }

        if (getSelectionLength() == 0 && isSelectionSemanticValue(e.d_semanticValue))
            d_dragAnchorIdx = d_caretPos;

        // Check if the semantic value to be handled is of a general type and can thus be
        // handled via common EditboxBase handlers
        bool isSemanticValueHandled = handleBasicSemanticValue(e);

        // If the semantic value was not handled, check for specific values
        if (!isSemanticValueHandled)
        {
            // We assume it will be handled now, if not it will be set to false in default-case
            isSemanticValueHandled = true;

            switch (e.d_semanticValue)
            {
            case SV_Confirm:
            {
                WindowEventArgs args(this);
                // Fire 'input accepted' event
                onTextAcceptedEvent(args);
                break;
            }

            case SV_GoToStartOfLine:
                handleHome(false);
                break;

            case SV_GoToEndOfLine:
                handleEnd(false);
                break;

            case SV_SelectToStartOfLine:
                handleHome(true);
                break;

            case SV_SelectToEndOfLine:
                handleEnd(true);
                break;

            default:
                Window::onSemanticInputEvent(e);
                isSemanticValueHandled = false;
            }
        }

        if (isSemanticValueHandled)
            ++e.handled;
    }
}
예제 #20
0
/*************************************************************************
	Handler for when non-printable keys are typed.
*************************************************************************/
void MultiLineEditbox::onKeyDown(KeyEventArgs& e)
{
	// base class processing
	Window::onKeyDown(e);

	if (hasInputFocus() && !isReadOnly())
	{
		WindowEventArgs args(this);
		switch (e.scancode)
		{
		case Key::LeftShift:
		case Key::RightShift:
			if (getSelectionLength() == 0)
			{
				d_dragAnchorIdx = getCaratIndex();
			}
			break;

		case Key::Backspace:
			handleBackspace();
			break;

		case Key::Delete:
			handleDelete();
			break;

		case Key::Return:
		case Key::NumpadEnter:
			handleNewLine(e.sysKeys);
			break;

		case Key::ArrowLeft:
			if (e.sysKeys & Control)
			{
				handleWordLeft(e.sysKeys);
			}
			else
			{
				handleCharLeft(e.sysKeys);
			}
			break;

		case Key::ArrowRight:
			if (e.sysKeys & Control)
			{
				handleWordRight(e.sysKeys);
			}
			else
			{
				handleCharRight(e.sysKeys);
			}
			break;

		case Key::ArrowUp:
			handleLineUp(e.sysKeys);
			break;

		case Key::ArrowDown:
			handleLineDown(e.sysKeys);
			break;

		case Key::Home:
			if (e.sysKeys & Control)
			{
				handleDocHome(e.sysKeys);
			}
			else
			{
				handleLineHome(e.sysKeys);
			}
			break;

		case Key::End:
			if (e.sysKeys & Control)
			{
				handleDocEnd(e.sysKeys);
			}
			else
			{
				handleLineEnd(e.sysKeys);
			}
			break;

        // default case is now to leave event as (possibly) unhandled.
        default:
            return;
		}

		e.handled = true;
	}

}