This is a helper class for CardboardOverlayView.
108 | */
109 | private class CardboardOverlayEyeView extends ViewGroup {
110 | private final ImageView imageView;
111 | private final TextView textView;
112 | private float offset;
113 |
114 | public CardboardOverlayEyeView(Context context, AttributeSet attrs) {
115 | super(context, attrs);
116 | imageView = new ImageView(context, attrs);
117 | imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
118 | imageView.setAdjustViewBounds(true); // Preserve aspect ratio.
119 | addView(imageView);
120 |
121 | textView = new TextView(context, attrs);
122 | textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14.0f);
123 | textView.setTypeface(textView.getTypeface(), Typeface.BOLD);
124 | textView.setGravity(Gravity.CENTER);
125 | textView.setShadowLayer(3.0f, 0.0f, 0.0f, Color.DKGRAY);
126 | addView(textView);
127 | }
128 |
129 | public void setColor(int color) {
130 | imageView.setColorFilter(color);
131 | textView.setTextColor(color);
132 | }
133 |
134 | public void setText(String text) {
135 | textView.setText(text);
136 | }
137 |
138 | public void setTextViewAlpha(float alpha) {
139 | textView.setAlpha(alpha);
140 | }
141 |
142 | public void setOffset(float offset) {
143 | this.offset = offset;
144 | }
145 |
146 | @Override
147 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
148 | // Width and height of this ViewGroup.
149 | final int width = right - left;
150 | final int height = bottom - top;
151 |
152 | // The size of the image, given as a fraction of the dimension as a ViewGroup.
153 | // We multiply both width and heading with this number to compute the image's bounding
154 | // box. Inside the box, the image is the horizontally and vertically centered.
155 | final float imageSize = 0.1f;
156 |
157 | // The fraction of this ViewGroup's height by which we shift the image off the
158 | // ViewGroup's center. Positive values shift downwards, negative values shift upwards.
159 | final float verticalImageOffset = -0.07f;
160 |
161 | // Vertical position of the text, specified in fractions of this ViewGroup's height.
162 | final float verticalTextPos = 0.52f;
163 |
164 | // Layout ImageView
165 | float adjustedOffset = offset;
166 | // If the half screen width is bigger than 1000 pixels, that means it's a big screen
167 | // phone and we need to use a different offset value.
168 | if (width > 1000) {
169 | adjustedOffset = 3.8f * offset;
170 | }
171 | float imageMargin = (1.0f - imageSize) / 2.0f;
172 | float leftMargin = (int) (width * (imageMargin + adjustedOffset));
173 | float topMargin = (int) (height * (imageMargin + verticalImageOffset));
174 | imageView.layout(
175 | (int) leftMargin, (int) topMargin,
176 | (int) (leftMargin + width * imageSize), (int) (topMargin + height * imageSize));
177 |
178 | // Layout TextView
179 | leftMargin = adjustedOffset * width;
180 | topMargin = height * verticalTextPos;
181 | textView.layout(
182 | (int) leftMargin, (int) topMargin,
183 | (int) (leftMargin + width), (int) (topMargin + height * (1.0f - verticalTextPos)));
184 | }
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/RajawaliVR/src/main/java/org/rajawali3d/vr/ui/GestureListener.java:
--------------------------------------------------------------------------------
1 | package org.rajawali3d.vr.ui;
2 |
3 | import android.view.MotionEvent;
4 | import android.view.View;
5 | import android.view.View.OnTouchListener;
6 |
7 | public class GestureListener implements OnTouchListener {
8 | private int mode = 0;
9 | private long touchStartTime;
10 | private float x, y;
11 | private float mTouchStartX;
12 | private float mTouchStartY;
13 | private float mClickTouchStartX, mClickTouchStartY;
14 | private float oldDist;
15 | private TOUCHEMODE mTouchMode = TOUCHEMODE.NOTHING;
16 | private TOUCHTYPE mTouchType;
17 | private OnEventGesture mOnEventGesture;
18 |
19 | public enum TOUCHEMODE {
20 | MODE_ZOOM_AND_MOVE, MODE_CTRL_SBP, NOTHING
21 | }
22 |
23 | public enum TOUCHTYPE {
24 | TYPE_GLIDE_LEFT_RIGHT, TYPE_GLIDE_UP_DOWN_IN_LEFT, TYPE_GLIDE_UP_DOWN_IN_RIGHT,
25 | }
26 |
27 | public enum GestureState {
28 | STATE_GESTURE_START, STATE_GESTURE_ING, STATE_GESTURE_END
29 | }
30 |
31 | public void setToucheMode(TOUCHEMODE mode) {
32 | mTouchMode = mode;
33 | }
34 |
35 | public void setOnEventGesture(OnEventGesture onEventGesture) {
36 | this.mOnEventGesture = onEventGesture;
37 | }
38 |
39 | @Override
40 | public boolean onTouch(View v, MotionEvent event) {
41 | int pointCount = event.getPointerCount();
42 | switch (event.getAction() & MotionEvent.ACTION_MASK) {
43 |
44 | case MotionEvent.ACTION_DOWN:
45 | mode = 1;
46 | touchStartTime = System.currentTimeMillis();
47 | mTouchStartX = event.getRawX();
48 | mTouchStartY = event.getRawY();
49 | mClickTouchStartX = mTouchStartX;
50 | mClickTouchStartY = mTouchStartY;
51 | x = event.getX();
52 | y = event.getY();
53 | break;
54 | case MotionEvent.ACTION_POINTER_UP:
55 | mode -= 1;
56 | break;
57 | case MotionEvent.ACTION_POINTER_DOWN:
58 | oldDist = spacing(event);
59 | mode += 1;
60 | break;
61 | case MotionEvent.ACTION_MOVE:
62 | if (mode >= 2) {
63 |
64 | float newDist = spacing(event);
65 | if (mTouchMode == TOUCHEMODE.MODE_ZOOM_AND_MOVE)
66 | mOnEventGesture.onZoomGesture(v, newDist, oldDist);
67 | oldDist = newDist;
68 |
69 | } else {
70 | singleMove(event, v);
71 |
72 | }
73 | break;
74 |
75 | case MotionEvent.ACTION_UP:
76 | mode = 0;
77 | if (pointCount >= 2)
78 | break;
79 |
80 | if (mTouchType != null) {
81 | switch (mTouchType) {
82 | case TYPE_GLIDE_LEFT_RIGHT:
83 |
84 | mOnEventGesture.onLeftRightGesture(v, event, x, y,
85 | GestureState.STATE_GESTURE_END);
86 | break;
87 | case TYPE_GLIDE_UP_DOWN_IN_LEFT:
88 | mOnEventGesture.onUpDownLeftGesture(v, event, x, y,
89 | GestureState.STATE_GESTURE_END);
90 | break;
91 | case TYPE_GLIDE_UP_DOWN_IN_RIGHT:
92 | mOnEventGesture.onUpDownRightGesture(v, event, x, y,
93 | GestureState.STATE_GESTURE_END);
94 | break;
95 | }
96 | mTouchType = null;
97 |
98 | } else {
99 | if (Math.abs(event.getRawX() - mClickTouchStartX) < 30
100 | && Math.abs(event.getRawY() - mClickTouchStartY) < 30
101 | && System.currentTimeMillis() - touchStartTime < 300) {
102 | mOnEventGesture.onClick(v, event);
103 | }
104 | }
105 | break;
106 | default:
107 | break;
108 | }
109 | return true;
110 | }
111 |
112 | private void singleMove(MotionEvent event, View v) {
113 | switch (mTouchMode) {
114 | case MODE_CTRL_SBP:
115 | if (mTouchType != null) {
116 | switch (mTouchType) {
117 | case TYPE_GLIDE_LEFT_RIGHT:
118 |
119 | mOnEventGesture.onLeftRightGesture(v, event, x, y,
120 | GestureState.STATE_GESTURE_ING);
121 | break;
122 | case TYPE_GLIDE_UP_DOWN_IN_LEFT:
123 | mOnEventGesture.onUpDownLeftGesture(v, event, x, y,
124 | GestureState.STATE_GESTURE_ING);
125 | break;
126 | case TYPE_GLIDE_UP_DOWN_IN_RIGHT:
127 | mOnEventGesture.onUpDownRightGesture(v, event, x, y,
128 | GestureState.STATE_GESTURE_ING);
129 | break;
130 | }
131 | } else {
132 |
133 | if (Math.abs(event.getY() - y) < 50
134 | && Math.abs(event.getX() - x) > 50) {
135 | mTouchType = TOUCHTYPE.TYPE_GLIDE_LEFT_RIGHT;
136 | mOnEventGesture.onLeftRightGesture(v, event, x, y,
137 | GestureState.STATE_GESTURE_START);
138 | x = event.getX();
139 | y = event.getY();
140 | } else if (Math.abs(event.getX() - x) < 50
141 | && Math.abs(event.getY() - y) > 50) {
142 |
143 | if (x < v.getWidth() / 2) {
144 | mTouchType = TOUCHTYPE.TYPE_GLIDE_UP_DOWN_IN_LEFT;
145 | mOnEventGesture.onUpDownLeftGesture(v, event, x, y,
146 | GestureState.STATE_GESTURE_START);
147 | } else {
148 | mTouchType = TOUCHTYPE.TYPE_GLIDE_UP_DOWN_IN_RIGHT;
149 | mOnEventGesture.onUpDownRightGesture(v, event, x, y,
150 | GestureState.STATE_GESTURE_START);
151 | }
152 | x = event.getX();
153 | y = event.getY();
154 | }
155 |
156 | }
157 | break;
158 | case MODE_ZOOM_AND_MOVE:
159 | mOnEventGesture.onMoveGesture(v, event, mTouchStartX, mTouchStartY);
160 | mTouchStartX = event.getRawX();
161 | mTouchStartY = event.getRawY();
162 | break;
163 | }
164 | }
165 |
166 | private float spacing(MotionEvent event) {
167 | float x = event.getX(0) - event.getX(1);
168 | float y = event.getY(0) - event.getY(1);
169 | return (float)Math.sqrt(x * x + y * y);
170 | }
171 |
172 | public interface OnEventGesture {
173 | public void onZoomGesture(View v, float newDist, float oldDist);
174 |
175 | public void onMoveGesture(View v, MotionEvent currentMoveEvent,
176 | float mTouchStartX, float mTouchStartY);
177 |
178 | public void onClick(View v, MotionEvent currentMoveEvent);
179 |
180 | public void onLeftRightGesture(View v, MotionEvent currentEventm,
181 | float startx, float starty, GestureState state);
182 |
183 | public void onUpDownLeftGesture(View v, MotionEvent currentEventm,
184 | float startx, float starty, GestureState state);
185 |
186 | public void onUpDownRightGesture(View v, MotionEvent currentEventm,
187 | float startx, float starty, GestureState state);
188 | }
189 | }
--------------------------------------------------------------------------------
/RajawaliVR/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |