Use mojo clipboard service for copy/paste toolbar. (#3778)
* Use mojo clipboard service for copy/paste toolbar. BUG=https://github.com/flutter/flutter/issues/1567
This commit is contained in:
parent
770f8f1d0c
commit
e4342184be
@ -18,6 +18,7 @@ export 'src/services/activity.dart';
|
||||
export 'src/services/app_messages.dart';
|
||||
export 'src/services/asset_bundle.dart';
|
||||
export 'src/services/binding.dart';
|
||||
export 'src/services/clipboard.dart';
|
||||
export 'src/services/haptic_feedback.dart';
|
||||
export 'src/services/image_cache.dart';
|
||||
export 'src/services/image_decoder.dart';
|
||||
|
@ -2,9 +2,11 @@
|
||||
// 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:math' as math;
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'flat_button.dart';
|
||||
import 'icon_button.dart';
|
||||
@ -32,8 +34,9 @@ class _TextSelectionToolbar extends StatelessWidget {
|
||||
}
|
||||
items.add(new FlatButton(
|
||||
child: new Text('PASTE'),
|
||||
onPressed: delegate.pasteBuffer != null ? _handlePaste : null)
|
||||
);
|
||||
// TODO(mpcomplete): This should probably be grayed-out if there is nothing to paste.
|
||||
onPressed: _handlePaste
|
||||
));
|
||||
if (value.selection.isCollapsed) {
|
||||
items.add(new FlatButton(child: new Text('SELECT ALL'), onPressed: _handleSelectAll));
|
||||
}
|
||||
@ -50,8 +53,7 @@ class _TextSelectionToolbar extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _handleCut() {
|
||||
InputValue value = this.value;
|
||||
delegate.pasteBuffer = value.selection.textInside(value.text);
|
||||
Clipboard.setClipboardData(new ClipboardData()..text = value.selection.textInside(value.text));
|
||||
delegate.inputValue = new InputValue(
|
||||
text: value.selection.textBefore(value.text) + value.selection.textAfter(value.text),
|
||||
selection: new TextSelection.collapsed(offset: value.selection.start)
|
||||
@ -60,7 +62,7 @@ class _TextSelectionToolbar extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _handleCopy() {
|
||||
delegate.pasteBuffer = value.selection.textInside(value.text);
|
||||
Clipboard.setClipboardData(new ClipboardData()..text = value.selection.textInside(value.text));
|
||||
delegate.inputValue = new InputValue(
|
||||
text: value.text,
|
||||
selection: new TextSelection.collapsed(offset: value.selection.end)
|
||||
@ -68,11 +70,15 @@ class _TextSelectionToolbar extends StatelessWidget {
|
||||
delegate.hideToolbar();
|
||||
}
|
||||
|
||||
void _handlePaste() {
|
||||
delegate.inputValue = new InputValue(
|
||||
text: value.selection.textBefore(value.text) + delegate.pasteBuffer + value.selection.textAfter(value.text),
|
||||
selection: new TextSelection.collapsed(offset: value.selection.start + delegate.pasteBuffer.length)
|
||||
);
|
||||
Future<Null> _handlePaste() async {
|
||||
InputValue value = this.value; // Snapshot the input before using `await`.
|
||||
ClipboardData clip = await Clipboard.getClipboardData(Clipboard.kTextPlain);
|
||||
if (clip != null) {
|
||||
delegate.inputValue = new InputValue(
|
||||
text: value.selection.textBefore(value.text) + clip.text + value.selection.textAfter(value.text),
|
||||
selection: new TextSelection.collapsed(offset: value.selection.start + clip.text.length)
|
||||
);
|
||||
}
|
||||
delegate.hideToolbar();
|
||||
}
|
||||
|
||||
|
35
packages/flutter/lib/src/services/clipboard.dart
Normal file
35
packages/flutter/lib/src/services/clipboard.dart
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2016 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 'package:sky_services/editing/editing.mojom.dart' as mojom;
|
||||
|
||||
import 'shell.dart';
|
||||
|
||||
export 'package:sky_services/editing/editing.mojom.dart' show ClipboardData;
|
||||
|
||||
mojom.ClipboardProxy _initClipboardProxy() {
|
||||
mojom.ClipboardProxy proxy = new mojom.ClipboardProxy.unbound();
|
||||
shell.connectToService('mojo:clipboard', proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
final mojom.ClipboardProxy _clipboardProxy = _initClipboardProxy();
|
||||
|
||||
/// An interface to the system's clipboard. Wraps the mojo interface.
|
||||
class Clipboard {
|
||||
/// Constants for common [getClipboardData] [format] types.
|
||||
static final String kTextPlain = 'text/plain';
|
||||
|
||||
Clipboard._();
|
||||
|
||||
static void setClipboardData(mojom.ClipboardData clip) {
|
||||
_clipboardProxy.ptr.setClipboardData(clip);
|
||||
}
|
||||
|
||||
static Future<mojom.ClipboardData> getClipboardData(String format) async {
|
||||
return (await _clipboardProxy.ptr.getClipboardData(format)).clip;
|
||||
}
|
||||
}
|
@ -42,19 +42,10 @@ abstract class TextSelectionDelegate {
|
||||
/// Sets the current text input (replaces the whole line).
|
||||
void set inputValue(InputValue value);
|
||||
|
||||
/// The copy/paste buffer. Application-wide.
|
||||
String get pasteBuffer;
|
||||
|
||||
/// Sets the copy/paste buffer.
|
||||
void set pasteBuffer(String value);
|
||||
|
||||
/// Hides the text selection toolbar.
|
||||
void hideToolbar();
|
||||
}
|
||||
|
||||
// TODO(mpcomplete): need to interact with the system clipboard.
|
||||
String _pasteBuffer;
|
||||
|
||||
/// Manages a pair of text selection handles to be shown in an Overlay
|
||||
/// containing the owning widget.
|
||||
class TextSelectionOverlay implements TextSelectionDelegate {
|
||||
@ -162,14 +153,6 @@ class TextSelectionOverlay implements TextSelectionDelegate {
|
||||
onSelectionOverlayChanged(value);
|
||||
}
|
||||
|
||||
@override
|
||||
String get pasteBuffer => _pasteBuffer;
|
||||
|
||||
@override
|
||||
void set pasteBuffer(String value) {
|
||||
_pasteBuffer = value;
|
||||
}
|
||||
|
||||
@override
|
||||
void hideToolbar() {
|
||||
hide();
|
||||
|
@ -26,9 +26,25 @@ class MockKeyboard implements mojom.Keyboard {
|
||||
void setEditingState(mojom.EditingState state) {}
|
||||
}
|
||||
|
||||
class MockClipboard implements mojom.Clipboard {
|
||||
mojom.ClipboardData _clip;
|
||||
|
||||
@override
|
||||
void setClipboardData(mojom.ClipboardData clip) {
|
||||
_clip = clip;
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic getClipboardData(String format,[Function responseFactory = null]) {
|
||||
return new mojom.ClipboardGetClipboardDataResponseParams()..clip = _clip;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
MockKeyboard mockKeyboard = new MockKeyboard();
|
||||
serviceMocker.registerMockService(mojom.Keyboard.serviceName, mockKeyboard);
|
||||
MockClipboard mockClipboard = new MockClipboard();
|
||||
serviceMocker.registerMockService(mojom.Clipboard.serviceName, mockClipboard);
|
||||
|
||||
void enterText(String testValue) {
|
||||
// Simulate entry of text through the keyboard.
|
||||
|
Loading…
x
Reference in New Issue
Block a user