Skip to content

Commit

Permalink
Guess touch draw mode on the browser by default
Browse files Browse the repository at this point in the history
So that phone users don't have to dig through the preferences to enable
touch drawing. We now guess if the user wants to draw via touch by
having received a tablet event or not. Touch drawing is the default, the
first tablet event will switch it over to pan instead. The user can
still explicitly specify what they want in the preferences.
  • Loading branch information
askmeaboutlo0m committed Sep 20, 2024
1 parent 6c5fcaa commit c1ef85b
Show file tree
Hide file tree
Showing 13 changed files with 206 additions and 59 deletions.
11 changes: 5 additions & 6 deletions src/desktop/dialogs/settingsdialog/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,12 @@ void Input::initTablet(
auto *oneTouch = utils::addRadioGroup(
form, tr("One-finger input:"), true,
{
{tr("Do nothing"), 0},
{tr("Draw"), 1},
{tr("Pan canvas"), 2},
{tr("None"), int(desktop::settings::OneFingerTouchAction::Nothing)},
{tr("Draw"), int(desktop::settings::OneFingerTouchAction::Draw)},
{tr("Pan"), int(desktop::settings::OneFingerTouchAction::Pan)},
{tr("Guess"), int(desktop::settings::OneFingerTouchAction::Guess)},
});
oneTouch->button(0)->setChecked(true);
settings.bindOneFingerDraw(oneTouch->button(1));
settings.bindOneFingerScroll(oneTouch->button(2));
settings.bindOneFingerTouch(oneTouch);
settings.bindTouchGestures(oneTouch->button(1), &QWidget::setDisabled);

auto *twoTouch = new utils::EncapsulatedLayout;
Expand Down
8 changes: 4 additions & 4 deletions src/desktop/dialogs/systeminfodialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,10 @@ QString SystemInfoDialog::getSystemInfo() const
info += QStringLiteral("Global smoothing: %1\n").arg(settings.smoothing());
info += QStringLiteral("Global pressure curve: \"%1\"\n")
.arg(settings.globalPressureCurve());
info += QStringLiteral("One-finger draw: %1\n")
.arg(boolToYesNo(settings.oneFingerDraw()));
info += QStringLiteral("One-finger scroll: %1\n")
.arg(boolToYesNo(settings.oneFingerScroll()));
info +=
QStringLiteral("One-finger touch action: %1\n")
.arg(QMetaEnum::fromType<desktop::settings::OneFingerTouchAction>()
.valueToKey(settings.oneFingerTouch()));
info += QStringLiteral("Two-finger zoom: %1\n")
.arg(boolToYesNo(settings.twoFingerZoom()));
info += QStringLiteral("Two-finger rotate: %1\n")
Expand Down
7 changes: 4 additions & 3 deletions src/desktop/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,10 +827,11 @@ static StartupOptions initApp(DrawpileApp &app)
// We'll flush the flag that we checked the input here in case we crash.
settings.setAndroidStylusChecked(true);
settings.trySubmit();
// Enable fingerpainting if this device doesn't have a stylus.
// Disable finerpainting if this device is detected to have a stylus.
bool hasStylus = utils::androidHasStylusInput();
settings.setOneFingerScroll(hasStylus);
settings.setOneFingerDraw(!hasStylus);
settings.setOneFingerTouch(
int(hasStylus ? desktop::settings::OneFingerTouchAction::Draw
: desktop::settings::OneFingerTouchAction::Guess));
}

settings.bindCaptureVolumeRocker([](bool capture) {
Expand Down
3 changes: 1 addition & 2 deletions src/desktop/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2256,8 +2256,7 @@ void MainWindow::toggleTabletEventLog()
const desktop::settings::Settings &settings = dpApp().settings();
DP_event_log_write_meta("Tablet enabled: %d", settings.tabletEvents());
DP_event_log_write_meta("Tablet eraser action: %d", settings.tabletEraserAction());
DP_event_log_write_meta("One-finger draw: %d", settings.oneFingerDraw());
DP_event_log_write_meta("One-finger scroll: %d", settings.oneFingerScroll());
DP_event_log_write_meta("One-finger touch action: %d", settings.oneFingerTouch());
DP_event_log_write_meta("Two-finger rotate: %d", settings.twoFingerRotate());
DP_event_log_write_meta("Two-finger zoom: %d", settings.twoFingerZoom());
DP_event_log_write_meta("Gestures: %d", settings.touchGestures());
Expand Down
77 changes: 64 additions & 13 deletions src/desktop/scene/canvasview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ CanvasView::CanvasView(QWidget *parent)
, m_saveInProgress(false)
, m_pointertracking(false)
, m_pixelgrid(true)
, m_enableTouchScroll(true)
, m_enableTouchDraw(false)
, m_enableTouchPinch(true)
, m_enableTouchTwist(true)
, m_useGestureEvents(false)
, m_touching(false)
, m_touchRotating(false)
, m_anyTabletEventsReceived(false)
, m_oneFingerTouchAction(int(ONE_FINGER_TOUCH_DEFAULT))
, m_touchMode(TouchMode::Unknown)
, m_dpi(96)
, m_brushCursorStyle(int(view::Cursor::TriangleRight))
Expand Down Expand Up @@ -131,8 +131,8 @@ CanvasView::CanvasView(QWidget *parent)
}

settings.bindTabletEvents(this, &widgets::CanvasView::setTabletEnabled);
settings.bindOneFingerDraw(this, &widgets::CanvasView::setTouchDraw);
settings.bindOneFingerScroll(this, &widgets::CanvasView::setTouchScroll);
settings.bindOneFingerTouch(
this, &widgets::CanvasView::setOneFingerTouchAction);
settings.bindTwoFingerZoom(this, &widgets::CanvasView::setTouchPinch);
settings.bindTwoFingerRotate(this, &widgets::CanvasView::setTouchTwist);
settings.bindTouchGestures(
Expand Down Expand Up @@ -171,6 +171,21 @@ CanvasView::CanvasView(QWidget *parent)
this, &CanvasView::setShowTransformNotices);
}

void CanvasView::setOneFingerTouchAction(int oneFingerTouchAction)
{
switch(oneFingerTouchAction) {
case int(desktop::settings::OneFingerTouchAction::Nothing):
case int(desktop::settings::OneFingerTouchAction::Draw):
case int(desktop::settings::OneFingerTouchAction::Pan):
case int(desktop::settings::OneFingerTouchAction::Guess):
m_oneFingerTouchAction = oneFingerTouchAction;
break;
default:
qWarning("Unknown one finger touch action %d", oneFingerTouchAction);
break;
}
}

void CanvasView::setTouchUseGestureEvents(bool useGestureEvents)
{
if(useGestureEvents && !m_useGestureEvents) {
Expand Down Expand Up @@ -894,6 +909,42 @@ void CanvasView::clearKeys()
resetCursor();
}

bool CanvasView::isTouchDrawEnabled() const
{
switch(m_oneFingerTouchAction) {
case int(desktop::settings::OneFingerTouchAction::Draw):
return true;
case int(desktop::settings::OneFingerTouchAction::Guess):
return !m_anyTabletEventsReceived;
default:
return false;
}
}

bool CanvasView::isTouchPanEnabled() const
{
switch(m_oneFingerTouchAction) {
case int(desktop::settings::OneFingerTouchAction::Pan):
return false;
case int(desktop::settings::OneFingerTouchAction::Guess):
return m_anyTabletEventsReceived;
default:
return false;
}
}

bool CanvasView::isTouchDrawOrPanEnabled() const
{
switch(m_oneFingerTouchAction) {
case int(desktop::settings::OneFingerTouchAction::Pan):
case int(desktop::settings::OneFingerTouchAction::Draw):
case int(desktop::settings::OneFingerTouchAction::Guess):
return true;
default:
return false;
}
}

canvas::Point CanvasView::mapToCanvas(
long long timeMsec, const QPoint &point, qreal pressure, qreal xtilt,
qreal ytilt, qreal rotation) const
Expand Down Expand Up @@ -1370,7 +1421,7 @@ void CanvasView::gestureEvent(QGestureEvent *event)
[[fallthrough]];
case Qt::GestureUpdated:
case Qt::GestureFinished:
if((m_enableTouchScroll || m_enableTouchDraw) &&
if(isTouchDrawOrPanEnabled() &&
cf.testFlag(QPinchGesture::CenterPointChanged)) {
QPointF d = pinch->centerPoint() - pinch->lastCenterPoint();
horizontalScrollBar()->setValue(
Expand Down Expand Up @@ -1420,7 +1471,7 @@ void CanvasView::gestureEvent(QGestureEvent *event)
[[fallthrough]];
case Qt::GestureUpdated:
case Qt::GestureFinished:
if(!hadPinchUpdate && (m_enableTouchScroll || m_enableTouchDraw)) {
if(!hadPinchUpdate && isTouchDrawOrPanEnabled()) {
horizontalScrollBar()->setValue(
horizontalScrollBar()->value() - delta.x());
verticalScrollBar()->setValue(
Expand Down Expand Up @@ -1777,7 +1828,7 @@ void CanvasView::touchEvent(QTouchEvent *event)

m_touchDrawBuffer.clear();
m_touchRotating = false;
if(m_enableTouchDraw && pointsCount == 1 &&
if(isTouchDrawEnabled() && pointsCount == 1 &&
!compat::isTouchPad(event)) {
DP_EVENT_LOG(
"touch_draw_begin x=%f y=%f pendown=%d touching=%d type=%d "
Expand All @@ -1787,7 +1838,7 @@ void CanvasView::touchEvent(QTouchEvent *event)
qUtf8Printable(compat::touchDeviceName(event)),
qUtf8Printable(compat::debug(points)),
qulonglong(event->timestamp()));
if(m_enableTouchScroll || m_enableTouchPinch ||
if(isTouchPanEnabled() || m_enableTouchPinch ||
m_enableTouchTwist) {
// Buffer the touch first, since it might end up being the
// beginning of an action that involves multiple fingers.
Expand Down Expand Up @@ -1815,7 +1866,7 @@ void CanvasView::touchEvent(QTouchEvent *event)
}

case QEvent::TouchUpdate:
if(m_enableTouchDraw &&
if(isTouchDrawEnabled() &&
((pointsCount == 1 && m_touchMode == TouchMode::Unknown) ||
m_touchMode == TouchMode::Drawing) &&
!compat::isTouchPad(event)) {
Expand Down Expand Up @@ -1892,7 +1943,7 @@ void CanvasView::touchEvent(QTouchEvent *event)
bool havePinchOrTwist =
haveMultiTouch && (m_enableTouchPinch || m_enableTouchTwist);
bool havePan = havePinchOrTwist ||
((m_enableTouchScroll || m_enableTouchDraw) &&
(isTouchDrawOrPanEnabled() &&
(haveMultiTouch || !compat::isTouchPad(event)));
if(havePan) {
m_touching = true;
Expand Down Expand Up @@ -1960,9 +2011,9 @@ void CanvasView::touchEvent(QTouchEvent *event)

case QEvent::TouchEnd:
case QEvent::TouchCancel:
if(m_enableTouchDraw && ((m_touchMode == TouchMode::Unknown &&
!m_touchDrawBuffer.isEmpty()) ||
m_touchMode == TouchMode::Drawing)) {
if(isTouchDrawEnabled() && ((m_touchMode == TouchMode::Unknown &&
!m_touchDrawBuffer.isEmpty()) ||
m_touchMode == TouchMode::Drawing)) {
DP_EVENT_LOG(
"touch_draw_%s pendown=%d touching=%d type=%d device=%s "
"points=%s timestamp=%llu",
Expand Down
12 changes: 7 additions & 5 deletions src/desktop/scene/canvasview.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ class CanvasView final : public QGraphicsView {
}

bool isTabletEnabled() const { return m_enableTablet; }
bool isTouchScrollEnabled() const { return m_enableTouchScroll; }
bool isTouchDrawEnabled() const { return m_enableTouchDraw; }
bool isTouchDrawEnabled() const;
bool isTouchPanEnabled() const;
bool isTouchDrawOrPanEnabled() const;

canvas::Point mapToCanvas(
long long timeMsec, const QPoint &point, qreal pressure, qreal xtilt,
Expand All @@ -90,8 +91,7 @@ class CanvasView final : public QGraphicsView {
void setTabletEnabled(bool enable) { m_enableTablet = enable; }

//! Enable/disable touch gestures
void setTouchScroll(bool scroll) { m_enableTouchScroll = scroll; }
void setTouchDraw(bool draw) { m_enableTouchDraw = draw; }
void setOneFingerTouchAction(int oneFingerTouchAction);
void setTouchPinch(bool pinch) { m_enableTouchPinch = pinch; }
void setTouchTwist(bool twist) { m_enableTouchTwist = twist; }
void setTouchUseGestureEvents(bool touchUseGestureEvents);
Expand Down Expand Up @@ -270,6 +270,7 @@ private slots:

void startTabletEventTimer()
{
m_anyTabletEventsReceived = true;
if(m_tabletEventTimerDelay > 0) {
m_tabletEventTimer.setRemainingTime(m_tabletEventTimerDelay);
}
Expand Down Expand Up @@ -431,10 +432,11 @@ private slots:
bool m_pointertracking;
bool m_pixelgrid;

bool m_enableTouchScroll, m_enableTouchDraw;
bool m_enableTouchPinch, m_enableTouchTwist;
bool m_useGestureEvents;
bool m_touching, m_touchRotating;
bool m_anyTabletEventsReceived;
int m_oneFingerTouchAction;
TouchMode m_touchMode;
QVector<QPair<long long, QPointF>> m_touchDrawBuffer;
qreal m_touchStartZoom, m_touchStartRotate;
Expand Down
2 changes: 1 addition & 1 deletion src/desktop/scene/scenewrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ bool SceneWrapper::isTabletEnabled() const

bool SceneWrapper::isTouchScrollEnabled() const
{
return m_view->isTouchScrollEnabled();
return m_view->isTouchPanEnabled();
}

bool SceneWrapper::isTouchDrawEnabled() const
Expand Down
36 changes: 36 additions & 0 deletions src/desktop/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,42 @@ namespace newCanvasBackColor {
}
}

namespace oneFingerTouch {
QVariant get(const SettingMeta &meta, QSettings &settings)
{
if (findKey(settings, meta.baseKey, meta.version)) {
bool ok;
int value = any::get(meta, settings).toInt(&ok);
if(ok) {
switch(value) {
case int(OneFingerTouchAction::Nothing):
case int(OneFingerTouchAction::Draw):
case int(OneFingerTouchAction::Pan):
case int(OneFingerTouchAction::Guess):
return value;
default:
break;
}
}
return int(ONE_FINGER_TOUCH_DEFAULT);
}

std::optional<libclient::settings::FoundKey> touchDrawKey = findKey(
settings, "settings/input/touchdraw", SettingMeta::Version::V0);
if(touchDrawKey.has_value() && settings.value(touchDrawKey->key).toBool()) {
return int(OneFingerTouchAction::Draw);
}

std::optional<libclient::settings::FoundKey> touchScrollKey = findKey(
settings, "settings/input/touchscroll", SettingMeta::Version::V0);
if(touchScrollKey.has_value() && settings.value(touchScrollKey->key).toBool()) {
return int(OneFingerTouchAction::Pan);
}

return int(ONE_FINGER_TOUCH_DEFAULT);
}
}

namespace tabletDriver {
QVariant get(const SettingMeta &meta, QSettings &settings)
{
Expand Down
8 changes: 8 additions & 0 deletions src/desktop/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ enum class KineticScrollGesture : int {
};
Q_ENUM_NS(KineticScrollGesture)

enum class OneFingerTouchAction : int {
Nothing,
Pan,
Draw,
Guess,
};
Q_ENUM_NS(OneFingerTouchAction)

enum class ThemePalette : int {
System,
Light,
Expand Down
12 changes: 10 additions & 2 deletions src/desktop/settings_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@
# endif
#endif

#ifndef ONE_FINGER_TOUCH_DEFAULT
# if defined(Q_OS_ANDROID) || defined(__EMSCRIPTEN__)
# define ONE_FINGER_TOUCH_DEFAULT desktop::settings::OneFingerTouchAction::Guess
# else
# define ONE_FINGER_TOUCH_DEFAULT desktop::settings::OneFingerTouchAction::Pan
# endif
#endif

#ifndef OVERRIDE_FONT_SIZE_DEFAULT
# if defined(Q_OS_ANDROID) || defined(__EMSCRIPTEN__)
# define OVERRIDE_FONT_SIZE_DEFAULT true
Expand Down Expand Up @@ -171,8 +179,8 @@ SETTING(notifSoundLogin , NotifSoundLogin , "notifications/l
SETTING(notifSoundLogout , NotifSoundLogout , "notifications/logout" , true)
SETTING(notifSoundPrivateChat , NotifSoundPrivateChat , "notifications/privatechat" , true)
SETTING(notifSoundUnlock , NotifSoundUnlock , "notifications/unlock" , true)
SETTING(oneFingerDraw , OneFingerDraw , "settings/input/touchdraw" , false)
SETTING(oneFingerScroll , OneFingerScroll , "settings/input/touchscroll" , true)
SETTING_GETSET(oneFingerTouch , OneFingerTouch , "settings/input/onefinertouch" , int(ONE_FINGER_TOUCH_DEFAULT)
, &oneFingerTouch::get, &any::set)
SETTING(tabletPressTimerDelay , TabletPressTimerDelay , "settings/input/tabletpresstimerdelay" , 500)
SETTING(touchGestures , TouchGestures , "settings/input/touchgestures" , false)
SETTING(onionSkinsFrameCount , OnionSkinsFrameCount , "onionskins/framecount" , 8)
Expand Down
Loading

0 comments on commit c1ef85b

Please sign in to comment.