提交 a01babc0 编写于 作者: A Adam Barth

Implement a basic IME-aware input element

This CL introduces a new keyboard service that understands Android IME and
starts work on a Input component that interacts with this service to provide an
editing control.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/995613002
上级 56898f39
......@@ -18,6 +18,8 @@ android_library("java") {
"//base:base_java",
"//mojo/public/java:bindings",
"//mojo/public/java:system",
"//sky/services/keyboard",
"//sky/services/keyboard:interfaces_java",
"//sky/services/sensors",
"//sky/services/sensors:interfaces_java",
"//sky/shell:java",
......
......@@ -8,7 +8,9 @@ import android.content.Context;
import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.MessagePipeHandle;
import org.chromium.mojom.keyboard.KeyboardService;
import org.chromium.mojom.sensors.SensorService;
import org.domokit.keyboard.KeyboardServiceImpl;
import org.domokit.sensors.SensorServiceImpl;
import org.domokit.sky.shell.ServiceFactory;
import org.domokit.sky.shell.ServiceRegistry;
......@@ -28,5 +30,12 @@ public class SkyDemoApplication extends SkyApplication {
new SensorServiceImpl(context, core, pipe);
}
});
ServiceRegistry.SHARED.register(KeyboardService.MANAGER.getName(), new ServiceFactory() {
@Override
public void connectToService(Context context, Core core, MessagePipeHandle pipe) {
new KeyboardServiceImpl(context, core, pipe);
}
});
}
}
// 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();
}
}
#!mojo mojo:sky_viewer
<sky>
<import src="/sky/framework/debug/shake-to-reload.sky" />
<script>
import 'editor_app.dart';
main() {
new EditorApp();
}
</script>
</sky>
// 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<Node> children = new List<Node>();
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
);
}
}
# 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("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//mojo/public/tools/bindings/mojom.gni")
android_library("keyboard") {
java_files = [
"org/domokit/keyboard/InputConnectionAdaptor.java",
"org/domokit/keyboard/KeyboardServiceImpl.java",
]
deps = [
"//mojo/public/java:bindings",
"//mojo/public/java:system",
":interfaces_java",
]
}
mojom("interfaces") {
sources = [
"keyboard.mojom",
]
}
// 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.
module keyboard;
interface KeyboardClient {
commitText(string text, int32 newCursorPosition);
setComposingText(string text, int32 newCursorPosition);
setComposingRegion(int32 start, int32 end);
};
interface KeyboardService {
Show(KeyboardClient client);
Hide();
};
// 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.
package org.domokit.keyboard;
import android.text.InputType;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import org.chromium.mojom.keyboard.KeyboardClient;
/**
* An adaptor between InputConnection and KeyboardClient.
*/
public class InputConnectionAdaptor extends BaseInputConnection {
private KeyboardClient mClient;
public InputConnectionAdaptor(View view, KeyboardClient client, EditorInfo outAttrs) {
super(view, true);
assert client != null;
mClient = client;
outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
outAttrs.initialSelStart = -1;
outAttrs.initialSelEnd = -1;
}
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
mClient.commitText(text.toString(), newCursorPosition);
return super.commitText(text, newCursorPosition);
}
@Override
public boolean setComposingText(CharSequence text, int newCursorPosition) {
mClient.setComposingText(text.toString(), newCursorPosition);
return super.setComposingText(text, newCursorPosition);
}
@Override
public boolean setComposingRegion(int start, int end) {
mClient.setComposingRegion(start, end);
return super.setComposingRegion(start, end);
}
}
// 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.
package org.domokit.keyboard;
import android.content.Context;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.MessagePipeHandle;
import org.chromium.mojo.system.MojoException;
import org.chromium.mojom.keyboard.KeyboardClient;
import org.chromium.mojom.keyboard.KeyboardService;
/**
* Android implementation of Keyboard.
*/
public class KeyboardServiceImpl implements KeyboardService {
private static View sActiveView;
private static KeyboardClient sActiveClient;
private Context mContext;
public KeyboardServiceImpl(Context context, Core core, MessagePipeHandle pipe) {
mContext = context;
KeyboardService.MANAGER.bind(this, pipe);
}
public static void setActiveView(View view) {
sActiveView = view;
}
public static InputConnection createInputConnection(EditorInfo outAttrs) {
if (sActiveClient == null)
return null;
return new InputConnectionAdaptor(sActiveView, sActiveClient, outAttrs);
}
@Override
public void close() {}
@Override
public void onConnectionError(MojoException e) {}
@Override
public void show(KeyboardClient client) {
sActiveClient = client;
InputMethodManager imm =
(InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.restartInput(sActiveView);
imm.showSoftInput(sActiveView, InputMethodManager.SHOW_IMPLICIT);
}
public void hide() {
InputMethodManager imm =
(InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(sActiveView.getApplicationWindowToken(), 0);
}
}
......@@ -89,6 +89,7 @@ android_library("java") {
"//mojo/public/java:bindings",
"//mojo/public/java:system",
"//mojo/services/network/public/interfaces:interfaces_java",
"//sky/services/keyboard",
"//sky/services/oknet",
"//sky/services/viewport:viewport_java",
]
......
......@@ -10,6 +10,8 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import org.chromium.base.JNINamespace;
import org.chromium.mojo.bindings.InterfaceRequest;
......@@ -21,6 +23,7 @@ import org.chromium.mojom.sky.InputEvent;
import org.chromium.mojom.sky.PointerData;
import org.chromium.mojom.sky.PointerKind;
import org.chromium.mojom.sky.ViewportObserver;
import org.domokit.keyboard.KeyboardServiceImpl;
/**
* A view containing Sky
......@@ -68,6 +71,7 @@ public class PlatformView extends SurfaceView
getHolder().addCallback(mSurfaceCallback);
mGestureProvider = new GestureProvider(context, this);
KeyboardServiceImpl.setActiveView(this);
}
@Override
......@@ -86,6 +90,16 @@ public class PlatformView extends SurfaceView
}
}
@Override
public boolean onCheckIsTextEditor() {
return true;
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
return KeyboardServiceImpl.createInputConnection(outAttrs);
}
private int getTypeForAction(int maskedAction) {
// Primary pointer:
if (maskedAction == MotionEvent.ACTION_DOWN)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册