aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPardis Beikzadeh <pardis@google.com>2020-05-21 23:10:36 -0700
committerPardis Beikzadeh <pardis@google.com>2020-05-28 15:37:02 -0700
commitfc75237d13c10d4b4f438a3ef60dd54ed92a4ecb (patch)
treef0d7bcd03d781aef8885d0ec6dfc26336df2aee1
parent58158382afa4a72a1b8a2e7936c50dd42c4322a4 (diff)
downloadtests-fc75237d13c10d4b4f438a3ef60dd54ed92a4ecb.tar.gz
Refactor code to reduce duplication.
BUG: 153886988 Test: make, install and run Change-Id: I64294a3438e297fb8c6e90b078697b883dee8cb4
-rw-r--r--RotaryPlayground/src/com/android/car/rotaryplayground/DirectManipulationView.java100
-rw-r--r--RotaryPlayground/src/com/android/car/rotaryplayground/RotaryDirectManipulationWidgets.java122
2 files changed, 103 insertions, 119 deletions
diff --git a/RotaryPlayground/src/com/android/car/rotaryplayground/DirectManipulationView.java b/RotaryPlayground/src/com/android/car/rotaryplayground/DirectManipulationView.java
index 6c37556..733de87 100644
--- a/RotaryPlayground/src/com/android/car/rotaryplayground/DirectManipulationView.java
+++ b/RotaryPlayground/src/com/android/car/rotaryplayground/DirectManipulationView.java
@@ -15,17 +15,20 @@
*/
package com.android.car.rotaryplayground;
+import static java.lang.Math.min;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
import android.view.View;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import static java.lang.Math.min;
-
/**
* A {@link View} used to demonstrate direct manipulation mode.
* <p>
@@ -95,7 +98,7 @@ public class DirectManipulationView extends View {
}
/** Changes the radius of the circle by {@code dr} then redraws it. */
- void zoom(float dr) {
+ void resizeCircle(float dr) {
mDeltaRadius += dr;
invalidate();
}
@@ -113,4 +116,95 @@ public class DirectManipulationView extends View {
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
}
+
+ /**
+ * A {@link View.OnKeyListener} for handling Direct Manipulation rotary nudge behavior
+ * for a {@link DirectManipulationView}.
+ * <p>
+ * This handler expects that it is being used in Direct Manipulation mode, i.e. as a directional
+ * delegate through a {@link DirectManipulationHandler} which can invoke it at the
+ * appropriate times.
+ * <p>
+ * Moves the circle drawn in the {@link DirectManipulationView} in the relevant direction for
+ * following {@link KeyEvent}s:
+ * <ul>
+ * <li>{@link KeyEvent#KEYCODE_DPAD_UP}
+ * <li>{@link KeyEvent#KEYCODE_DPAD_DOWN}
+ * <li>{@link KeyEvent#KEYCODE_DPAD_LEFT}
+ * <li>{@link KeyEvent#KEYCODE_DPAD_RIGHT}
+ * </ul>
+ */
+ static class NudgeHandler implements View.OnKeyListener {
+
+ /** How many pixels do we want to move the {@link DirectManipulationView} per nudge. */
+ private static final float DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE = 10f;
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent keyEvent) {
+ if (keyEvent.getAction() != KeyEvent.ACTION_UP) {
+ return true;
+ }
+
+ if (v instanceof DirectManipulationView) {
+ DirectManipulationView dmv = (DirectManipulationView) v;
+ handleNudgeEvent(dmv, keyCode);
+ return true;
+ }
+
+ throw new UnsupportedOperationException("NudgeHandler shouldn't be registered "
+ + "as a listener on a view other than a DirectManipulationView.");
+ }
+
+ /** Moves the circle of the DirectManipulationView when the controller nudges. */
+ private void handleNudgeEvent(@NonNull DirectManipulationView dmv, int keyCode) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_UP:
+ dmv.move(0f, -DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE);
+ return;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ dmv.move(0f, DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE);
+ return;
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ dmv.move(-DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE, 0f);
+ return;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ dmv.move(DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE, 0f);
+ return;
+ default:
+ throw new IllegalArgumentException("Invalid keycode: " + keyCode);
+ }
+ }
+ }
+
+ /**
+ * A {@link View.OnGenericMotionListener} for handling Direct Manipulation rotation events for
+ * a {@link DirectManipulationView}. It does so by increasing or decreasing the radius of
+ * the circle drawn depending on the direction of rotation.
+ */
+ static class RotationHandler implements View.OnGenericMotionListener {
+
+ /**
+ * How many pixels do we want to change the radius of the circle in the
+ * {@link DirectManipulationView} for a rotation.
+ */
+ private static final float DIRECT_MANIPULATION_VIEW_PX_PER_ROTATION = 10f;
+
+ @Override
+ public boolean onGenericMotion(View v, MotionEvent event) {
+ if (v instanceof DirectManipulationView) {
+ handleRotateEvent(
+ (DirectManipulationView) v,
+ event.getAxisValue(MotionEvent.AXIS_SCROLL));
+ return true;
+ }
+
+ throw new UnsupportedOperationException("RotationHandler shouldn't be registered "
+ + "as a listener on a view other than a DirectManipulationView.");
+ }
+
+ /** Resizes the circle of the DirectManipulationView when the controller rotates. */
+ private void handleRotateEvent(@NonNull DirectManipulationView dmv, float scroll) {
+ dmv.resizeCircle(DIRECT_MANIPULATION_VIEW_PX_PER_ROTATION * scroll);
+ }
+ }
}
diff --git a/RotaryPlayground/src/com/android/car/rotaryplayground/RotaryDirectManipulationWidgets.java b/RotaryPlayground/src/com/android/car/rotaryplayground/RotaryDirectManipulationWidgets.java
index 79a384c..a4715c3 100644
--- a/RotaryPlayground/src/com/android/car/rotaryplayground/RotaryDirectManipulationWidgets.java
+++ b/RotaryPlayground/src/com/android/car/rotaryplayground/RotaryDirectManipulationWidgets.java
@@ -51,12 +51,6 @@ public class RotaryDirectManipulationWidgets extends Fragment {
// TODO(agathaman): refactor a common class that takes in a fragment xml id and inflates it, to
// share between this and RotaryCards.
- /** How many pixels do we want to move the {@link DirectManipulationView} for nudge. */
- private static final float DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE = 10f;
-
- /** How many pixels do we want to zoom the {@link DirectManipulationView} for a rotation. */
- private static final float DIRECT_MANIPULATION_VIEW_PX_PER_ROTATION = 10f;
-
/** Background color of a view when it's in direct manipulation mode. */
private static final int BACKGROUND_COLOR_IN_DIRECT_MANIPULATION_MODE = Color.BLUE;
@@ -71,7 +65,12 @@ public class RotaryDirectManipulationWidgets extends Fragment {
View view = inflater.inflate(R.layout.rotary_direct_manipulation, container, false);
DirectManipulationView dmv = view.findViewById(R.id.direct_manipulation_view);
- initDirectManipulationMode(dmv, /* handleNudge= */ true, /* handleRotate= */ true);
+ registerDirectManipulationHandler(dmv,
+ new DirectManipulationHandler.Builder(mDirectManipulationMode)
+ .setNudgeHandler(new DirectManipulationView.NudgeHandler())
+ .setRotationHandler(new DirectManipulationView.RotationHandler())
+ .build());
+
TimePicker spinnerTimePicker = view.findViewById(R.id.spinner_time_picker);
registerDirectManipulationHandler(spinnerTimePicker,
@@ -139,52 +138,6 @@ public class RotaryDirectManipulationWidgets extends Fragment {
super.onPause();
}
- /**
- * Initializes the given view so that it can enter/exit direct manipulation mode and interact
- * with the rotary controller directly.
- *
- * @param dmv the view to enable direct manipulation mode
- * @param handleNudge whether to handle controller nudge in direct manipulation mode
- * @param handleRotate whether to handle controller rotate in direct manipulation mode
- */
- private void initDirectManipulationMode(
- @NonNull View dmv, boolean handleNudge, boolean handleRotate) {
- dmv.setOnKeyListener((view, keyCode, keyEvent) -> {
- boolean isActionUp = keyEvent.getAction() == KeyEvent.ACTION_UP;
- switch (keyCode) {
- // Always consume KEYCODE_DPAD_CENTER and KEYCODE_BACK event.
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (!mDirectManipulationMode.isActive() && isActionUp) {
- enableDirectManipulationMode(dmv, true);
- }
- return true;
- case KeyEvent.KEYCODE_BACK:
- if (mDirectManipulationMode.isActive() && isActionUp) {
- enableDirectManipulationMode(dmv, false);
- }
- return true;
- // Consume nudge event if the view handles controller nudge in direct manipulation
- // mode.
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- return handleNudge ? handleNudgeEvent(keyEvent) : false;
- // Don't consume other key events.
- default:
- return false;
- }
- });
-
- // Consume rotate event if the view handles controller rotate in direct manipulation mode.
- if (handleRotate) {
- dmv.setOnGenericMotionListener(((view, motionEvent) -> {
- float scroll = motionEvent.getAxisValue(MotionEvent.AXIS_SCROLL);
- return handleRotateEvent(scroll);
- }));
- }
- }
-
private void enableDirectManipulationMode(@NonNull View view, boolean enable) {
view.setBackgroundColor(enable
? BACKGROUND_COLOR_IN_DIRECT_MANIPULATION_MODE
@@ -195,69 +148,6 @@ public class RotaryDirectManipulationWidgets extends Fragment {
mDirectManipulationMode.setStartingView(currentView);
}
- /** Handles controller nudge event. Returns whether the event was consumed. */
- private boolean handleNudgeEvent(KeyEvent keyEvent) {
- if (!mDirectManipulationMode.isActive()) {
- return false;
- }
- if (keyEvent.getAction() != KeyEvent.ACTION_UP) {
- return true;
- }
- int keyCode = keyEvent.getKeyCode();
- if (mDirectManipulationMode.getStartingView() instanceof DirectManipulationView) {
- DirectManipulationView dmv =
- (DirectManipulationView) mDirectManipulationMode.getStartingView();
- handleNudgeEvent(dmv, keyCode);
- return true;
- }
-
- // TODO: support other views.
-
- return true;
- }
-
- /** Handles controller rotate event. Returns whether the event was consumed. */
- private boolean handleRotateEvent(float scroll) {
- if (!mDirectManipulationMode.isActive()) {
- return false;
- }
- if (mDirectManipulationMode.getStartingView() instanceof DirectManipulationView) {
- DirectManipulationView dmv =
- (DirectManipulationView) mDirectManipulationMode.getStartingView();
- handleRotateEvent(dmv, scroll);
- return true;
- }
-
- // TODO: support other views.
-
- return true;
- }
-
- /** Moves the circle of the DirectManipulationView when the controller nudges. */
- private void handleNudgeEvent(@NonNull DirectManipulationView dmv, int keyCode) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_UP:
- dmv.move(0f, -DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE);
- return;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- dmv.move(0f, DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE);
- return;
- case KeyEvent.KEYCODE_DPAD_LEFT:
- dmv.move(-DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE, 0f);
- return;
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- dmv.move(DIRECT_MANIPULATION_VIEW_PX_PER_NUDGE, 0f);
- return;
- default:
- throw new IllegalArgumentException("Invalid keycode :" + keyCode);
- }
- }
-
- /** Zooms the circle of the DirectManipulationView when the controller rotates. */
- private void handleRotateEvent(@NonNull DirectManipulationView dmv, float scroll) {
- dmv.zoom(DIRECT_MANIPULATION_VIEW_PX_PER_ROTATION * scroll);
- }
-
/**
* Register the given {@link DirectManipulationHandler} as both the
* {@link View.OnKeyListener} and {@link View.OnGenericMotionListener} for the given