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>
diff --git a/experimental/editor/editor_application.cpp b/experimental/editor/editor_application.cpp
index 0592560..7949851 100644
--- a/experimental/editor/editor_application.cpp
+++ b/experimental/editor/editor_application.cpp
@@ -148,31 +148,33 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
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;
}
diff --git a/include/private/SkBitmaskEnum.h b/include/private/SkBitmaskEnum.h
index 0f7aa15..859a2de 100644
--- a/include/private/SkBitmaskEnum.h
+++ b/include/private/SkBitmaskEnum.h
@@ -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 @@
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
diff --git a/samplecode/PerlinPatch.cpp b/samplecode/PerlinPatch.cpp
index 5736e9e..1e036d7 100644
--- a/samplecode/PerlinPatch.cpp
+++ b/samplecode/PerlinPatch.cpp
@@ -168,6 +168,7 @@
}
Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, ModifierKey modi) override {
+ modi &= ~ModifierKey::kFirstPress; // ignore this
if (ModifierKey::kShift == modi) {
return new PtClick(-1);
}
diff --git a/tools/ModifierKey.h b/tools/ModifierKey.h
index 5f4d25d..8ebfb76 100644
--- a/tools/ModifierKey.h
+++ b/tools/ModifierKey.h
@@ -18,8 +18,4 @@
template <> struct is_bitmask_enum<ModifierKey> : std::true_type {};
}
-static inline bool ModifierKeyIsSet(ModifierKey m) {
- return m != ModifierKey::kNone;
-}
-
#endif // ModifierKey_DEFINED
diff --git a/tools/viewer/SlideDir.cpp b/tools/viewer/SlideDir.cpp
index f4c1d6b..c4ac3e4 100644
--- a/tools/viewer/SlideDir.cpp
+++ b/tools/viewer/SlideDir.cpp
@@ -381,7 +381,8 @@
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()) {