experimental/editor: mouse drag select, modifierkeys cleanup.
Change-Id: I8c8de54ad6309424bdf18987ccf3eac6bdd41c19 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/233080 Commit-Queue: Hal Canary <halcanary@google.com> Reviewed-by: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
228518f0f8
commit
bcfed55a8c
@ -148,31 +148,33 @@ struct EditorLayer : public sk_app::Window::Layer {
|
||||
|
||||
void inval() { if (fParent) { fParent->inval(); } }
|
||||
|
||||
bool onMouseWheel(float delta, ModifierKey modifiers) override {
|
||||
bool onMouseWheel(float delta, ModifierKey) override {
|
||||
this->scroll(-(int)(delta * fEditor.font().getSpacing()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fMouseDown = false;
|
||||
|
||||
bool onMouse(int x, int y, InputState state, ModifierKey modifiers) override {
|
||||
if (InputState::kDown == state) {
|
||||
y += fPos - fMargin;
|
||||
x -= fMargin;
|
||||
editor::Editor::TextPosition pos = fEditor.getPosition(SkIPoint{x, y});
|
||||
#ifdef SK_EDITOR_DEBUG_OUT
|
||||
SkDebugf("select: line:%d column:%d \n", pos.fParagraphIndex, pos.fTextByteIndex);
|
||||
#endif // SK_EDITOR_DEBUG_OUT
|
||||
if (pos != editor::Editor::TextPosition()) {
|
||||
fTextPos = pos;
|
||||
this->inval();
|
||||
}
|
||||
bool mouseDown = InputState::kDown == state;
|
||||
if (mouseDown) {
|
||||
fMouseDown = true;
|
||||
} else if (InputState::kUp == state) {
|
||||
fMouseDown = false;
|
||||
}
|
||||
return true;
|
||||
bool shiftOrDrag = skstd::Any(modifiers & ModifierKey::kShift) || !mouseDown;
|
||||
if (fMouseDown) {
|
||||
return this->move(fEditor.getPosition({x - fMargin, y + fPos - fMargin}), shiftOrDrag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool onChar(SkUnichar c, ModifierKey modifiers) override {
|
||||
if (!ModifierKeyIsSet(modifiers & (ModifierKey::kControl |
|
||||
ModifierKey::kOption |
|
||||
ModifierKey::kCommand))) {
|
||||
bool onChar(SkUnichar c, ModifierKey modi) override {
|
||||
using skstd::Any;
|
||||
modi &= ~ModifierKey::kFirstPress;
|
||||
if (!Any(modi & (ModifierKey::kControl |
|
||||
ModifierKey::kOption |
|
||||
ModifierKey::kCommand))) {
|
||||
if (((unsigned)c < 0x7F && (unsigned)c >= 0x20) || c == '\n') {
|
||||
char ch = (char)c;
|
||||
fEditor.insert(fTextPos, &ch, 1);
|
||||
@ -182,7 +184,9 @@ struct EditorLayer : public sk_app::Window::Layer {
|
||||
return this->moveCursor(editor::Editor::Movement::kRight);
|
||||
}
|
||||
}
|
||||
if (modifiers == ModifierKey::kControl) {
|
||||
static constexpr ModifierKey kCommandOrControl = ModifierKey::kCommand |
|
||||
ModifierKey::kControl;
|
||||
if (Any(modi & kCommandOrControl) && !Any(modi & ~kCommandOrControl)) {
|
||||
switch (c) {
|
||||
case 'p':
|
||||
for (editor::StringView str : fEditor.text()) {
|
||||
@ -208,6 +212,7 @@ struct EditorLayer : public sk_app::Window::Layer {
|
||||
fClipboard.resize(fEditor.copy(fMarkPos, fTextPos, nullptr));
|
||||
fEditor.copy(fMarkPos, fTextPos, fClipboard.data());
|
||||
fTextPos = fEditor.remove(fMarkPos, fTextPos);
|
||||
fMarkPos = editor::Editor::TextPosition();
|
||||
this->inval();
|
||||
return true;
|
||||
}
|
||||
@ -224,12 +229,20 @@ struct EditorLayer : public sk_app::Window::Layer {
|
||||
#endif // SK_EDITOR_DEBUG_OUT
|
||||
return false;
|
||||
}
|
||||
|
||||
bool moveCursor(editor::Editor::Movement m, bool shift = false) {
|
||||
return this->move(fEditor.move(m, fTextPos), shift);
|
||||
}
|
||||
|
||||
bool move(editor::Editor::TextPosition pos, bool shift) {
|
||||
if (pos == fTextPos || pos == editor::Editor::TextPosition()) {
|
||||
return false;
|
||||
}
|
||||
if (shift != fShiftDown) {
|
||||
fMarkPos = shift ? fTextPos : editor::Editor::TextPosition();
|
||||
fMarkPos = shift ? fTextPos : editor::Editor::TextPosition();
|
||||
fShiftDown = shift;
|
||||
}
|
||||
fTextPos = fEditor.move(m, fTextPos);
|
||||
fTextPos = pos;
|
||||
|
||||
// scroll if needed.
|
||||
SkIRect cursor = fEditor.getLocation(fTextPos).roundOut();
|
||||
@ -249,10 +262,12 @@ struct EditorLayer : public sk_app::Window::Layer {
|
||||
return false; // ignore keyup
|
||||
}
|
||||
// ignore other modifiers.
|
||||
using skstd::Any;
|
||||
ModifierKey ctrlAltCmd = modifiers & (ModifierKey::kControl |
|
||||
ModifierKey::kOption |
|
||||
ModifierKey::kCommand);
|
||||
if (!ModifierKeyIsSet(ctrlAltCmd)) {
|
||||
bool shift = Any(modifiers & (ModifierKey::kShift));
|
||||
if (!Any(ctrlAltCmd)) {
|
||||
// no modifiers
|
||||
switch (key) {
|
||||
case sk_app::Window::Key::kPageDown:
|
||||
@ -265,8 +280,7 @@ struct EditorLayer : public sk_app::Window::Layer {
|
||||
case sk_app::Window::Key::kDown:
|
||||
case sk_app::Window::Key::kHome:
|
||||
case sk_app::Window::Key::kEnd:
|
||||
return this->moveCursor(convert(key),
|
||||
(int)(modifiers & ModifierKey::kShift));
|
||||
return this->moveCursor(convert(key), shift);
|
||||
case sk_app::Window::Key::kDelete:
|
||||
if (fMarkPos != editor::Editor::TextPosition()) {
|
||||
fTextPos = fEditor.remove(fMarkPos, fTextPos);
|
||||
@ -294,14 +308,12 @@ struct EditorLayer : public sk_app::Window::Layer {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (ModifierKeyIsSet(ctrlAltCmd & (ModifierKey::kControl | ModifierKey::kCommand))) {
|
||||
} else if (skstd::Any(ctrlAltCmd & (ModifierKey::kControl | ModifierKey::kCommand))) {
|
||||
switch (key) {
|
||||
case sk_app::Window::Key::kLeft:
|
||||
return this->moveCursor(editor::Editor::Movement::kWordLeft,
|
||||
(int)(modifiers & ModifierKey::kShift));
|
||||
return this->moveCursor(editor::Editor::Movement::kWordLeft, shift);
|
||||
case sk_app::Window::Key::kRight:
|
||||
return this->moveCursor(editor::Editor::Movement::kWordRight,
|
||||
(int)(modifiers & ModifierKey::kShift));
|
||||
return this->moveCursor(editor::Editor::Movement::kWordRight, shift);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -11,6 +11,10 @@
|
||||
|
||||
namespace skstd {
|
||||
template <typename T> struct is_bitmask_enum : std::false_type {};
|
||||
|
||||
template <typename E> SK_WHEN(skstd::is_bitmask_enum<E>::value, bool) constexpr Any(E e) {
|
||||
return static_cast<typename std::underlying_type<E>::type>(e) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename E> SK_WHEN(skstd::is_bitmask_enum<E>::value, E) constexpr operator|(E l, E r) {
|
||||
@ -31,4 +35,8 @@ template <typename E> SK_WHEN(skstd::is_bitmask_enum<E>::value, E&) constexpr op
|
||||
return l = l & r;
|
||||
}
|
||||
|
||||
template <typename E> SK_WHEN(skstd::is_bitmask_enum<E>::value, E) constexpr operator~(E e) {
|
||||
return static_cast<E>(~static_cast<typename std::underlying_type<E>::type>(e));
|
||||
}
|
||||
|
||||
#endif // SkEnumOperators_DEFINED
|
||||
|
@ -168,6 +168,7 @@ protected:
|
||||
}
|
||||
|
||||
Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, ModifierKey modi) override {
|
||||
modi &= ~ModifierKey::kFirstPress; // ignore this
|
||||
if (ModifierKey::kShift == modi) {
|
||||
return new PtClick(-1);
|
||||
}
|
||||
|
@ -18,8 +18,4 @@ namespace skstd {
|
||||
template <> struct is_bitmask_enum<ModifierKey> : std::true_type {};
|
||||
}
|
||||
|
||||
static inline bool ModifierKeyIsSet(ModifierKey m) {
|
||||
return m != ModifierKey::kNone;
|
||||
}
|
||||
|
||||
#endif // ModifierKey_DEFINED
|
||||
|
@ -381,7 +381,8 @@ bool SlideDir::onChar(SkUnichar c) {
|
||||
|
||||
bool SlideDir::onMouse(SkScalar x, SkScalar y, InputState state,
|
||||
ModifierKey modifiers) {
|
||||
if (state == InputState::kMove || ModifierKeyIsSet(modifiers))
|
||||
modifiers &= ~ModifierKey::kFirstPress;
|
||||
if (state == InputState::kMove || skstd::Any(modifiers))
|
||||
return false;
|
||||
|
||||
if (fFocusController->hasFocus()) {
|
||||
|
Loading…
Reference in New Issue
Block a user