diff --git a/examples/editor/editor_app.dart b/examples/editor/editor_app.dart new file mode 100644 index 00000000000..58239c96c37 --- /dev/null +++ b/examples/editor/editor_app.dart @@ -0,0 +1,12 @@ +// Copyright 2015 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 '../../framework/fn.dart'; +import 'input.dart'; + +class EditorApp extends App { + Node build() { + return new Input(); + } +} diff --git a/examples/editor/index.sky b/examples/editor/index.sky new file mode 100644 index 00000000000..d677e24b583 --- /dev/null +++ b/examples/editor/index.sky @@ -0,0 +1,10 @@ +#!mojo mojo:sky_viewer + + + + diff --git a/examples/editor/input.dart b/examples/editor/input.dart new file mode 100644 index 00000000000..8508a7ce2fa --- /dev/null +++ b/examples/editor/input.dart @@ -0,0 +1,111 @@ +// Copyright 2015 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 '../../framework/fn.dart'; +import '../../framework/shell.dart' as shell; +import 'package:sky/services/keyboard/keyboard.mojom.dart'; +import 'dart:math'; + +class Input extends Component implements KeyboardClient{ + static Style _style = new Style(''' + display: paragraph; + padding: 10px; + height: 200px; + background-color: lightblue;''' + ); + + static Style _composingStyle = new Style(''' + display: inline; + text-decoration: underline;''' + ); + + KeyboardServiceProxy _service; + KeyboardClientStub _stub; + + String _text = ""; + int _composingStart = -1; + int _composingEnd = -1; + + Input({Object key}) : super(key: key, stateful: true) { + events.listen('click', _handleClick); + _stub = new KeyboardClientStub.unbound()..impl = this; + } + + bool get _hasComposingRegion => _composingStart != -1 && _composingEnd != -1; + + void _handleClick(_) { + if (_service != null) + return; + _service = new KeyboardServiceProxy.unbound(); + shell.requestService(_service); + _service.ptr.show(_stub); + } + + void _replaceComposing(String text) { + if (!_hasComposingRegion) { + _composingStart = _text.length; + _composingEnd = _composingStart + text.length; + _text += text; + return; + } + + _text = _text.substring(0, _composingStart) + + text + _text.substring(_composingEnd); + _composingEnd = _composingStart + text.length; + } + + void _clearComposingRegion() { + _composingStart = -1; + _composingEnd = -1; + } + + void commitText(String text, int newCursorPosition) { + setState(() { + _replaceComposing(text); + _clearComposingRegion(); + }); + } + + void setComposingText(String text, int newCursorPosition) { + setState(() { + _replaceComposing(text); + }); + } + + void setComposingRegion(int start, int end) { + setState(() { + _composingStart = start; + _composingEnd = end; + }); + } + + Node build() { + List children = new List(); + + if (!_hasComposingRegion) { + children.add(new Text(_text)); + } else { + String run = _text.substring(0, _composingStart); + if (!run.isEmpty) + children.add(new Text(run)); + + run = _text.substring(_composingStart, _composingEnd); + if (!run.isEmpty) { + children.add(new Container( + style: _composingStyle, + children: [new Text(_text.substring(_composingStart, _composingEnd))] + )); + } + + run = _text.substring(_composingEnd); + if (!run.isEmpty) + children.add(new Text(_text.substring(_composingEnd))); + } + + return new Container( + style: _style, + children: children + ); + } +}