Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(625)

Unified Diff: runtime/embedders/openglui/common/gl.dart

Issue 12390045: Added a rudimentary DOM, to assist with event dispatch. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/embedders/openglui/android/eventloop.cc ('k') | runtime/embedders/openglui/common/input_handler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/embedders/openglui/common/gl.dart
===================================================================
--- runtime/embedders/openglui/common/gl.dart (revision 19252)
+++ runtime/embedders/openglui/common/gl.dart (working copy)
@@ -3,8 +3,224 @@
// BSD-style license that can be found in the LICENSE file.
library android_extension;
+import 'dart:async';
-class CanvasElement {
+// A VERY simplified DOM.
+
+class BodyElement {
+ List _nodes;
+ get nodes => _nodes;
+ BodyElement() : _nodes = new List();
+}
+
+// The OpenGLUI "equivalent" of HtmlDocument.
+class Document {
+ BodyElement _body;
+ get body => _body;
+ Document._internal() : _body = new BodyElement();
+}
+
+Document document = new Document._internal();
+
+// Event handling. This is very kludgy for now, especially the
+// bare-bones Stream stuff!
+
+class Event {
+ final String type;
+ Event(String type) : this.type = type;
+}
+
+class KeyEvent extends Event {
+ final bool altKey;
+ final bool ctrlKey;
+ final bool shiftKey;
+ final int keyCode;
+
+ KeyEvent(String type, int keycode, bool alt, bool ctrl, bool shift)
+ : super(type),
+ keyCode = keycode,
+ altKey = alt,
+ ctrlKey = ctrl,
+ shiftKey = shift {
+ }
+}
+
+class MouseEvent extends Event {
+ final int screenX, screenY;
+ final int clientX, clientY;
+
+ MouseEvent(String type, int x, int y)
+ : super(type),
+ screenX = x,
+ screenY = y,
+ clientX = x,
+ clientY = y {
+ }
+}
+
+typedef void EventListener(Event event);
+
+Map<String,List<Function>> _listeners = new Map();
+
+class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
+ int _pauseCount = 0;
+ Object _target;
+ final String _eventType;
+ var _onData;
+
+ _EventStreamSubscription(this._target, this._eventType, this._onData) {
+ _tryResume();
+ }
+
+ void cancel() {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+
+ _unlisten();
+ // Clear out the target to indicate this is complete.
+ _target = null;
+ _onData = null;
+ }
+
+ bool get _canceled => _target == null;
+
+ void onData(void handleData(T event)) {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+ // Remove current event listener.
+ _unlisten();
+
+ _onData = handleData
+ _tryResume();
+ }
+
+ /// Has no effect.
+ void onError(void handleError(AsyncError error)) {}
+
+ /// Has no effect.
+ void onDone(void handleDone()) {}
+
+ void pause([Future resumeSignal]) {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+ ++_pauseCount;
+ _unlisten();
+
+ if (resumeSignal != null) {
+ resumeSignal.whenComplete(resume);
+ }
+ }
+
+ bool get _paused => _pauseCount > 0;
+
+ void resume() {
+ if (_canceled) {
+ throw new StateError("Subscription has been canceled.");
+ }
+ if (!_paused) {
+ throw new StateError("Subscription is not paused.");
+ }
+ --_pauseCount;
+ _tryResume();
+ }
+
+ void _tryResume() {
+ if (_onData != null && !_paused) {
+ if (!_listeners.containsKey(_eventType)) {
+ _listeners[_eventType] = new List();
+ }
+ var event_listeners = _listeners[_eventType];
+ for (var i = 0; i < event_listeners.length; i++) {
+ if (event_listeners[i] == null) {
+ event_listeners[i] = _onData;
+ return;
+ }
+ }
+ event_listeners.add(_onData);
+ }
+ }
+
+ void _unlisten() {
+ if (_onData != null) {
+ if (!_listeners.containsKey(_eventType)) {
+ var event_listeners = _listeners[_eventType];
+ for (var i = 0; i < event_listeners.length; i++) {
+ if (event_listeners[i] == _onData) {
+ event_listeners[i] = null;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+class _EventStream<T extends Event> extends Stream<T> {
+ final Object _target;
+ final String _eventType;
+
+ _EventStream(this._target, this._eventType);
+
+ // DOM events are inherently multi-subscribers.
+ Stream<T> asBroadcastStream() => this;
+ bool get isBroadcast => true;
+
+ StreamSubscription<T> listen(void onData(T event),
+ { void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError}) {
+
+ return new _EventStreamSubscription<T>(
+ this._target, this._eventType, onData);
+ }
+}
+
+class Node {
+ Stream<KeyEvent> get onKeyDown => new _EventStream(this, 'keydown');
+ Stream<KeyEvent> get onKeyUp => new _EventStream(this, 'keyup');
+ Stream<MouseEvent> get onMouseDown => new _EventStream(this, 'mousedown');
+ Stream<MouseEvent> get onMouseMove => new _EventStream(this, 'mousemove');
+ Stream<MouseEvent> get onMouseUp => new _EventStream(this, 'mouseup');
+}
+
+// TODO(gram): If we support more than one on-screen canvas, we will
+// need to filter dispatched events by the target Node.
+_dispatchEvent(String event_type, Event e) {
+ if (!_listeners.containsKey(event_type)) return;
+ var event_listeners = _listeners[event_type];
+ for (var i = 0; i < event_listeners.length; i++) {
+ if (event_listeners[i] != null) {
+ event_listeners[i](e);
+ }
+ }
+}
+
+_dispatchKeyEvent(String type, int keyCode, bool alt, bool ctrl, bool shift) =>
+ _dispatchEvent(type, new KeyEvent(type, keyCode, alt, ctrl, shift));
+
+_dispatchMouseEvent(String type, double x, double y) =>
+ _dispatchEvent(type, new MouseEvent(type, x.toInt(), y.toInt()));
+
+// These next few are called by vmglue.cc.
+onKeyDown_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat)
+ => _dispatchKeyEvent('keydown', keyCode, alt, ctrl, shift);
+
+onKeyUp_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat) =>
+ _dispatchKeyEvent('keyup', keyCode, alt, ctrl, shift);
+
+onMouseDown_(int when, double x, double y) =>
+ _dispatchMouseEvent('mousedown', x, y);
+
+onMouseMove_(int when, double x, double y) =>
+ _dispatchMouseEvent('mousemove', x, y);
+
+onMouseUp_(int when, double x, double y) =>
+ _dispatchMouseEvent('mouseup', x, y);
+
+class CanvasElement extends Node {
int _height;
int _width;
@@ -19,7 +235,8 @@
// code.
get src => "context2d://${_context2d.handle}";
- CanvasElement({int width, int height}) {
+ CanvasElement({int width, int height})
+ : super() {
_width = (width == null) ? getDeviceScreenWidth() : width;
_height = (height == null) ? getDeviceScreenHeight() : height;
}
« no previous file with comments | « runtime/embedders/openglui/android/eventloop.cc ('k') | runtime/embedders/openglui/common/input_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698