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:
Hal Canary 2019-08-07 10:59:27 -04:00 committed by Skia Commit-Bot
parent 228518f0f8
commit bcfed55a8c
5 changed files with 51 additions and 33 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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()) {