Widgets/[Rich]TextAreaWidget: Add copy/cut/paste support
This commit is contained in:
parent
a29c0b0e63
commit
bb93209713
|
|
@ -73,10 +73,13 @@ namespace Nz
|
||||||
|
|
||||||
NazaraSignal(OnTextAreaCursorMove, const AbstractTextAreaWidget* /*textArea*/, Vector2ui* /*newCursorPosition*/);
|
NazaraSignal(OnTextAreaCursorMove, const AbstractTextAreaWidget* /*textArea*/, Vector2ui* /*newCursorPosition*/);
|
||||||
NazaraSignal(OnTextAreaKeyBackspace, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyBackspace, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
|
NazaraSignal(OnTextAreaKeyCopy, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
|
NazaraSignal(OnTextAreaKeyCut, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
NazaraSignal(OnTextAreaKeyDown, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyDown, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
NazaraSignal(OnTextAreaKeyEnd, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyEnd, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
NazaraSignal(OnTextAreaKeyHome, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyHome, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
NazaraSignal(OnTextAreaKeyLeft, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyLeft, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
|
NazaraSignal(OnTextAreaKeyPaste, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
NazaraSignal(OnTextAreaKeyReturn, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyReturn, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
NazaraSignal(OnTextAreaKeyRight, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyRight, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
NazaraSignal(OnTextAreaKeyUp, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
NazaraSignal(OnTextAreaKeyUp, const AbstractTextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/);
|
||||||
|
|
@ -86,13 +89,15 @@ namespace Nz
|
||||||
virtual AbstractTextDrawer& GetTextDrawer() = 0;
|
virtual AbstractTextDrawer& GetTextDrawer() = 0;
|
||||||
virtual const AbstractTextDrawer& GetTextDrawer() const = 0;
|
virtual const AbstractTextDrawer& GetTextDrawer() const = 0;
|
||||||
|
|
||||||
void Layout() override;
|
virtual void CopySelectionToClipboard(const Vector2ui& selectionBegin, const Vector2ui& selectionEnd) = 0;
|
||||||
|
|
||||||
virtual void HandleIndentation(bool add) = 0;
|
virtual void HandleIndentation(bool add) = 0;
|
||||||
virtual void HandleSelectionIndentation(bool add) = 0;
|
virtual void HandleSelectionIndentation(bool add) = 0;
|
||||||
virtual void HandleWordCursorMove(bool left) = 0;
|
virtual void HandleWordCursorMove(bool left) = 0;
|
||||||
|
|
||||||
bool IsFocusable() const override;
|
bool IsFocusable() const override;
|
||||||
|
void Layout() override;
|
||||||
|
|
||||||
void OnFocusLost() override;
|
void OnFocusLost() override;
|
||||||
void OnFocusReceived() override;
|
void OnFocusReceived() override;
|
||||||
bool OnKeyPressed(const WindowEvent::KeyEvent& key) override;
|
bool OnKeyPressed(const WindowEvent::KeyEvent& key) override;
|
||||||
|
|
@ -103,10 +108,13 @@ namespace Nz
|
||||||
void OnMouseMoved(int x, int y, int deltaX, int deltaY) override;
|
void OnMouseMoved(int x, int y, int deltaX, int deltaY) override;
|
||||||
void OnTextEntered(char32_t character, bool repeated) override;
|
void OnTextEntered(char32_t character, bool repeated) override;
|
||||||
|
|
||||||
|
virtual void PasteFromClipboard(const Vector2ui& targetPosition) = 0;
|
||||||
|
|
||||||
|
void RefreshCursor();
|
||||||
|
|
||||||
inline void SetCursorPositionInternal(std::size_t glyphIndex);
|
inline void SetCursorPositionInternal(std::size_t glyphIndex);
|
||||||
inline void SetCursorPositionInternal(Vector2ui cursorPosition);
|
inline void SetCursorPositionInternal(Vector2ui cursorPosition);
|
||||||
|
|
||||||
void RefreshCursor();
|
|
||||||
virtual void UpdateDisplayText() = 0;
|
virtual void UpdateDisplayText() = 0;
|
||||||
void UpdateTextSprite();
|
void UpdateTextSprite();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ namespace Nz
|
||||||
RichTextAreaWidget& operator=(RichTextAreaWidget&&) = default;
|
RichTextAreaWidget& operator=(RichTextAreaWidget&&) = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CopySelectionToClipboard(const Vector2ui& selectionBegin, const Vector2ui& selectionEnd) override;
|
||||||
|
|
||||||
AbstractTextDrawer& GetTextDrawer() override;
|
AbstractTextDrawer& GetTextDrawer() override;
|
||||||
const AbstractTextDrawer& GetTextDrawer() const override;
|
const AbstractTextDrawer& GetTextDrawer() const override;
|
||||||
|
|
||||||
|
|
@ -57,6 +59,8 @@ namespace Nz
|
||||||
void HandleSelectionIndentation(bool add) override;
|
void HandleSelectionIndentation(bool add) override;
|
||||||
void HandleWordCursorMove(bool left) override;
|
void HandleWordCursorMove(bool left) override;
|
||||||
|
|
||||||
|
void PasteFromClipboard(const Vector2ui& targetPosition) override;
|
||||||
|
|
||||||
void UpdateDisplayText() override;
|
void UpdateDisplayText() override;
|
||||||
|
|
||||||
RichTextDrawer m_drawer;
|
RichTextDrawer m_drawer;
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ namespace Nz
|
||||||
NazaraSignal(OnTextChanged, const AbstractTextAreaWidget* /*textArea*/, const std::string& /*text*/);
|
NazaraSignal(OnTextChanged, const AbstractTextAreaWidget* /*textArea*/, const std::string& /*text*/);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CopySelectionToClipboard(const Vector2ui& selectionBegin, const Vector2ui& selectionEnd) override;
|
||||||
|
|
||||||
AbstractTextDrawer& GetTextDrawer() override;
|
AbstractTextDrawer& GetTextDrawer() override;
|
||||||
const AbstractTextDrawer& GetTextDrawer() const override;
|
const AbstractTextDrawer& GetTextDrawer() const override;
|
||||||
|
|
||||||
|
|
@ -64,6 +66,8 @@ namespace Nz
|
||||||
void HandleSelectionIndentation(bool add) override;
|
void HandleSelectionIndentation(bool add) override;
|
||||||
void HandleWordCursorMove(bool left) override;
|
void HandleWordCursorMove(bool left) override;
|
||||||
|
|
||||||
|
void PasteFromClipboard(const Vector2ui& targetPosition) override;
|
||||||
|
|
||||||
void UpdateDisplayText() override;
|
void UpdateDisplayText() override;
|
||||||
void UpdateMinimumSize();
|
void UpdateMinimumSize();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,59 @@ namespace Nz
|
||||||
|
|
||||||
switch (key.virtualKey)
|
switch (key.virtualKey)
|
||||||
{
|
{
|
||||||
|
// Copy (Ctrl+C)
|
||||||
|
case Keyboard::VKey::C:
|
||||||
|
{
|
||||||
|
if (!key.control)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool ignoreDefaultAction = (m_echoMode != EchoMode::Normal);
|
||||||
|
OnTextAreaKeyCopy(this, &ignoreDefaultAction);
|
||||||
|
|
||||||
|
if (ignoreDefaultAction || !HasSelection())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CopySelectionToClipboard(m_cursorPositionBegin, m_cursorPositionEnd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paste (Ctrl+V)
|
||||||
|
case Keyboard::VKey::V:
|
||||||
|
{
|
||||||
|
if (!key.control)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool ignoreDefaultAction = false;
|
||||||
|
OnTextAreaKeyPaste(this, &ignoreDefaultAction);
|
||||||
|
|
||||||
|
if (ignoreDefaultAction)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (HasSelection())
|
||||||
|
EraseSelection();
|
||||||
|
|
||||||
|
PasteFromClipboard(m_cursorPositionBegin);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cut (Ctrl+X)
|
||||||
|
case Keyboard::VKey::X:
|
||||||
|
{
|
||||||
|
if (!key.control)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool ignoreDefaultAction = (m_echoMode != EchoMode::Normal);
|
||||||
|
OnTextAreaKeyCut(this, &ignoreDefaultAction);
|
||||||
|
|
||||||
|
if (ignoreDefaultAction || !HasSelection())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CopySelectionToClipboard(m_cursorPositionBegin, m_cursorPositionEnd);
|
||||||
|
EraseSelection();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case Keyboard::VKey::Backspace:
|
case Keyboard::VKey::Backspace:
|
||||||
{
|
{
|
||||||
bool ignoreDefaultAction = false;
|
bool ignoreDefaultAction = false;
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,11 @@ namespace Nz
|
||||||
UpdateDisplayText();
|
UpdateDisplayText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RichTextAreaWidget::CopySelectionToClipboard(const Vector2ui& selectionBegin, const Vector2ui& selectionEnd)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
AbstractTextDrawer& RichTextAreaWidget::GetTextDrawer()
|
AbstractTextDrawer& RichTextAreaWidget::GetTextDrawer()
|
||||||
{
|
{
|
||||||
return m_drawer;
|
return m_drawer;
|
||||||
|
|
@ -176,6 +181,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RichTextAreaWidget::PasteFromClipboard(const Vector2ui& targetPosition)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
void RichTextAreaWidget::UpdateDisplayText()
|
void RichTextAreaWidget::UpdateDisplayText()
|
||||||
{
|
{
|
||||||
/*m_drawer.Clear();
|
/*m_drawer.Clear();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <Nazara/Widgets/TextAreaWidget.hpp>
|
#include <Nazara/Widgets/TextAreaWidget.hpp>
|
||||||
#include <Nazara/Core/Unicode.hpp>
|
#include <Nazara/Core/Unicode.hpp>
|
||||||
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
||||||
|
#include <Nazara/Platform/Clipboard.hpp>
|
||||||
#include <Nazara/Utility/Font.hpp>
|
#include <Nazara/Utility/Font.hpp>
|
||||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||||
#include <Nazara/Widgets/Debug.hpp>
|
#include <Nazara/Widgets/Debug.hpp>
|
||||||
|
|
@ -110,6 +111,17 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextAreaWidget::CopySelectionToClipboard(const Vector2ui& selectionBegin, const Vector2ui& selectionEnd)
|
||||||
|
{
|
||||||
|
std::size_t glyphCount = ComputeCharacterCount(m_text);
|
||||||
|
assert(glyphCount > 0);
|
||||||
|
|
||||||
|
std::size_t startIndex = GetCharacterPosition(m_text, GetGlyphIndex(selectionBegin));
|
||||||
|
std::size_t endIndex = GetCharacterPosition(m_text, std::min(GetGlyphIndex(selectionEnd), glyphCount - 1));
|
||||||
|
|
||||||
|
Clipboard::SetString(m_text.substr(startIndex, endIndex - startIndex));
|
||||||
|
}
|
||||||
|
|
||||||
AbstractTextDrawer& TextAreaWidget::GetTextDrawer()
|
AbstractTextDrawer& TextAreaWidget::GetTextDrawer()
|
||||||
{
|
{
|
||||||
return m_drawer;
|
return m_drawer;
|
||||||
|
|
@ -216,6 +228,21 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextAreaWidget::PasteFromClipboard(const Vector2ui& targetPosition)
|
||||||
|
{
|
||||||
|
std::size_t glyphCount = ComputeCharacterCount(m_text);
|
||||||
|
std::size_t targetIndex = GetCharacterPosition(m_text, std::min(GetGlyphIndex(targetPosition), glyphCount));
|
||||||
|
|
||||||
|
std::string clipboardString = Clipboard::GetString();
|
||||||
|
if (clipboardString.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_text.insert(targetIndex, clipboardString);
|
||||||
|
UpdateDisplayText();
|
||||||
|
|
||||||
|
SetCursorPosition(targetIndex + ComputeCharacterCount(clipboardString));
|
||||||
|
}
|
||||||
|
|
||||||
void TextAreaWidget::UpdateDisplayText()
|
void TextAreaWidget::UpdateDisplayText()
|
||||||
{
|
{
|
||||||
switch (m_echoMode)
|
switch (m_echoMode)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue