提交 2419fcf8 编写于 作者: A Adam Barth

Add haptic and aural feedback service

And use the service in mine_digger to notify the user when they flag a bomb.
上级 f338ec97
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:sky' as sky; import 'dart:sky' as sky;
import 'dart:math'; import 'dart:math';
import 'package:sky/mojo/activity.dart' as activity;
import 'package:sky/painting/text_style.dart'; import 'package:sky/painting/text_style.dart';
import 'package:sky/rendering/flex.dart'; import 'package:sky/rendering/flex.dart';
import 'package:sky/theme/colors.dart' as colors; import 'package:sky/theme/colors.dart' as colors;
...@@ -83,33 +84,13 @@ class MineDiggerApp extends App { ...@@ -83,33 +84,13 @@ class MineDiggerApp extends App {
assert(false); assert(false);
} }
Stopwatch longPressStopwatch;
PointerEventListener _pointerDownHandlerFor(int posX, int posY) { PointerEventListener _pointerDownHandlerFor(int posX, int posY) {
return (sky.PointerEvent event) { return (sky.PointerEvent event) {
if (event.buttons == 1) { if (event.buttons == 1) {
probe(posX, posY); probe(posX, posY);
} else if (event.buttons == 2) { } else if (event.buttons == 2) {
flag(posX, posY); flag(posX, posY);
} else {
// Touch event.
longPressStopwatch = new Stopwatch()..start();
}
};
}
PointerEventListener _pointerUpHandlerFor(int posX, int posY) {
return (sky.PointerEvent event) {
if (longPressStopwatch == null)
return;
// Pointer down was a touch event.
if (longPressStopwatch.elapsedMilliseconds < 250) {
probe(posX, posY);
} else {
// Long press flags.
flag(posX, posY);
} }
longPressStopwatch = null;
}; };
} }
...@@ -128,7 +109,13 @@ class MineDiggerApp extends App { ...@@ -128,7 +109,13 @@ class MineDiggerApp extends App {
if (state == CellState.covered) { if (state == CellState.covered) {
row.add(new Listener( row.add(new Listener(
onPointerDown: _pointerDownHandlerFor(ix, iy), onPointerDown: _pointerDownHandlerFor(ix, iy),
onPointerUp: _pointerUpHandlerFor(ix, iy), onGestureTap: (_) {
probe(ix, iy);
},
onGestureLongPress: (_) {
activity.userFeedback.performHapticFeedback(activity.HapticFeedbackType_LONG_PRESS);
flag(ix, iy);
},
child: new CoveredMineNode( child: new CoveredMineNode(
flagged: false, flagged: false,
posX: ix, posX: ix,
......
...@@ -8,7 +8,7 @@ import 'dart:async'; ...@@ -8,7 +8,7 @@ import 'dart:async';
import 'package:sky/mojo/shell.dart' as shell; import 'package:sky/mojo/shell.dart' as shell;
import 'package:sky_services/activity/activity.mojom.dart'; import 'package:sky_services/activity/activity.mojom.dart';
export 'package:sky_services/activity/activity.mojom.dart' show Intent, ComponentName, StringExtra, SystemUIVisibility_STANDARD, SystemUIVisibility_FULLSCREEN, SystemUIVisibility_IMMERSIVE; export 'package:sky_services/activity/activity.mojom.dart';
/// Dart wrapper around Activity mojo service available in Sky on Android. /// Dart wrapper around Activity mojo service available in Sky on Android.
/// ///
...@@ -27,6 +27,15 @@ ActivityProxy _initActivity() { ...@@ -27,6 +27,15 @@ ActivityProxy _initActivity() {
final ActivityProxy _activity = _initActivity(); final ActivityProxy _activity = _initActivity();
UserFeedbackProxy _initUserFeedbackProxy() {
UserFeedbackProxy proxy = new UserFeedbackProxy.unbound();
_activity.ptr.getUserFeedback(proxy);
return proxy;
}
final UserFeedbackProxy _userFeedbackProxy = _initUserFeedbackProxy();
final UserFeedback userFeedback = _userFeedbackProxy.ptr;
Color _cachedPrimaryColor; Color _cachedPrimaryColor;
String _cachedLabel; String _cachedLabel;
......
...@@ -27,7 +27,10 @@ if (is_android) { ...@@ -27,7 +27,10 @@ if (is_android) {
import("//build/config/android/rules.gni") import("//build/config/android/rules.gni")
android_library("activity_lib") { android_library("activity_lib") {
java_files = [ "src/org/domokit/activity/ActivityImpl.java" ] java_files = [
"src/org/domokit/activity/ActivityImpl.java",
"src/org/domokit/activity/UserFeedbackImpl.java",
]
deps = [ deps = [
"//base:base_java", "//base:base_java",
......
...@@ -39,6 +39,8 @@ enum SystemUIVisibility { ...@@ -39,6 +39,8 @@ enum SystemUIVisibility {
// of services that only work on specific platforms? We need to // of services that only work on specific platforms? We need to
// figure out how to rationalize this interface across platforms. // figure out how to rationalize this interface across platforms.
interface Activity { interface Activity {
GetUserFeedback(UserFeedback& user_feedback);
StartActivity(Intent intent); StartActivity(Intent intent);
FinishCurrentActivity(); FinishCurrentActivity();
SetTaskDescription(TaskDescription description); SetTaskDescription(TaskDescription description);
...@@ -53,3 +55,23 @@ interface Activity { ...@@ -53,3 +55,23 @@ interface Activity {
// Where to store short-term files. // Where to store short-term files.
GetCacheDir() => (string path); GetCacheDir() => (string path);
}; };
enum HapticFeedbackType {
LONG_PRESS,
VIRTUAL_KEY,
KEYBOARD_TAP,
CLOCK_TICK,
};
enum AuralFeedbackType {
CLICK,
NAVIGATION_LEFT,
NAVIGATION_UP,
NAVIGATION_RIGHT,
NAVIGATION_DOWN,
};
interface UserFeedback {
PerformHapticFeedback(HapticFeedbackType type);
PerformAuralFeedback(AuralFeedbackType type);
};
...@@ -10,6 +10,7 @@ import android.os.Build; ...@@ -10,6 +10,7 @@ import android.os.Build;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import org.chromium.mojo.bindings.InterfaceRequest;
import org.chromium.mojo.system.MojoException; import org.chromium.mojo.system.MojoException;
import org.chromium.mojom.activity.Activity; import org.chromium.mojom.activity.Activity;
import org.chromium.mojom.activity.ComponentName; import org.chromium.mojom.activity.ComponentName;
...@@ -17,6 +18,7 @@ import org.chromium.mojom.activity.Intent; ...@@ -17,6 +18,7 @@ import org.chromium.mojom.activity.Intent;
import org.chromium.mojom.activity.StringExtra; import org.chromium.mojom.activity.StringExtra;
import org.chromium.mojom.activity.SystemUiVisibility; import org.chromium.mojom.activity.SystemUiVisibility;
import org.chromium.mojom.activity.TaskDescription; import org.chromium.mojom.activity.TaskDescription;
import org.chromium.mojom.activity.UserFeedback;
/** /**
* Android implementation of Activity. * Android implementation of Activity.
...@@ -38,6 +40,12 @@ public class ActivityImpl implements Activity { ...@@ -38,6 +40,12 @@ public class ActivityImpl implements Activity {
@Override @Override
public void onConnectionError(MojoException e) {} public void onConnectionError(MojoException e) {}
@Override
public void getUserFeedback(InterfaceRequest<UserFeedback> request) {
View view = sCurrentActivity.getWindow().getDecorView();
UserFeedback.MANAGER.bind(new UserFeedbackImpl(view), request);
}
@Override @Override
public void startActivity(Intent intent) { public void startActivity(Intent intent) {
if (sCurrentActivity == null) { if (sCurrentActivity == null) {
......
// 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.activity;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.SoundEffectConstants;
import android.view.View;
import org.chromium.mojo.system.MojoException;
import org.chromium.mojom.activity.AuralFeedbackType;
import org.chromium.mojom.activity.HapticFeedbackType;
import org.chromium.mojom.activity.UserFeedback;
/**
* Android implementation of UserFeedback.
*/
public class UserFeedbackImpl implements UserFeedback {
private static final String TAG = "UserFeedbackImpl";
private View mView;
public UserFeedbackImpl(View view) {
mView = view;
}
@Override
public void close() {}
@Override
public void onConnectionError(MojoException e) {}
@Override
public void performHapticFeedback(int type) {
int androidType = 0;
switch (type) {
case HapticFeedbackType.LONG_PRESS:
androidType = HapticFeedbackConstants.LONG_PRESS;
break;
case HapticFeedbackType.VIRTUAL_KEY:
androidType = HapticFeedbackConstants.VIRTUAL_KEY;
break;
case HapticFeedbackType.KEYBOARD_TAP:
androidType = HapticFeedbackConstants.KEYBOARD_TAP;
break;
case HapticFeedbackType.CLOCK_TICK:
androidType = HapticFeedbackConstants.CLOCK_TICK;
break;
default:
Log.e(TAG, "Unknown HapticFeedbackType " + type);
return;
}
mView.performHapticFeedback(androidType, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
@Override
public void performAuralFeedback(int type) {
int androidType = 0;
switch (type) {
case AuralFeedbackType.CLICK:
androidType = SoundEffectConstants.CLICK;
break;
case AuralFeedbackType.NAVIGATION_LEFT:
androidType = SoundEffectConstants.NAVIGATION_LEFT;
break;
case AuralFeedbackType.NAVIGATION_UP:
androidType = SoundEffectConstants.NAVIGATION_UP;
break;
case AuralFeedbackType.NAVIGATION_RIGHT:
androidType = SoundEffectConstants.NAVIGATION_RIGHT;
break;
case AuralFeedbackType.NAVIGATION_DOWN:
androidType = SoundEffectConstants.NAVIGATION_DOWN;
break;
default:
Log.e(TAG, "Unknown AuralFeedbackType " + type);
return;
}
mView.playSoundEffect(androidType);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册