Add support to move the text box when we drag it from the edges

This commit is contained in:
David Capello 2024-08-27 14:38:16 -03:00
parent 241746d04b
commit 49afc0dd52
2 changed files with 99 additions and 6 deletions

View File

@ -99,6 +99,12 @@ public:
return m_extraCel; return m_extraCel;
} }
void setExtraCelBounds(const gfx::Rect& bounds) {
m_extraCel->cel()->setBounds(bounds);
renderExtraCelBase();
renderExtraCelText(true);
}
private: private:
bool onProcessMessage(Message* msg) override { bool onProcessMessage(Message* msg) override {
switch (msg->type()) { switch (msg->type()) {
@ -237,7 +243,8 @@ private:
WritingTextState::WritingTextState(Editor* editor, WritingTextState::WritingTextState(Editor* editor,
const gfx::Rect& bounds) const gfx::Rect& bounds)
: m_editor(editor) : m_delayedMouseMove(this, editor, 5)
, m_editor(editor)
, m_bounds(bounds) , m_bounds(bounds)
, m_entry(new TextEditor(editor, editor->getSite(), bounds)) , m_entry(new TextEditor(editor, editor->getSite(), bounds))
{ {
@ -258,8 +265,22 @@ WritingTextState::~WritingTextState()
bool WritingTextState::onMouseDown(Editor* editor, MouseMessage* msg) bool WritingTextState::onMouseDown(Editor* editor, MouseMessage* msg)
{ {
m_delayedMouseMove.onMouseDown(msg);
m_hit = calcHit(editor, msg->position());
if (msg->left()) { if (msg->left()) {
if (m_hit == Hit::Edges) {
m_mouseMoveReceived = false;
m_movingBounds = true;
m_cursorStart = editor->screenToEditorF(msg->position());
m_boundsOrigin = m_bounds.origin();
editor->captureMouse();
return true;
}
drop(); drop();
return true;
} }
else if (msg->right()) { else if (msg->right()) {
cancel(); cancel();
@ -271,16 +292,53 @@ bool WritingTextState::onMouseDown(Editor* editor, MouseMessage* msg)
bool WritingTextState::onMouseUp(Editor* editor, MouseMessage* msg) bool WritingTextState::onMouseUp(Editor* editor, MouseMessage* msg)
{ {
m_delayedMouseMove.onMouseUp(msg);
const bool result = StandbyState::onMouseUp(editor, msg); const bool result = StandbyState::onMouseUp(editor, msg);
if (msg->middle()) { if (m_movingBounds) {
if (m_entry) m_movingBounds = false;
m_entry->requestFocus();
// Drop if the user just clicked (so other text box is created)
if (!m_mouseMoveReceived)
drop();
} }
return result; return result;
} }
bool WritingTextState::onSetCursor(Editor* editor, const gfx::Point&) bool WritingTextState::onMouseMove(Editor* editor, ui::MouseMessage* msg)
{ {
m_delayedMouseMove.onMouseMove(msg);
// Use StandbyState implementation
return StandbyState::onMouseMove(editor, msg);
}
void WritingTextState::onCommitMouseMove(Editor* editor,
const gfx::PointF& spritePos)
{
if (!m_movingBounds)
return;
gfx::Point delta(spritePos - m_cursorStart);
if (delta.x == 0 && delta.y == 0)
return;
m_mouseMoveReceived = true;
m_bounds.setOrigin(gfx::Point(delta + m_boundsOrigin));
m_entry->setExtraCelBounds(m_bounds);
m_entry->setBounds(calcEntryBounds());
}
bool WritingTextState::onSetCursor(Editor* editor,
const gfx::Point& mouseScreenPos)
{
if (calcHit(editor, mouseScreenPos) == Hit::Edges) {
editor->showMouseCursor(kMoveCursor);
return true;
}
editor->showMouseCursor(kArrowCursor); editor->showMouseCursor(kArrowCursor);
return true; return true;
} }
@ -438,4 +496,16 @@ void WritingTextState::drop()
m_editor->invalidate(); m_editor->invalidate();
} }
WritingTextState::Hit WritingTextState::calcHit(Editor* editor,
const gfx::Point& mouseScreenPos)
{
auto edges = editor->editorToScreen(m_bounds);
if (!edges.contains(mouseScreenPos) &&
edges.enlarge(32*guiscale()).contains(mouseScreenPos)) {
return Hit::Edges;
}
return Hit::Normal;
}
} // namespace app } // namespace app

View File

@ -8,6 +8,7 @@
#define APP_UI_EDITOR_WRITING_TEXT_STATE_H_INCLUDED #define APP_UI_EDITOR_WRITING_TEXT_STATE_H_INCLUDED
#pragma once #pragma once
#include "app/ui/editor/delayed_mouse_move.h"
#include "app/ui/editor/standby_state.h" #include "app/ui/editor/standby_state.h"
#include <memory> #include <memory>
@ -15,7 +16,8 @@
namespace app { namespace app {
class CommandExecutionEvent; class CommandExecutionEvent;
class WritingTextState : public StandbyState { class WritingTextState : public StandbyState
, DelayedMouseMoveDelegate {
public: public:
WritingTextState(Editor* editor, WritingTextState(Editor* editor,
const gfx::Rect& bounds); const gfx::Rect& bounds);
@ -28,11 +30,21 @@ namespace app {
void onEditorResize(Editor* editor) override; void onEditorResize(Editor* editor) override;
bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override; bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override; bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override; bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override;
bool onKeyDown(Editor* editor, ui::KeyMessage* msg) override; bool onKeyDown(Editor* editor, ui::KeyMessage* msg) override;
bool onKeyUp(Editor* editor, ui::KeyMessage* msg) override; bool onKeyUp(Editor* editor, ui::KeyMessage* msg) override;
private: private:
enum class Hit {
Normal,
Edges,
};
// DelayedMouseMoveDelegate impl
void onCommitMouseMove(Editor* editor,
const gfx::PointF& spritePos) override;
gfx::Rect calcEntryBounds(); gfx::Rect calcEntryBounds();
void onBeforeCommandExecution(CommandExecutionEvent& ev); void onBeforeCommandExecution(CommandExecutionEvent& ev);
void onFontChange(); void onFontChange();
@ -41,8 +53,11 @@ namespace app {
void switchCaretVisiblity(); void switchCaretVisiblity();
Hit calcHit(Editor* editor, const gfx::Point& mouseScreenPos);
class TextEditor; class TextEditor;
DelayedMouseMove m_delayedMouseMove;
Editor* m_editor; Editor* m_editor;
gfx::Rect m_bounds; gfx::Rect m_bounds;
std::unique_ptr<TextEditor> m_entry; std::unique_ptr<TextEditor> m_entry;
@ -50,6 +65,14 @@ namespace app {
// True if the text was discarded. // True if the text was discarded.
bool m_discarded = false; bool m_discarded = false;
// To move text entry bounds when we drag the mouse from the edges
// of the TextEditor.
Hit m_hit = Hit::Normal;
bool m_mouseMoveReceived = false;
bool m_movingBounds = false;
gfx::PointF m_cursorStart;
gfx::Point m_boundsOrigin;
obs::scoped_connection m_beforeCmdConn; obs::scoped_connection m_beforeCmdConn;
obs::scoped_connection m_fontChangeConn; obs::scoped_connection m_fontChangeConn;
}; };