Dart Documentationdartkart.mapMouseEventStream

MouseEventStream class

MouseEventStream transforms the bare bone DOM events into a stream of higher level MouseEvents.

A MouseEventStream originates at an DOM Element which the stream is attached to.

class MouseEventStream {
 var _controler = new StreamController();
 var _subscriptions = [];

 var _lastMouseDownPos = null;
 var _lastMouseDownTimestamp = 0;
 var _mouseDown = false;
 var _isDragging = false;

 /// Creates a new stream which isn't attached to any element
 MouseEventStream();
 
 /// Creates a new stream which is attached to [source]. 
 MouseEventStream.from(Element source) {
   attach(source);
 }

 var _deferredEvent = null;

 _fireDeferred() {
   if (_deferredEvent != null) {
     var e = _deferredEvent;
     _deferredEvent = null;
     _controler.sink.add(new MouseEvent(MouseEvent.CLICK, e));
   }
 }

 void _rawMouseClick(html.MouseEvent evt) {
   if (_deferredEvent == null) {
     var ts = new DateTime.now().millisecondsSinceEpoch;
     if (ts - _lastMouseDownTimestamp > 150) {
       // a click generated at the end of a drag sequence
       //      mouse down, mouse move, ..., mouse move, mouse up, click
       // Ignore it.
       return;
     }
     _deferredEvent = evt;
     new Timer(const Duration(milliseconds: 200), () => _fireDeferred());
   } else {
     _deferredEvent = null;
     _controler.sink.add(new MouseEvent(MouseEvent.DOUBLE_CLICK,evt));
   }
 }

 void _rawMouseMove(html.MouseEvent evt){
   if (_mouseDown) {
      if (!_isDragging) {
        _controler.sink.add(new MouseEvent(MouseEvent.DRAG_START, evt));
      }
     _isDragging = true;
   }
   if (_isDragging) {
     _controler.sink.add(new MouseEvent(MouseEvent.DRAG, evt));
   } else {
     _controler.sink.add(new MouseEvent(MouseEvent.HOVER, evt));
   }
 }

 void _rawMouseDown(html.MouseEvent evt) {
   if (evt.button != 0 /* left */) return;
   evt.preventDefault();
   evt.stopPropagation();
   _mouseDown = true;
   _lastMouseDownTimestamp = new DateTime.now().millisecondsSinceEpoch;
   _lastMouseDownPos = new Point2D(evt.offset.x, evt.offset.y);
 }

 void _rawMouseUp(html.MouseEvent evt) {
   if (evt.button != 0 /* left */) return;
   evt.preventDefault();
   evt.stopPropagation();
   if (_isDragging) {
     _controler.sink.add(new MouseEvent(MouseEvent.DRAG_END, evt));
   }
   _mouseDown = false;
   _isDragging = false;
 }

 get stream => _controler.stream;

 /// Detach from source and cancel all event subsriptions
 void detach() {
   _subscriptions
     ..forEach((s) => s.cancel())
     ..clear();
 }

 /// Attach to [source] and process its raw mouse events.
 void attach(Element source) {
   _subscriptions.add(source.onClick.listen(_rawMouseClick));
   _subscriptions.add(source.onMouseDown.listen(_rawMouseDown));
   _subscriptions.add(source.onMouseUp.listen(_rawMouseUp));
   _subscriptions.add(source.onMouseMove.listen(_rawMouseMove));
 }
}

Constructors

new MouseEventStream() #

Creates a new stream which isn't attached to any element

MouseEventStream();

new MouseEventStream.from(Element source) #

Creates a new stream which is attached to source.

MouseEventStream.from(Element source) {
 attach(source);
}

Properties

final stream #

get stream => _controler.stream;

Methods

void attach(Element source) #

Attach to source and process its raw mouse events.

void attach(Element source) {
 _subscriptions.add(source.onClick.listen(_rawMouseClick));
 _subscriptions.add(source.onMouseDown.listen(_rawMouseDown));
 _subscriptions.add(source.onMouseUp.listen(_rawMouseUp));
 _subscriptions.add(source.onMouseMove.listen(_rawMouseMove));
}

void detach() #

Detach from source and cancel all event subsriptions

void detach() {
 _subscriptions
   ..forEach((s) => s.cancel())
   ..clear();
}