blob: c8949f80d8563d362ccb2b9df05fc06900f2dcfd [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:html';
import '../ui/elements.dart';
class DragScroll {
/// Whether the element was dragged on the previous click or touch.
bool wasDragged = false;
// This callback can optionally be set to perform additional actions on a
// vertical scroll. For example, the CPU flame chart sets this callback to
// force a canvas rebuild on vertical scroll.
VoidCallback _onVerticalScroll;
set onVerticalScroll(VoidCallback callback) => _onVerticalScroll = callback;
StreamSubscription<MouseEvent> _mouseMoveListener;
StreamSubscription<MouseEvent> _mouseUpListener;
StreamSubscription<TouchEvent> _touchMoveListener;
StreamSubscription<TouchEvent> _touchEndListener;
void enableDragScrolling(CoreElement element) {
final dragged = element.element;
_handleMouseDrags(dragged);
_handleTouchDrags(dragged);
}
void _handleMouseDrags(Element dragged) {
num lastX;
num lastY;
dragged.onMouseDown.listen((event) {
final MouseEvent m = event;
wasDragged = false;
lastX = m.client.x;
lastY = m.client.y;
m.preventDefault();
_mouseMoveListener = window.onMouseMove.listen((event) {
final MouseEvent m = event;
final num newX = m.client.x;
final num newY = m.client.y;
final num deltaX = lastX - newX;
final num deltaY = lastY - newY;
dragged.scrollLeft += deltaX.round();
dragged.scrollTop += deltaY.round();
if (_onVerticalScroll != null && deltaY.round() != 0) {
_onVerticalScroll();
}
lastX = newX;
lastY = newY;
wasDragged = true;
});
_mouseUpListener = window.onMouseUp.listen((event) {
_mouseUpListener.cancel();
_mouseMoveListener.cancel();
});
});
}
void _handleTouchDrags(Element dragged) {
num lastX;
num lastY;
dragged.onTouchStart.listen((event) {
final TouchEvent t = event;
// If there are multiple touches, always use the first.
final Touch touch = t.touches.first;
wasDragged = false;
lastX = touch.client.x;
lastY = touch.client.y;
t.preventDefault();
_touchMoveListener = window.onTouchMove.listen((event) {
final TouchEvent t = event;
// If there are multiple touches, always use the first.
final Touch touch = t.touches.first;
final num newX = touch.client.x;
final num newY = touch.client.y;
final num deltaX = lastX - newX;
final num deltaY = lastY - newY;
dragged.scrollLeft += deltaX.round();
dragged.scrollTop += deltaY.round();
if (_onVerticalScroll != null && deltaY.round() != 0) {
_onVerticalScroll();
}
lastX = newX;
lastY = newY;
wasDragged = true;
});
_touchEndListener = window.onTouchEnd.listen((event) {
final TouchEvent t = event;
if (t.touches.isEmpty) {
_touchEndListener.cancel();
_touchMoveListener.cancel();
}
});
});
}
}