mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 02:53:05 +00:00
improve virtual controller:
* add digital 8-Way pad * add on screen element size and position configuration * begin with cleanup
This commit is contained in:
parent
4c533fedfd
commit
f23bb9fac1
12
app/app.iml
12
app/app.iml
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="limelight-android" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="moonlight-new" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
@ -85,24 +85,18 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/nonRootDebug" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
|
@ -76,18 +76,7 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.limelight.AppView" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".binding.input.virtual_controller.VirtualControllerConfiguration"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/StreamTheme"
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".binding.input.virtual_controller.VirtualControllerSettings"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@android:style/Theme.Holo.Dialog"
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection" >
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".discovery.DiscoveryService"
|
||||
android:label="mDNS PC Auto-Discovery Service" />
|
||||
|
@ -287,9 +287,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
evdevHandler.start();
|
||||
}
|
||||
|
||||
if (prefConfig.virtualController_enable)
|
||||
{
|
||||
virtualController = new VirtualController(conn, (FrameLayout) findViewById(R.id.surfaceView).getParent(), getApplicationContext());
|
||||
if (prefConfig.virtualController_enable) {
|
||||
// create virtual onscreen controller
|
||||
virtualController = new VirtualController(conn,
|
||||
(FrameLayout)findViewById(R.id.surfaceView).getParent(),
|
||||
this);
|
||||
}
|
||||
|
||||
if (prefConfig.usbDriver) {
|
||||
@ -315,6 +317,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
|
||||
// Apply the size change
|
||||
sv.setLayoutParams(lp);
|
||||
|
||||
// refresh virtual controller layout
|
||||
if (virtualController != null) {
|
||||
virtualController.refreshLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDataConnection()
|
||||
|
@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
@ -10,88 +14,199 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Karim Mreisi on 30.11.2014.
|
||||
* This is a analog stick on screen element. It is used to get 2-Axis user input.
|
||||
*/
|
||||
public class AnalogStick extends VirtualControllerElement
|
||||
{
|
||||
float radius_complete = 0;
|
||||
float radius_minimum = 0;
|
||||
float radius_dead_zone = 0;
|
||||
float radius_analog_stick = 0;
|
||||
public class AnalogStick extends VirtualControllerElement {
|
||||
|
||||
float position_pressed_x = 0;
|
||||
float position_pressed_y = 0;
|
||||
/** outer radius size in percent of the ui element */
|
||||
public static final int SIZE_RADIUS_COMPLETE = 90;
|
||||
/** analog stick size in percent of the ui element */
|
||||
public static final int SIZE_RADIUS_ANALOG_STICK = 90;
|
||||
/** dead zone size in percent of the ui element */
|
||||
public static final int SIZE_RADIUS_DEADZONE = 90;
|
||||
/** time frame for a double click */
|
||||
public final static long timeoutDoubleClick = 250;
|
||||
|
||||
float position_moved_x = 0;
|
||||
float position_moved_y = 0;
|
||||
/**
|
||||
* Listener interface to update registered observers.
|
||||
*/
|
||||
public interface AnalogStickListener {
|
||||
|
||||
float position_stick_x = 0;
|
||||
float position_stick_y = 0;
|
||||
/**
|
||||
* onMovement event will be fired on real analog stick movement (outside of the deadzone).
|
||||
* @param x horizontal position, value from -1.0 ... 0 .. 1.0
|
||||
* @param y vertical position, value from -1.0 ... 0 .. 1.0
|
||||
*/
|
||||
void onMovement(float x, float y);
|
||||
|
||||
Paint paint = new Paint();
|
||||
/**
|
||||
* onClick event will be fired on click on the analog stick
|
||||
*/
|
||||
void onClick();
|
||||
|
||||
/**
|
||||
* onDoubleClick event will be fired on a double click in a short time frame on the analog
|
||||
* stick.
|
||||
*/
|
||||
void onDoubleClick();
|
||||
|
||||
/**
|
||||
* onRevoke event will be fired on unpress of the analog stick.
|
||||
*/
|
||||
void onRevoke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Movement states of the analog sick.
|
||||
*/
|
||||
private enum STICK_STATE {
|
||||
NO_MOVEMENT,
|
||||
MOVED_IN_DEAD_ZONE,
|
||||
MOVED_ACTIVE
|
||||
}
|
||||
|
||||
/**
|
||||
* Click type states.
|
||||
*/
|
||||
private enum CLICK_STATE {
|
||||
SINGLE,
|
||||
DOUBLE
|
||||
}
|
||||
|
||||
/** configuration if the analog stick should be displayed as circle or square*/
|
||||
private boolean circle_stick = true; // TODO: implement square sick for simulations
|
||||
|
||||
/** outer radius, this size will be automatically updated on resize */
|
||||
private float radius_complete = 0;
|
||||
/** analog stick radius, this size will be automatically updated on resize */
|
||||
private float radius_analog_stick = 0;
|
||||
/** dead zone radius, this size will be automatically updated on resize */
|
||||
private float radius_dead_zone = 0;
|
||||
|
||||
/** horizontal position in relation to the center of the element */
|
||||
private float relative_x = 0;
|
||||
/** vertical position in relation to the center of the element */
|
||||
private float relative_y = 0;
|
||||
|
||||
|
||||
_STICK_STATE stick_state = _STICK_STATE.NO_MOVEMENT;
|
||||
_CLICK_STATE click_state = _CLICK_STATE.SINGLE;
|
||||
private double movement_radius = 0;
|
||||
private double movement_angle = 0;
|
||||
|
||||
List<AnalogStickListener> listeners = new ArrayList<>();
|
||||
OnTouchListener onTouchListener = null;
|
||||
private long timeoutDoubleClick = 250;
|
||||
private float position_stick_x = 0;
|
||||
private float position_stick_y = 0;
|
||||
|
||||
private Paint paint = new Paint();
|
||||
|
||||
private STICK_STATE stick_state = STICK_STATE.NO_MOVEMENT;
|
||||
private CLICK_STATE click_state = CLICK_STATE.SINGLE;
|
||||
|
||||
private List<AnalogStickListener> listeners = new ArrayList<>();
|
||||
private long timeLastClick = 0;
|
||||
|
||||
public AnalogStick(Context context)
|
||||
{
|
||||
super(context);
|
||||
private static double getMovementRadius(float x, float y) {
|
||||
// corner cases
|
||||
if (x == 0) {
|
||||
return y > 0 ? y : -y;
|
||||
}
|
||||
if (y == 0) {
|
||||
return x > 0 ? x : -x;
|
||||
}
|
||||
// return hypotenuse (pythagoras)
|
||||
return Math.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
private static double getAngle(float way_x, float way_y) {
|
||||
double angle = 0;
|
||||
// prevent divisions by zero for corner cases
|
||||
if (way_x == 0) {
|
||||
return way_y < 0 ? Math.PI : 0;
|
||||
} else if (way_y == 0) {
|
||||
if (way_x > 0) {
|
||||
return Math.PI * 3 / 2;
|
||||
} else if (way_x < 0) {
|
||||
return Math.PI * 1 / 2;
|
||||
}
|
||||
}
|
||||
// return correct calculated angle for each quadrant
|
||||
if (way_x > 0) {
|
||||
if (way_y < 0) {
|
||||
// first quadrant
|
||||
return 3 * Math.PI / 2 + Math.atan((double) (-way_y / way_x));
|
||||
} else {
|
||||
// second quadrant
|
||||
return Math.PI + Math.atan((double) (way_x / way_y));
|
||||
}
|
||||
} else {
|
||||
if (way_y > 0) {
|
||||
// third quadrant
|
||||
return Math.PI / 2 + Math.atan((double) (way_y / -way_x));
|
||||
} else {
|
||||
// fourth quadrant
|
||||
return 0 + Math.atan((double) (-way_x / -way_y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AnalogStick(VirtualController controller, Context context) {
|
||||
super(controller, context);
|
||||
// reset stick position
|
||||
position_stick_x = getWidth() / 2;
|
||||
position_stick_y = getHeight() / 2;
|
||||
}
|
||||
|
||||
public void addAnalogStickListener(AnalogStickListener listener)
|
||||
{
|
||||
listeners.add(listener);
|
||||
public void addAnalogStickListener(AnalogStickListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void setOnTouchListener(OnTouchListener listener)
|
||||
{
|
||||
onTouchListener = listener;
|
||||
}
|
||||
private void notifyOnMovement(float x, float y) {
|
||||
_DBG("movement x: " + x + " movement y: " + y);
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners) {
|
||||
listener.onMovement(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColors(int normalColor, int pressedColor)
|
||||
{
|
||||
this.normalColor = normalColor;
|
||||
this.pressedColor = pressedColor;
|
||||
}
|
||||
private void notifyOnClick() {
|
||||
_DBG("click");
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners) {
|
||||
listener.onClick();
|
||||
}
|
||||
}
|
||||
|
||||
private double getMovementRadius(float x, float y)
|
||||
{
|
||||
if (x == 0)
|
||||
{
|
||||
return y > 0 ? y : -y;
|
||||
}
|
||||
private void notifyOnDoubleClick() {
|
||||
_DBG("double click");
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners) {
|
||||
listener.onDoubleClick();
|
||||
}
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
return x > 0 ? x : -x;
|
||||
}
|
||||
private void notifyOnRevoke() {
|
||||
_DBG("revoke");
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners) {
|
||||
listener.onRevoke();
|
||||
}
|
||||
}
|
||||
|
||||
return Math.sqrt(x * x + y * y);
|
||||
}
|
||||
public void setColors(int normalColor, int pressedColor) {
|
||||
this.normalColor = normalColor;
|
||||
this.pressedColor = pressedColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh)
|
||||
{
|
||||
radius_complete = getPercent(getCorrectWidth() / 2, 90);
|
||||
radius_minimum = getPercent(getCorrectWidth() / 2, 30);
|
||||
radius_dead_zone = getPercent(getCorrectWidth() / 2, 10);
|
||||
radius_analog_stick = getPercent(getCorrectWidth() / 2, 20);
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
// calculate new radius sizes depending
|
||||
radius_complete = getPercent(getCorrectWidth() / 2, 90);
|
||||
radius_dead_zone = getPercent(getCorrectWidth() / 2, 30);
|
||||
radius_analog_stick = getPercent(getCorrectWidth() / 2, 20);
|
||||
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas)
|
||||
{
|
||||
protected void onElementDraw(Canvas canvas) {
|
||||
// set transparent background
|
||||
canvas.drawColor(Color.TRANSPARENT);
|
||||
|
||||
@ -99,293 +214,126 @@ public class AnalogStick extends VirtualControllerElement
|
||||
paint.setStrokeWidth(getPercent(getCorrectWidth() / 2, 2));
|
||||
|
||||
// draw outer circle
|
||||
if (!isPressed() || click_state == _CLICK_STATE.SINGLE)
|
||||
{
|
||||
if (!isPressed() || click_state == CLICK_STATE.SINGLE) {
|
||||
paint.setColor(normalColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
paint.setColor(pressedColor);
|
||||
}
|
||||
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_complete, paint);
|
||||
|
||||
paint.setColor(normalColor);
|
||||
// draw minimum
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_minimum, paint);
|
||||
// draw dead zone
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_dead_zone, paint);
|
||||
|
||||
// draw stick depending on state (no movement, moved, active(out of dead zone))
|
||||
switch (stick_state)
|
||||
{
|
||||
case NO_MOVEMENT:
|
||||
{
|
||||
// draw stick depending on state
|
||||
switch (stick_state) {
|
||||
case NO_MOVEMENT: {
|
||||
paint.setColor(normalColor);
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_analog_stick, paint);
|
||||
|
||||
break;
|
||||
}
|
||||
case MOVED_IN_DEAD_ZONE:
|
||||
{
|
||||
case MOVED_IN_DEAD_ZONE: {
|
||||
paint.setColor(normalColor);
|
||||
canvas.drawCircle(position_stick_x, position_stick_y, radius_analog_stick, paint);
|
||||
|
||||
break;
|
||||
}
|
||||
case MOVED_ACTIVE:
|
||||
{
|
||||
case MOVED_ACTIVE: {
|
||||
paint.setColor(pressedColor);
|
||||
canvas.drawCircle(position_stick_x, position_stick_y, radius_analog_stick, paint);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
private double getAngle(float way_x, float way_y)
|
||||
{
|
||||
double angle = 0;
|
||||
private void updatePosition() {
|
||||
// get 100% way
|
||||
float complete = (radius_complete - radius_analog_stick - radius_dead_zone);
|
||||
|
||||
// prevent divisions by zero
|
||||
if (way_x == 0)
|
||||
{
|
||||
if (way_y > 0)
|
||||
{
|
||||
angle = 0;
|
||||
}
|
||||
else if (way_y < 0)
|
||||
{
|
||||
angle = Math.PI;
|
||||
}
|
||||
// calculate relative way
|
||||
float correlated_y = (float) (Math.sin(Math.PI / 2 - movement_angle) * (movement_radius));
|
||||
float correlated_x = (float) (Math.cos(Math.PI / 2 - movement_angle) * (movement_radius));
|
||||
|
||||
// update positions
|
||||
position_stick_x = getWidth() / 2 - correlated_x;
|
||||
position_stick_y = getHeight() / 2 - correlated_y;
|
||||
|
||||
// set active depending on dead zone
|
||||
stick_state = movement_radius > radius_dead_zone ?
|
||||
STICK_STATE.MOVED_ACTIVE : STICK_STATE.MOVED_IN_DEAD_ZONE;
|
||||
|
||||
// trigger move event if state active
|
||||
if (stick_state == STICK_STATE.MOVED_ACTIVE) {
|
||||
notifyOnMovement(-(1 / complete) *
|
||||
(correlated_x - (correlated_x > 0 ? radius_dead_zone : -radius_dead_zone)), (1 / complete) *
|
||||
(correlated_y - (correlated_y > 0 ? radius_dead_zone : -radius_dead_zone)));
|
||||
}
|
||||
else if (way_y == 0)
|
||||
{
|
||||
if (way_x > 0)
|
||||
{
|
||||
angle = Math.PI * 3 / 2;
|
||||
}
|
||||
else if (way_x < 0)
|
||||
{
|
||||
angle = Math.PI * 1 / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (way_x > 0)
|
||||
{
|
||||
if (way_y < 0)
|
||||
{ // first quadrant
|
||||
angle =
|
||||
3 * Math.PI / 2 + Math.atan((double) (-way_y / way_x));
|
||||
}
|
||||
else
|
||||
{ // second quadrant
|
||||
angle = Math.PI + Math.atan((double) (way_x / way_y));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (way_y > 0)
|
||||
{ // third quadrant
|
||||
angle = Math.PI / 2 + Math.atan((double) (way_y / -way_x));
|
||||
}
|
||||
else
|
||||
{ // fourth quadrant
|
||||
angle = 0 + Math.atan((double) (-way_x / -way_y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_DBG("angle: " + angle + " way y: " + way_y + " way x: " + way_x);
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
private void moveActionCallback(float x, float y)
|
||||
{
|
||||
_DBG("movement x: " + x + " movement y: " + y);
|
||||
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners)
|
||||
{
|
||||
listener.onMovement(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
private void clickActionCallback()
|
||||
{
|
||||
_DBG("click");
|
||||
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners)
|
||||
{
|
||||
listener.onClick();
|
||||
}
|
||||
}
|
||||
|
||||
private void doubleClickActionCallback()
|
||||
{
|
||||
_DBG("double click");
|
||||
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners)
|
||||
{
|
||||
listener.onDoubleClick();
|
||||
}
|
||||
}
|
||||
|
||||
private void revokeActionCallback()
|
||||
{
|
||||
_DBG("revoke");
|
||||
|
||||
// notify listeners
|
||||
for (AnalogStickListener listener : listeners)
|
||||
{
|
||||
listener.onRevoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePosition()
|
||||
{
|
||||
// get real way for each axis
|
||||
float way_center_x = -(getWidth() / 2 - position_moved_x);
|
||||
float way_center_y = -(getHeight() / 2 - position_moved_y);
|
||||
|
||||
// get radius and angel of movement from center
|
||||
double movement_radius = getMovementRadius(way_center_x, way_center_y);
|
||||
double movement_angle = getAngle(way_center_x, way_center_y);
|
||||
|
||||
// get dead zone way for each axis
|
||||
float way_pressed_x = position_pressed_x - position_moved_x;
|
||||
float way_pressed_y = position_pressed_y - position_moved_y;
|
||||
|
||||
// get radius and angel from pressed position
|
||||
double movement_dead_zone_radius = getMovementRadius(way_pressed_x, way_pressed_y);
|
||||
|
||||
// chop radius if out of outer circle
|
||||
if (movement_radius > (radius_complete - radius_analog_stick))
|
||||
{
|
||||
movement_radius = radius_complete - radius_analog_stick;
|
||||
}
|
||||
|
||||
// calculate new positions
|
||||
float correlated_y =
|
||||
(float) (Math.sin(Math.PI / 2 - movement_angle) * (movement_radius));
|
||||
float correlated_x =
|
||||
(float) (Math.cos(Math.PI / 2 - movement_angle) * (movement_radius));
|
||||
|
||||
float complete = (radius_complete - radius_analog_stick - radius_minimum);
|
||||
|
||||
float movement_x;
|
||||
float movement_y;
|
||||
|
||||
movement_x = -(1 / complete) * (correlated_x - (correlated_x > 0 ? radius_minimum : -radius_minimum));
|
||||
movement_y = (1 / complete) * (correlated_y - (correlated_y > 0 ? radius_minimum : -radius_minimum));
|
||||
|
||||
position_stick_x = getWidth() / 2 - correlated_x;
|
||||
position_stick_y = getHeight() / 2 - correlated_y;
|
||||
|
||||
// check if analog stick is outside of dead zone and minimum
|
||||
if (movement_radius > radius_minimum && movement_dead_zone_radius > radius_dead_zone)
|
||||
{
|
||||
// set active
|
||||
stick_state = _STICK_STATE.MOVED_ACTIVE;
|
||||
}
|
||||
|
||||
if (stick_state == _STICK_STATE.MOVED_ACTIVE)
|
||||
{
|
||||
moveActionCallback(movement_x, movement_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event)
|
||||
{
|
||||
// get masked (not specific to a pointer) action
|
||||
int action = event.getActionMasked();
|
||||
_CLICK_STATE lastClickState = click_state;
|
||||
public boolean onElementTouchEvent(MotionEvent event) {
|
||||
// save last click state
|
||||
CLICK_STATE lastClickState = click_state;
|
||||
|
||||
position_moved_x = event.getX();
|
||||
position_moved_y = event.getY();
|
||||
// get absolute way for each axis
|
||||
relative_x = -(getWidth() / 2 - event.getX());
|
||||
relative_y = -(getHeight() / 2 - event.getY());
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
{
|
||||
setPressed(true);
|
||||
position_pressed_x = position_moved_x;
|
||||
position_pressed_y = position_moved_y;
|
||||
stick_state = _STICK_STATE.MOVED_IN_DEAD_ZONE;
|
||||
// get radius and angel of movement from center
|
||||
movement_radius = getMovementRadius(relative_x, relative_y);
|
||||
movement_angle = getAngle(relative_x, relative_y);
|
||||
|
||||
// check for double click
|
||||
if (lastClickState == _CLICK_STATE.SINGLE && timeLastClick + timeoutDoubleClick > System.currentTimeMillis())
|
||||
{
|
||||
click_state = _CLICK_STATE.DOUBLE;
|
||||
// chop radius if out of outer circle and already pressed
|
||||
if (movement_radius > (radius_complete - radius_analog_stick)) {
|
||||
// not pressed already, so ignore event from outer circle
|
||||
if (!isPressed()) {
|
||||
return false;
|
||||
}
|
||||
movement_radius = radius_complete - radius_analog_stick;
|
||||
}
|
||||
|
||||
doubleClickActionCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
click_state = _CLICK_STATE.SINGLE;
|
||||
// handle event depending on action
|
||||
switch (event.getActionMasked()) {
|
||||
// down event (touch event)
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
// set to dead zoned, will be corrected in update position if necessary
|
||||
stick_state = STICK_STATE.MOVED_IN_DEAD_ZONE;
|
||||
// check for double click
|
||||
if (lastClickState == CLICK_STATE.SINGLE &&
|
||||
timeLastClick + timeoutDoubleClick > System.currentTimeMillis()) {
|
||||
click_state = CLICK_STATE.DOUBLE;
|
||||
notifyOnDoubleClick();
|
||||
} else {
|
||||
click_state = CLICK_STATE.SINGLE;
|
||||
notifyOnClick();
|
||||
}
|
||||
// reset last click timestamp
|
||||
timeLastClick = System.currentTimeMillis();
|
||||
// set item pressed and update
|
||||
setPressed(true);
|
||||
break;
|
||||
}
|
||||
// up event (revoke touch)
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
setPressed(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
clickActionCallback();
|
||||
}
|
||||
|
||||
timeLastClick = System.currentTimeMillis();
|
||||
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
{
|
||||
setPressed(false);
|
||||
stick_state = _STICK_STATE.NO_MOVEMENT;
|
||||
|
||||
revokeActionCallback();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isPressed())
|
||||
{ // when is pressed calculate new positions (will trigger movement if necessary)
|
||||
if (isPressed()) {
|
||||
// when is pressed calculate new positions (will trigger movement if necessary)
|
||||
updatePosition();
|
||||
} else {
|
||||
stick_state = STICK_STATE.NO_MOVEMENT;
|
||||
notifyOnRevoke();
|
||||
// not longer pressed reset analog stick
|
||||
notifyOnMovement(0, 0);
|
||||
}
|
||||
else
|
||||
{ // not longer pressed reset analog stick
|
||||
moveActionCallback(0, 0);
|
||||
}
|
||||
|
||||
// to get view refreshed
|
||||
// refresh view
|
||||
invalidate();
|
||||
|
||||
// accept the touch event
|
||||
return true;
|
||||
}
|
||||
|
||||
private enum _STICK_STATE
|
||||
{
|
||||
NO_MOVEMENT,
|
||||
MOVED_IN_DEAD_ZONE,
|
||||
MOVED_ACTIVE
|
||||
}
|
||||
|
||||
|
||||
private enum _CLICK_STATE
|
||||
{
|
||||
SINGLE,
|
||||
DOUBLE
|
||||
}
|
||||
|
||||
public interface AnalogStickListener
|
||||
{
|
||||
void onMovement(float x, float y);
|
||||
|
||||
void onClick();
|
||||
|
||||
void onRevoke();
|
||||
|
||||
void onDoubleClick();
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
@ -13,14 +17,42 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Created by Karim on 24.01.2015.
|
||||
* This is a digital button on screen element. It is used to get click and double click user input.
|
||||
*/
|
||||
public class DigitalButton extends VirtualControllerElement
|
||||
{
|
||||
static List<DigitalButton> allButtonsList = new ArrayList<>();
|
||||
public class DigitalButton extends VirtualControllerElement {
|
||||
|
||||
List<DigitalButtonListener> listeners = new ArrayList<>();
|
||||
OnTouchListener onTouchListener = null;
|
||||
/**
|
||||
* Listener interface to update registered observers.
|
||||
*/
|
||||
public interface DigitalButtonListener {
|
||||
|
||||
/**
|
||||
* onClick event will be fired on button click.
|
||||
*/
|
||||
void onClick();
|
||||
|
||||
/**
|
||||
* onLongClick event will be fired on button long click.
|
||||
*/
|
||||
void onLongClick();
|
||||
|
||||
/**
|
||||
* onRelease event will be fired on button unpress.
|
||||
*/
|
||||
void onRelease();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private class TimerLongClickTimerTask extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
onLongClickCallback();
|
||||
}
|
||||
}
|
||||
|
||||
private List<DigitalButtonListener> listeners = new ArrayList<DigitalButtonListener>();
|
||||
private String text = "";
|
||||
private int icon = -1;
|
||||
private long timerLongClickTimeout = 3000;
|
||||
@ -30,17 +62,14 @@ public class DigitalButton extends VirtualControllerElement
|
||||
private int layer;
|
||||
private DigitalButton movingButton = null;
|
||||
|
||||
boolean inRange(float x, float y)
|
||||
{
|
||||
boolean inRange(float x, float y) {
|
||||
return (this.getX() < x && this.getX() + this.getWidth() > x) &&
|
||||
(this.getY() < y && this.getY() + this.getHeight() > y);
|
||||
}
|
||||
|
||||
public boolean checkMovement(float x, float y, DigitalButton movingButton)
|
||||
{
|
||||
public boolean checkMovement(float x, float y, DigitalButton movingButton) {
|
||||
// check if the movement happened in the same layer
|
||||
if (movingButton.layer != this.layer)
|
||||
{
|
||||
if (movingButton.layer != this.layer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -49,36 +78,27 @@ public class DigitalButton extends VirtualControllerElement
|
||||
|
||||
// check if the movement directly happened on the button
|
||||
if ((this.movingButton == null || movingButton == this.movingButton)
|
||||
&& this.inRange(x, y))
|
||||
{
|
||||
&& this.inRange(x, y)) {
|
||||
// set button pressed state depending on moving button pressed state
|
||||
if (this.isPressed() != movingButton.isPressed())
|
||||
{
|
||||
if (this.isPressed() != movingButton.isPressed()) {
|
||||
this.setPressed(movingButton.isPressed());
|
||||
}
|
||||
}
|
||||
// check if the movement is outside of the range and the movement button
|
||||
// is saved moving button
|
||||
else if (movingButton == this.movingButton)
|
||||
{
|
||||
// check if the movement is outside of the range and the movement button
|
||||
// is the saved moving button
|
||||
else if (movingButton == this.movingButton) {
|
||||
this.setPressed(false);
|
||||
}
|
||||
|
||||
// check if a change occurred
|
||||
if (wasPressed != isPressed())
|
||||
{
|
||||
|
||||
if (isPressed())
|
||||
{ // is pressed set moving button and emit click event
|
||||
if (wasPressed != isPressed()) {
|
||||
if (isPressed()) {
|
||||
// is pressed set moving button and emit click event
|
||||
this.movingButton = movingButton;
|
||||
|
||||
onClickCallback();
|
||||
}
|
||||
|
||||
else
|
||||
{ // no longer pressed reset moving button and emit release event
|
||||
} else {
|
||||
// no longer pressed reset moving button and emit release event
|
||||
this.movingButton = null;
|
||||
|
||||
onReleaseCallback();
|
||||
}
|
||||
|
||||
@ -90,51 +110,35 @@ public class DigitalButton extends VirtualControllerElement
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkMovementForAllButtons(float x, float y)
|
||||
{
|
||||
for (DigitalButton button : allButtonsList)
|
||||
{
|
||||
if (button != this)
|
||||
{
|
||||
button.checkMovement(x, y, this);
|
||||
private void checkMovementForAllButtons(float x, float y) {
|
||||
for (VirtualControllerElement element : virtualController.getElements()) {
|
||||
if (element != this && element instanceof DigitalButton){
|
||||
((DigitalButton)element).checkMovement(x, y, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DigitalButton(int layer, Context context)
|
||||
{
|
||||
super(context);
|
||||
|
||||
public DigitalButton(VirtualController controller, int layer, Context context) {
|
||||
super(controller, context);
|
||||
this.layer = layer;
|
||||
}
|
||||
|
||||
allButtonsList.add(this);
|
||||
public void addDigitalButtonListener(DigitalButtonListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void addDigitalButtonListener(DigitalButtonListener listener)
|
||||
{
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void setOnTouchListener(OnTouchListener listener)
|
||||
{
|
||||
onTouchListener = listener;
|
||||
}
|
||||
|
||||
public void setText(String text)
|
||||
{
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIcon(int id)
|
||||
{
|
||||
public void setIcon(int id) {
|
||||
this.icon = id;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas)
|
||||
{
|
||||
protected void onElementDraw(Canvas canvas) {
|
||||
// set transparent background
|
||||
canvas.drawColor(Color.TRANSPARENT);
|
||||
|
||||
@ -146,90 +150,58 @@ public class DigitalButton extends VirtualControllerElement
|
||||
|
||||
paint.setColor(isPressed() ? pressedColor : normalColor);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
canvas.drawRect(
|
||||
1, 1,
|
||||
getWidth() - 1, getHeight() - 1,
|
||||
paint
|
||||
);
|
||||
canvas.drawRect(1, 1, getWidth() - 1, getHeight() - 1, paint);
|
||||
|
||||
if (icon != -1)
|
||||
{
|
||||
if (icon != -1) {
|
||||
Drawable d = getResources().getDrawable(icon);
|
||||
d.setBounds(5, 5, getWidth() - 5, getHeight() - 5);
|
||||
d.draw(canvas);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
paint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
canvas.drawText(text,
|
||||
getPercent(getWidth(), 50), getPercent(getHeight(), 73),
|
||||
paint);
|
||||
canvas.drawText(text, getPercent(getWidth(), 50), getPercent(getHeight(), 73), paint);
|
||||
}
|
||||
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
private void onClickCallback()
|
||||
{
|
||||
private void onClickCallback() {
|
||||
_DBG("clicked");
|
||||
|
||||
// notify listeners
|
||||
for (DigitalButtonListener listener : listeners)
|
||||
{
|
||||
for (DigitalButtonListener listener : listeners) {
|
||||
listener.onClick();
|
||||
}
|
||||
|
||||
timerLongClick = new Timer();
|
||||
longClickTimerTask = new TimerLongClickTimerTask();
|
||||
|
||||
timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout);
|
||||
}
|
||||
|
||||
private void onLongClickCallback()
|
||||
{
|
||||
private void onLongClickCallback() {
|
||||
_DBG("long click");
|
||||
|
||||
// notify listeners
|
||||
for (DigitalButtonListener listener : listeners)
|
||||
{
|
||||
for (DigitalButtonListener listener : listeners) {
|
||||
listener.onLongClick();
|
||||
}
|
||||
}
|
||||
|
||||
private void onReleaseCallback()
|
||||
{
|
||||
private void onReleaseCallback() {
|
||||
_DBG("released");
|
||||
|
||||
// notify listeners
|
||||
for (DigitalButtonListener listener : listeners)
|
||||
{
|
||||
for (DigitalButtonListener listener : listeners) {
|
||||
listener.onRelease();
|
||||
}
|
||||
|
||||
timerLongClick.cancel();
|
||||
longClickTimerTask.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event)
|
||||
{
|
||||
/*
|
||||
if (onTouchListener != null)
|
||||
{
|
||||
return onTouchListener.onTouch(this, event);
|
||||
}
|
||||
*/
|
||||
public boolean onElementTouchEvent(MotionEvent event) {
|
||||
// get masked (not specific to a pointer) action
|
||||
|
||||
float x = getX() + event.getX();
|
||||
float y = getY() + event.getY();
|
||||
int action = event.getActionMasked();
|
||||
|
||||
switch (action)
|
||||
{
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
{
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
movingButton = null;
|
||||
setPressed(true);
|
||||
onClickCallback();
|
||||
@ -238,16 +210,14 @@ public class DigitalButton extends VirtualControllerElement
|
||||
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
{
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
checkMovementForAllButtons(x, y);
|
||||
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
{
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
setPressed(false);
|
||||
onReleaseCallback();
|
||||
|
||||
@ -257,29 +227,9 @@ public class DigitalButton extends VirtualControllerElement
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public interface DigitalButtonListener
|
||||
{
|
||||
void onClick();
|
||||
|
||||
void onLongClick();
|
||||
|
||||
void onRelease();
|
||||
}
|
||||
|
||||
private class TimerLongClickTimerTask extends TimerTask
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
onLongClickCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
@ -9,11 +13,7 @@ import android.view.MotionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Karim Mreisi on 23.01.2015.
|
||||
*/
|
||||
public class DigitalPad extends VirtualControllerElement
|
||||
{
|
||||
public class DigitalPad extends VirtualControllerElement {
|
||||
public final static int DIGITAL_PAD_DIRECTION_NO_DIRECTION = 0;
|
||||
int direction = DIGITAL_PAD_DIRECTION_NO_DIRECTION;
|
||||
public final static int DIGITAL_PAD_DIRECTION_LEFT = 1;
|
||||
@ -21,26 +21,17 @@ public class DigitalPad extends VirtualControllerElement
|
||||
public final static int DIGITAL_PAD_DIRECTION_RIGHT = 4;
|
||||
public final static int DIGITAL_PAD_DIRECTION_DOWN = 8;
|
||||
List<DigitalPadListener> listeners = new ArrayList<DigitalPadListener>();
|
||||
OnTouchListener onTouchListener = null;
|
||||
|
||||
public DigitalPad(Context context)
|
||||
{
|
||||
super(context);
|
||||
public DigitalPad(VirtualController controller, Context context) {
|
||||
super(controller, context);
|
||||
}
|
||||
|
||||
public void addDigitalPadListener(DigitalPadListener listener)
|
||||
{
|
||||
public void addDigitalPadListener(DigitalPadListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void setOnTouchListener(OnTouchListener listener)
|
||||
{
|
||||
onTouchListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas)
|
||||
{
|
||||
protected void onElementDraw(Canvas canvas) {
|
||||
// set transparent background
|
||||
canvas.drawColor(Color.TRANSPARENT);
|
||||
|
||||
@ -50,8 +41,7 @@ public class DigitalPad extends VirtualControllerElement
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
paint.setStrokeWidth(3);
|
||||
|
||||
if (direction == DIGITAL_PAD_DIRECTION_NO_DIRECTION)
|
||||
{
|
||||
if (direction == DIGITAL_PAD_DIRECTION_NO_DIRECTION) {
|
||||
// draw no direction rect
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setColor(normalColor);
|
||||
@ -84,7 +74,7 @@ public class DigitalPad extends VirtualControllerElement
|
||||
);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
canvas.drawLine(
|
||||
0, getPercent(getWidth(), 33),
|
||||
0, getPercent(getHeight(), 33),
|
||||
getPercent(getWidth(), 33), 0,
|
||||
paint
|
||||
);
|
||||
@ -169,87 +159,60 @@ public class DigitalPad extends VirtualControllerElement
|
||||
getPercent(getWidth(), 0), getPercent(getHeight(), 66),
|
||||
paint
|
||||
);
|
||||
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
private void newDirectionCallback(int direction)
|
||||
{
|
||||
private void newDirectionCallback(int direction) {
|
||||
_DBG("direction: " + direction);
|
||||
|
||||
// notify listeners
|
||||
for (DigitalPadListener listener : listeners)
|
||||
{
|
||||
for (DigitalPadListener listener : listeners) {
|
||||
listener.onDirectionChange(direction);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event)
|
||||
{
|
||||
if (onTouchListener != null)
|
||||
{
|
||||
return onTouchListener.onTouch(this, event);
|
||||
}
|
||||
|
||||
public boolean onElementTouchEvent(MotionEvent event) {
|
||||
// get masked (not specific to a pointer) action
|
||||
int action = event.getActionMasked();
|
||||
|
||||
switch (action)
|
||||
{
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
{
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
direction = 0;
|
||||
|
||||
if (event.getX() < getPercent(getWidth(), 33))
|
||||
{
|
||||
if (event.getX() < getPercent(getWidth(), 33)) {
|
||||
direction |= DIGITAL_PAD_DIRECTION_LEFT;
|
||||
}
|
||||
|
||||
if (event.getX() > getPercent(getWidth(), 66))
|
||||
{
|
||||
if (event.getX() > getPercent(getWidth(), 66)) {
|
||||
direction |= DIGITAL_PAD_DIRECTION_RIGHT;
|
||||
}
|
||||
|
||||
if (event.getY() > getPercent(getHeight(), 66))
|
||||
{
|
||||
if (event.getY() > getPercent(getHeight(), 66)) {
|
||||
direction |= DIGITAL_PAD_DIRECTION_DOWN;
|
||||
}
|
||||
|
||||
if (event.getY() < getPercent(getHeight(), 33))
|
||||
{
|
||||
if (event.getY() < getPercent(getHeight(), 33)) {
|
||||
direction |= DIGITAL_PAD_DIRECTION_UP;
|
||||
}
|
||||
|
||||
newDirectionCallback(direction);
|
||||
|
||||
invalidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
{
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
direction = 0;
|
||||
|
||||
newDirectionCallback(direction);
|
||||
|
||||
invalidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public interface DigitalPadListener
|
||||
{
|
||||
public interface DigitalPadListener {
|
||||
void onDirectionChange(int direction);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.limelight.nvstream.input.ControllerPacket;
|
||||
|
||||
public class LeftAnalogStick extends AnalogStick {
|
||||
public LeftAnalogStick(final VirtualController controller, final Context context) {
|
||||
super(controller, context);
|
||||
|
||||
addAnalogStickListener(new AnalogStick.AnalogStickListener() {
|
||||
@Override
|
||||
public void onMovement(float x, float y) {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.leftStickX = (short) (x * 0x7FFE);
|
||||
inputContext.leftStickY = (short) (y * 0x7FFE);
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDoubleClick() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.inputMap |= ControllerPacket.LS_CLK_FLAG;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRevoke() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.inputMap &= ~ControllerPacket.LS_CLK_FLAG;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class LeftTrigger extends DigitalButton {
|
||||
public LeftTrigger(final VirtualController controller, final int layer, final Context context) {
|
||||
super(controller, layer, context);
|
||||
addDigitalButtonListener(new DigitalButton.DigitalButtonListener() {
|
||||
@Override
|
||||
public void onClick() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.leftTrigger = (byte)0xFF;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick() {}
|
||||
|
||||
@Override
|
||||
public void onRelease() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.leftTrigger = (byte)0x00;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.limelight.nvstream.input.ControllerPacket;
|
||||
|
||||
public class RightAnalogStick extends AnalogStick {
|
||||
public RightAnalogStick(final VirtualController controller, final Context context) {
|
||||
super(controller, context);
|
||||
|
||||
addAnalogStickListener(new AnalogStick.AnalogStickListener() {
|
||||
@Override
|
||||
public void onMovement(float x, float y) {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.rightStickX = (short) (x * 0x7FFE);
|
||||
inputContext.rightStickY = (short) (y * 0x7FFE);
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDoubleClick() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.inputMap |= ControllerPacket.RS_CLK_FLAG;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRevoke() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.inputMap &= ~ControllerPacket.RS_CLK_FLAG;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class RightTrigger extends DigitalButton {
|
||||
public RightTrigger(final VirtualController controller, final int layer, final Context context) {
|
||||
super(controller, layer, context);
|
||||
addDigitalButtonListener(new DigitalButton.DigitalButtonListener() {
|
||||
@Override
|
||||
public void onClick() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.rightTrigger = (byte)0xFF;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick() {}
|
||||
|
||||
@Override
|
||||
public void onRelease() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.rightTrigger = (byte)0x00;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,467 +1,148 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.limelight.R;
|
||||
import com.limelight.nvstream.NvConnection;
|
||||
import com.limelight.nvstream.input.ControllerPacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Karim Mreisi on 30.11.2014.
|
||||
*/
|
||||
public class VirtualController
|
||||
{
|
||||
private static final boolean _PRINT_DEBUG_INFORMATION = false;
|
||||
NvConnection connection = null;
|
||||
public class VirtualController {
|
||||
public class ControllerInputContext {
|
||||
public short inputMap = 0x0000;
|
||||
public byte leftTrigger = 0x00;
|
||||
public byte rightTrigger = 0x00;
|
||||
public short rightStickX = 0x0000;
|
||||
public short rightStickY = 0x0000;
|
||||
public short leftStickX = 0x0000;
|
||||
public short leftStickY = 0x0000;
|
||||
}
|
||||
|
||||
public enum ControllerMode {
|
||||
Active,
|
||||
Configuration
|
||||
}
|
||||
|
||||
private static final boolean _PRINT_DEBUG_INFORMATION = true;
|
||||
|
||||
private NvConnection connection = null;
|
||||
private Context context = null;
|
||||
private short inputMap = 0x0000;
|
||||
private byte leftTrigger = 0x00;
|
||||
private byte rightTrigger = 0x00;
|
||||
private short rightStickX = 0x0000;
|
||||
private short rightStickY = 0x0000;
|
||||
private short leftStickX = 0x0000;
|
||||
private short leftStickY = 0x0000;
|
||||
|
||||
private FrameLayout frame_layout = null;
|
||||
private RelativeLayout relative_layout = null;
|
||||
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonStart = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonSelect = null;
|
||||
ControllerMode currentMode = ControllerMode.Active;
|
||||
ControllerInputContext inputContext = new ControllerInputContext();
|
||||
|
||||
private RelativeLayout.LayoutParams layoutParamsDPad = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonConfigure = null;
|
||||
private Button buttonConfigure = null;
|
||||
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonA = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonB = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonX = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonY = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonLT = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonRT = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonLB = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonRB = null;
|
||||
private List<VirtualControllerElement> elements = new ArrayList<VirtualControllerElement>();
|
||||
|
||||
private RelativeLayout.LayoutParams layoutParamsStick = null;
|
||||
private RelativeLayout.LayoutParams layoutParamsStick2 = null;
|
||||
|
||||
private RelativeLayout.LayoutParams layoutParamsButtonConfigure = null;
|
||||
|
||||
private DigitalButton buttonStart = null;
|
||||
private DigitalButton buttonSelect = null;
|
||||
|
||||
private DigitalPad digitalPad = null;
|
||||
|
||||
private DigitalButton buttonA = null;
|
||||
private DigitalButton buttonB = null;
|
||||
private DigitalButton buttonX = null;
|
||||
private DigitalButton buttonY = null;
|
||||
private DigitalButton buttonLT = null;
|
||||
private DigitalButton buttonRT = null;
|
||||
private DigitalButton buttonLB = null;
|
||||
private DigitalButton buttonRB = null;
|
||||
|
||||
private AnalogStick stick = null;
|
||||
private AnalogStick stick2 = null;
|
||||
|
||||
private DigitalButton buttonConfigure = null;
|
||||
|
||||
public VirtualController(final NvConnection conn, FrameLayout layout, final Context context)
|
||||
{
|
||||
public VirtualController(final NvConnection conn, FrameLayout layout, final Context context) {
|
||||
this.connection = conn;
|
||||
this.frame_layout = layout;
|
||||
this.context = context;
|
||||
|
||||
relative_layout = new RelativeLayout(context);
|
||||
|
||||
relative_layout.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
|
||||
{
|
||||
refreshLayout();
|
||||
}
|
||||
});
|
||||
|
||||
frame_layout.addView(relative_layout);
|
||||
|
||||
digitalPad = new DigitalPad(context);
|
||||
digitalPad.addDigitalPadListener(new DigitalPad.DigitalPadListener()
|
||||
{
|
||||
buttonConfigure = new Button(context);
|
||||
buttonConfigure.setBackgroundResource(R.drawable.settings);
|
||||
buttonConfigure.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onDirectionChange(int direction)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (direction == DigitalPad.DIGITAL_PAD_DIRECTION_NO_DIRECTION)
|
||||
{
|
||||
inputMap &= ~ControllerPacket.LEFT_FLAG;
|
||||
inputMap &= ~ControllerPacket.RIGHT_FLAG;
|
||||
inputMap &= ~ControllerPacket.UP_FLAG;
|
||||
inputMap &= ~ControllerPacket.DOWN_FLAG;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_LEFT) > 0)
|
||||
{
|
||||
inputMap |= ControllerPacket.LEFT_FLAG;
|
||||
}
|
||||
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_RIGHT) > 0)
|
||||
{
|
||||
inputMap |= ControllerPacket.RIGHT_FLAG;
|
||||
}
|
||||
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_UP) > 0)
|
||||
{
|
||||
inputMap |= ControllerPacket.UP_FLAG;
|
||||
}
|
||||
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_DOWN) > 0)
|
||||
{
|
||||
inputMap |= ControllerPacket.DOWN_FLAG;
|
||||
}
|
||||
public void onClick(View v) {
|
||||
if (currentMode == ControllerMode.Configuration) {
|
||||
currentMode = ControllerMode.Active;
|
||||
} else {
|
||||
currentMode = ControllerMode.Configuration;
|
||||
}
|
||||
while (false);
|
||||
Toast.makeText(context, "CHANGE MODE " + currentMode, Toast.LENGTH_SHORT).show();
|
||||
|
||||
sendControllerInputPacket();
|
||||
relative_layout.invalidate();
|
||||
}
|
||||
});
|
||||
|
||||
buttonX = createDigitalButton("X", ControllerPacket.X_FLAG, context);
|
||||
buttonY = createDigitalButton("Y", ControllerPacket.Y_FLAG, context);
|
||||
buttonA = createDigitalButton("A", ControllerPacket.A_FLAG, context);
|
||||
buttonB = createDigitalButton("B", ControllerPacket.B_FLAG, context);
|
||||
|
||||
buttonLT = new DigitalButton(2, context);
|
||||
buttonLT.setText("LT");
|
||||
buttonLT.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick()
|
||||
{
|
||||
leftTrigger = (byte) (1 * 0xFF);
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease()
|
||||
{
|
||||
leftTrigger = (byte) (0 * 0xFF);
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
});
|
||||
|
||||
buttonRT = new DigitalButton(2, context);
|
||||
buttonRT.setText("RT");
|
||||
buttonRT.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick()
|
||||
{
|
||||
rightTrigger = (byte) (0xFF);
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease()
|
||||
{
|
||||
rightTrigger = (byte) (0);
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
});
|
||||
|
||||
buttonLB = createDigitalButton("LB", ControllerPacket.LB_FLAG, context);
|
||||
buttonRB = createDigitalButton("RB", ControllerPacket.RB_FLAG, context);
|
||||
|
||||
stick = new AnalogStick(context);
|
||||
|
||||
stick.addAnalogStickListener(new AnalogStick.AnalogStickListener()
|
||||
{
|
||||
@Override
|
||||
public void onMovement(float x, float y)
|
||||
{
|
||||
leftStickX = (short) (x * 0x7FFE);
|
||||
leftStickY = (short) (y * 0x7FFE);
|
||||
|
||||
_DBG("LEFT STICK MOVEMENT X: " + leftStickX + " Y: " + leftStickY);
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDoubleClick()
|
||||
{
|
||||
inputMap |= ControllerPacket.LS_CLK_FLAG;
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRevoke()
|
||||
{
|
||||
inputMap &= ~ControllerPacket.LS_CLK_FLAG;
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
});
|
||||
|
||||
stick2 = new AnalogStick(context);
|
||||
stick2.addAnalogStickListener(new AnalogStick.AnalogStickListener()
|
||||
{
|
||||
@Override
|
||||
public void onMovement(float x, float y)
|
||||
{
|
||||
rightStickX = (short) (x * 0x7FFE);
|
||||
rightStickY = (short) (y * 0x7FFE);
|
||||
|
||||
_DBG("RIGHT STICK MOVEMENT X: " + rightStickX + " Y: " + rightStickY);
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDoubleClick()
|
||||
{
|
||||
inputMap |= ControllerPacket.RS_CLK_FLAG;
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRevoke()
|
||||
{
|
||||
inputMap &= ~ControllerPacket.RS_CLK_FLAG;
|
||||
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
});
|
||||
|
||||
buttonStart = createDigitalButton("START", ControllerPacket.PLAY_FLAG, context);
|
||||
buttonSelect =
|
||||
createDigitalButton("SELECT", ControllerPacket.SPECIAL_BUTTON_FLAG, context);
|
||||
|
||||
buttonConfigure = new DigitalButton(1, context);
|
||||
buttonConfigure.setIcon(R.drawable.settings);
|
||||
buttonConfigure.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick()
|
||||
{
|
||||
openSettingsDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease()
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
refreshLayout();
|
||||
}
|
||||
|
||||
private static final void _DBG(String text)
|
||||
{
|
||||
if (_PRINT_DEBUG_INFORMATION)
|
||||
{
|
||||
public void removeElements() {
|
||||
for (VirtualControllerElement element : elements) {
|
||||
relative_layout.removeView(element);
|
||||
elements.remove(element);
|
||||
}
|
||||
}
|
||||
|
||||
public void addElement(VirtualControllerElement element, int x, int y, int width, int height) {
|
||||
elements.add(element);
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height);
|
||||
layoutParams.setMargins(x, y, 0, 0);
|
||||
|
||||
relative_layout.addView(element, layoutParams);
|
||||
}
|
||||
|
||||
public List<VirtualControllerElement> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
private static final void _DBG(String text) {
|
||||
if (_PRINT_DEBUG_INFORMATION) {
|
||||
System.out.println("VirtualController: " + text);
|
||||
}
|
||||
}
|
||||
|
||||
private int getPercentageV(int percent)
|
||||
{
|
||||
return (int) (((float) frame_layout.getHeight() / (float) 100) * (float) percent);
|
||||
}
|
||||
|
||||
private int getPercentageH(int percent)
|
||||
{
|
||||
return (int) (((float) frame_layout.getWidth() / (float) 100) * (float) percent);
|
||||
}
|
||||
|
||||
private void setPercentilePosition(RelativeLayout.LayoutParams parm, float pos_x, float pos_y)
|
||||
{
|
||||
parm.setMargins(
|
||||
(int) (((float) frame_layout.getWidth() / (float) 100 * pos_x) - ((float) parm.width / (float) 2)),
|
||||
(int) (((float) frame_layout.getHeight() / (float) 100 * pos_y) - ((float) parm.height / (float) 2)),
|
||||
0,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
public void openSettingsDialog()
|
||||
{
|
||||
Intent virtualControllerConfiguration =
|
||||
new Intent(context, VirtualControllerSettings.class);
|
||||
virtualControllerConfiguration.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
context.startActivity(virtualControllerConfiguration);
|
||||
|
||||
}
|
||||
|
||||
void refreshLayout()
|
||||
{
|
||||
public void refreshLayout() {
|
||||
relative_layout.removeAllViews();
|
||||
removeElements();
|
||||
|
||||
layoutParamsDPad =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(30), getPercentageV(30));
|
||||
|
||||
layoutParamsStick =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(40), getPercentageV(40));
|
||||
layoutParamsStick2 =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(40), getPercentageV(40));
|
||||
|
||||
layoutParamsButtonA =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
layoutParamsButtonB =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
layoutParamsButtonX =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
layoutParamsButtonY =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
layoutParamsButtonLT =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
layoutParamsButtonRT =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
|
||||
layoutParamsButtonLB =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
layoutParamsButtonRB =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
|
||||
layoutParamsButtonStart =
|
||||
new RelativeLayout.LayoutParams(getPercentageH(12), getPercentageV(8));
|
||||
layoutParamsButtonSelect =
|
||||
new RelativeLayout.LayoutParams(getPercentageH(12), getPercentageV(8));
|
||||
|
||||
layoutParamsButtonConfigure =
|
||||
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
|
||||
|
||||
setPercentilePosition(layoutParamsDPad, 10, 35);
|
||||
|
||||
setPercentilePosition(layoutParamsStick, 22, 78);
|
||||
setPercentilePosition(layoutParamsStick2, 78, 78);
|
||||
|
||||
setPercentilePosition(layoutParamsButtonA, 85, 52);
|
||||
setPercentilePosition(layoutParamsButtonB, 92, 47);
|
||||
setPercentilePosition(layoutParamsButtonX, 85, 40);
|
||||
setPercentilePosition(layoutParamsButtonY, 92, 35);
|
||||
|
||||
setPercentilePosition(layoutParamsButtonLT, 95, 68);
|
||||
setPercentilePosition(layoutParamsButtonRT, 95, 80);
|
||||
|
||||
setPercentilePosition(layoutParamsButtonLB, 85, 28);
|
||||
setPercentilePosition(layoutParamsButtonRB, 92, 23);
|
||||
|
||||
setPercentilePosition(layoutParamsButtonSelect, 43, 94);
|
||||
setPercentilePosition(layoutParamsButtonStart, 57, 94);
|
||||
|
||||
setPercentilePosition(layoutParamsButtonConfigure, 93, 7);
|
||||
|
||||
relative_layout.addView(digitalPad, layoutParamsDPad);
|
||||
|
||||
relative_layout.addView(stick, layoutParamsStick);
|
||||
relative_layout.addView(stick2, layoutParamsStick2);
|
||||
|
||||
relative_layout.addView(buttonA, layoutParamsButtonA);
|
||||
relative_layout.addView(buttonB, layoutParamsButtonB);
|
||||
relative_layout.addView(buttonX, layoutParamsButtonX);
|
||||
relative_layout.addView(buttonY, layoutParamsButtonY);
|
||||
relative_layout.addView(buttonLT, layoutParamsButtonLT);
|
||||
relative_layout.addView(buttonRT, layoutParamsButtonRT);
|
||||
relative_layout.addView(buttonLB, layoutParamsButtonLB);
|
||||
relative_layout.addView(buttonRB, layoutParamsButtonRB);
|
||||
|
||||
relative_layout.addView(buttonSelect, layoutParamsButtonSelect);
|
||||
relative_layout.addView(buttonStart, layoutParamsButtonStart);
|
||||
|
||||
layoutParamsButtonConfigure = new RelativeLayout.LayoutParams(50, 50);
|
||||
relative_layout.addView(buttonConfigure, layoutParamsButtonConfigure);
|
||||
|
||||
VirtualControllerConfigurationLoader.createDefaultLayout(this, context);
|
||||
}
|
||||
|
||||
private DigitalButton createDigitalButton(String text, final int key, Context context)
|
||||
{
|
||||
DigitalButton button = new DigitalButton(1, context);
|
||||
button.setText(text);
|
||||
button.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick()
|
||||
{
|
||||
inputMap |= key;
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease()
|
||||
{
|
||||
inputMap &= ~key;
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
});
|
||||
|
||||
return button;
|
||||
public ControllerMode getControllerMode () {
|
||||
return currentMode;
|
||||
}
|
||||
|
||||
private void sendControllerInputPacket()
|
||||
{
|
||||
try
|
||||
{
|
||||
_DBG("INPUT_MAP + " + inputMap);
|
||||
_DBG("LEFT_TRIGGER " + leftTrigger);
|
||||
_DBG("RIGHT_TRIGGER " + rightTrigger);
|
||||
_DBG("LEFT STICK X: " + leftStickX + " Y: " + leftStickY);
|
||||
_DBG("RIGHT STICK X: " + rightStickX + " Y: " + rightStickY);
|
||||
_DBG("RIGHT STICK X: " + rightStickX + " Y: " + rightStickY);
|
||||
public ControllerInputContext getControllerInputContext () {
|
||||
return inputContext;
|
||||
}
|
||||
|
||||
if (connection != null)
|
||||
{
|
||||
connection.sendControllerInput(inputMap, leftTrigger, rightTrigger,
|
||||
leftStickX, leftStickY, rightStickX, rightStickY);
|
||||
public void sendControllerInputContext() {
|
||||
sendControllerInputPacket();
|
||||
}
|
||||
|
||||
private void sendControllerInputPacket() {
|
||||
try {
|
||||
_DBG("INPUT_MAP + " + inputContext.inputMap);
|
||||
_DBG("LEFT_TRIGGER " + inputContext.leftTrigger);
|
||||
_DBG("RIGHT_TRIGGER " + inputContext.rightTrigger);
|
||||
_DBG("LEFT STICK X: " + inputContext.leftStickX + " Y: " + inputContext.leftStickY);
|
||||
_DBG("RIGHT STICK X: " + inputContext.rightStickX + " Y: " + inputContext.rightStickY);
|
||||
_DBG("RIGHT STICK X: " + inputContext.rightStickX + " Y: " + inputContext.rightStickY);
|
||||
|
||||
if (connection != null) {
|
||||
connection.sendControllerInput(
|
||||
inputContext.inputMap,
|
||||
inputContext.leftTrigger,
|
||||
inputContext.rightTrigger,
|
||||
inputContext.leftStickX,
|
||||
inputContext.leftStickY,
|
||||
inputContext.rightStickX,
|
||||
inputContext.rightStickY
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.limelight.R;
|
||||
|
||||
/**
|
||||
* Created by Karim Mreisi on 22.01.2015.
|
||||
*/
|
||||
public class VirtualControllerConfiguration extends Activity
|
||||
{
|
||||
VirtualController virtualController;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// We don't want a title bar
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
// Full-screen and don't let the display go off
|
||||
getWindow().addFlags(
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN |
|
||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
// Inflate the content
|
||||
setContentView(R.layout.activity_configure_virtual_controller);
|
||||
|
||||
FrameLayout frameLayout =
|
||||
(FrameLayout) findViewById(R.id.configure_virtual_controller_frameLayout);
|
||||
|
||||
// start with configuration constructor
|
||||
virtualController = new VirtualController(null, frameLayout, this);
|
||||
|
||||
Toast.makeText(getApplicationContext(), "Not implemented yet!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import com.limelight.nvstream.input.ControllerPacket;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VirtualControllerConfigurationLoader {
|
||||
private static final String PROFILE_PATH = "profiles";
|
||||
private static int getPercent(
|
||||
int percent,
|
||||
int total) {
|
||||
return (int) (((float) total / (float) 100) * (float) percent);
|
||||
}
|
||||
|
||||
private static DigitalPad createDigitalPad(
|
||||
final VirtualController controller,
|
||||
final Context context) {
|
||||
|
||||
DigitalPad digitalPad = new DigitalPad(controller, context);
|
||||
digitalPad.addDigitalPadListener(new DigitalPad.DigitalPadListener() {
|
||||
@Override
|
||||
public void onDirectionChange(int direction) {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
|
||||
if (direction == DigitalPad.DIGITAL_PAD_DIRECTION_NO_DIRECTION) {
|
||||
inputContext.inputMap &= ~ControllerPacket.LEFT_FLAG;
|
||||
inputContext.inputMap &= ~ControllerPacket.RIGHT_FLAG;
|
||||
inputContext.inputMap &= ~ControllerPacket.UP_FLAG;
|
||||
inputContext.inputMap &= ~ControllerPacket.DOWN_FLAG;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
return;
|
||||
}
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_LEFT) > 0) {
|
||||
inputContext.inputMap |= ControllerPacket.LEFT_FLAG;
|
||||
}
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_RIGHT) > 0) {
|
||||
inputContext.inputMap |= ControllerPacket.RIGHT_FLAG;
|
||||
}
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_UP) > 0) {
|
||||
inputContext.inputMap |= ControllerPacket.UP_FLAG;
|
||||
}
|
||||
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_DOWN) > 0) {
|
||||
inputContext.inputMap |= ControllerPacket.DOWN_FLAG;
|
||||
}
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
});
|
||||
|
||||
return digitalPad;
|
||||
}
|
||||
|
||||
private static DigitalButton createDigitalButton(
|
||||
final int keyShort,
|
||||
final int keyLong,
|
||||
final int layer,
|
||||
final String text,
|
||||
final int icon,
|
||||
final VirtualController controller,
|
||||
final Context context) {
|
||||
DigitalButton button = new DigitalButton(controller, layer, context);
|
||||
button.setText(text);
|
||||
button.setIcon(icon);
|
||||
|
||||
button.addDigitalButtonListener(new DigitalButton.DigitalButtonListener() {
|
||||
@Override
|
||||
public void onClick() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.inputMap |= keyShort;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClick() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.inputMap |= keyLong;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease() {
|
||||
VirtualController.ControllerInputContext inputContext =
|
||||
controller.getControllerInputContext();
|
||||
inputContext.inputMap &= ~keyShort;
|
||||
inputContext.inputMap &= ~keyLong;
|
||||
|
||||
controller.sendControllerInputContext();
|
||||
}
|
||||
});
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private static DigitalButton createLeftTrigger(
|
||||
final int layer,
|
||||
final String text,
|
||||
final int icon,
|
||||
final VirtualController controller,
|
||||
final Context context) {
|
||||
LeftTrigger button = new LeftTrigger(controller, layer, context);
|
||||
button.setText(text);
|
||||
button.setIcon(icon);
|
||||
return button;
|
||||
}
|
||||
|
||||
private static DigitalButton createRightTrigger(
|
||||
final int layer,
|
||||
final String text,
|
||||
final int icon,
|
||||
final VirtualController controller,
|
||||
final Context context) {
|
||||
RightTrigger button = new RightTrigger(controller, layer, context);
|
||||
button.setText(text);
|
||||
button.setIcon(icon);
|
||||
return button;
|
||||
}
|
||||
|
||||
private static AnalogStick createLeftStick(
|
||||
final VirtualController controller,
|
||||
final Context context) {
|
||||
return new LeftAnalogStick(controller, context);
|
||||
}
|
||||
|
||||
private static AnalogStick createRightStick(
|
||||
final VirtualController controller,
|
||||
final Context context) {
|
||||
return new RightAnalogStick(controller, context);
|
||||
}
|
||||
|
||||
public static void createDefaultLayout(final VirtualController controller, final Context context) {
|
||||
|
||||
DisplayMetrics screen = context.getResources().getDisplayMetrics();
|
||||
|
||||
controller.addElement(createDigitalPad(controller, context),
|
||||
getPercent(5, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels),
|
||||
getPercent(30, screen.widthPixels),
|
||||
getPercent(40, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createDigitalButton(
|
||||
ControllerPacket.A_FLAG, 0, 1, "A", -1, controller, context),
|
||||
getPercent(75, screen.widthPixels),
|
||||
getPercent(40, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createDigitalButton(
|
||||
ControllerPacket.B_FLAG, 0, 1, "B", -1, controller, context),
|
||||
getPercent(85, screen.widthPixels),
|
||||
getPercent(30, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createDigitalButton(
|
||||
ControllerPacket.X_FLAG, 0, 1, "X", -1, controller, context),
|
||||
getPercent(65, screen.widthPixels),
|
||||
getPercent(30, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createDigitalButton(
|
||||
ControllerPacket.Y_FLAG, 0, 1, "Y", -1, controller, context),
|
||||
getPercent(75, screen.widthPixels),
|
||||
getPercent(20, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createLeftTrigger(
|
||||
0, "LT", -1, controller, context),
|
||||
getPercent(65, screen.widthPixels),
|
||||
getPercent(20, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createRightTrigger(
|
||||
0, "RT", -1, controller, context),
|
||||
getPercent(85, screen.widthPixels),
|
||||
getPercent(20, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createLeftStick(controller, context),
|
||||
getPercent(5, screen.widthPixels),
|
||||
getPercent(50, screen.heightPixels),
|
||||
getPercent(40, screen.widthPixels),
|
||||
getPercent(50, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createRightStick(controller, context),
|
||||
getPercent(55, screen.widthPixels),
|
||||
getPercent(50, screen.heightPixels),
|
||||
getPercent(40, screen.widthPixels),
|
||||
getPercent(50, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createDigitalButton(
|
||||
ControllerPacket.SPECIAL_BUTTON_FLAG, 0, 2, "SELECT", -1, controller, context),
|
||||
getPercent(40, screen.widthPixels),
|
||||
getPercent(90, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
|
||||
controller.addElement(createDigitalButton(
|
||||
ControllerPacket.PLAY_FLAG, 0, 3, "PLAY", -1, controller, context),
|
||||
getPercent(50, screen.widthPixels),
|
||||
getPercent(90, screen.heightPixels),
|
||||
getPercent(10, screen.widthPixels),
|
||||
getPercent(10, screen.heightPixels)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
NOT IMPLEMENTED YET,
|
||||
this should later be used to store and load a profile for the virtual controller
|
||||
public static void saveProfile(final String name,
|
||||
final VirtualController controller,
|
||||
final Context context) {
|
||||
|
||||
SharedPreferences preferences = context.getSharedPreferences(PROFILE_PATH + "/" +
|
||||
name, Activity.MODE_PRIVATE);
|
||||
|
||||
JSONArray elementConfigurations = new JSONArray();
|
||||
for (VirtualControllerElement element : controller.getElements()) {
|
||||
JSONObject elementConfiguration = new JSONObject();
|
||||
try {
|
||||
elementConfiguration.put("TYPE", element.getClass().getName());
|
||||
elementConfiguration.put("CONFIGURATION", element.getConfiguration());
|
||||
elementConfigurations.put(elementConfiguration);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
SharedPreferences.Editor editor= preferences.edit();
|
||||
editor.putString("ELEMENTS", elementConfigurations.toString());
|
||||
}
|
||||
|
||||
public static void loadFromPreferences(final VirtualController controller) {
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,45 +1,280 @@
|
||||
/**
|
||||
* Created by Karim Mreisi.
|
||||
*/
|
||||
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
/**
|
||||
* Created by Karim on 27.01.2015.
|
||||
*/
|
||||
public abstract class VirtualControllerElement extends View
|
||||
{
|
||||
import org.json.JSONObject;
|
||||
|
||||
//import yuku.ambilwarna.AmbilWarnaDialog;
|
||||
|
||||
public abstract class VirtualControllerElement extends View {
|
||||
protected static boolean _PRINT_DEBUG_INFORMATION = false;
|
||||
|
||||
protected VirtualController virtualController;
|
||||
|
||||
protected int normalColor = 0xF0888888;
|
||||
protected int pressedColor = 0xF00000FF;
|
||||
|
||||
protected VirtualControllerElement(Context context)
|
||||
{
|
||||
super(context);
|
||||
protected int startSize_x;
|
||||
protected int startSize_y;
|
||||
|
||||
float position_pressed_x = 0;
|
||||
float position_pressed_y = 0;
|
||||
|
||||
private enum Mode {
|
||||
Normal,
|
||||
Resize,
|
||||
Move
|
||||
}
|
||||
|
||||
protected static final void _DBG(String text)
|
||||
{
|
||||
if (_PRINT_DEBUG_INFORMATION)
|
||||
{
|
||||
private Mode currentMode = Mode.Normal;
|
||||
|
||||
protected VirtualControllerElement(VirtualController controller, Context context) {
|
||||
super(context);
|
||||
|
||||
this.virtualController = controller;
|
||||
}
|
||||
|
||||
protected void moveElement(int pressed_x, int pressed_y, int x, int y) {
|
||||
int newPos_x = (int)getX() + x - pressed_x;
|
||||
int newPos_y = (int)getY() + y - pressed_y;
|
||||
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
layoutParams.leftMargin = newPos_x > 0 ? newPos_x : 0;
|
||||
layoutParams.topMargin = newPos_y > 0 ? newPos_y : 0;
|
||||
layoutParams.rightMargin = 0;
|
||||
layoutParams.bottomMargin = 0;
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
protected void resizeElement(int pressed_x, int pressed_y, int width, int height) {
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
int newHeight = height + (startSize_y - pressed_y);
|
||||
int newWidth = width + (startSize_x - pressed_x);
|
||||
|
||||
layoutParams.height = newHeight > 20 ? newHeight : 20;
|
||||
layoutParams.width = newWidth > 20 ? newWidth : 20;
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (virtualController.getControllerMode() == VirtualController.ControllerMode.
|
||||
Configuration) {
|
||||
Paint paint = new Paint();
|
||||
|
||||
paint.setColor(pressedColor);
|
||||
paint.setStrokeWidth(3);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
|
||||
canvas.drawRect(0, 0,
|
||||
getWidth(), getHeight(),
|
||||
paint);
|
||||
}
|
||||
|
||||
onElementDraw(canvas);
|
||||
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
/*
|
||||
protected void actionShowNormalColorChooser() {
|
||||
AmbilWarnaDialog colorDialog = new AmbilWarnaDialog(getContext(), normalColor, true, new AmbilWarnaDialog.OnAmbilWarnaListener() {
|
||||
@Override
|
||||
public void onCancel(AmbilWarnaDialog dialog)
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void onOk(AmbilWarnaDialog dialog, int color) {
|
||||
normalColor = color;
|
||||
invalidate();
|
||||
}
|
||||
});
|
||||
colorDialog.show();
|
||||
}
|
||||
|
||||
protected void actionShowPressedColorChooser() {
|
||||
AmbilWarnaDialog colorDialog = new AmbilWarnaDialog(getContext(), normalColor, true, new AmbilWarnaDialog.OnAmbilWarnaListener() {
|
||||
@Override
|
||||
public void onCancel(AmbilWarnaDialog dialog) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOk(AmbilWarnaDialog dialog, int color) {
|
||||
pressedColor = color;
|
||||
invalidate();
|
||||
}
|
||||
});
|
||||
colorDialog.show();
|
||||
}
|
||||
*/
|
||||
|
||||
protected void actionEnableMove() {
|
||||
currentMode = Mode.Move;
|
||||
}
|
||||
|
||||
protected void actionEnableResize() {
|
||||
currentMode = Mode.Resize;
|
||||
}
|
||||
|
||||
protected void actionCancel() {
|
||||
currentMode = Mode.Normal;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
protected void showConfigurationDialog() {
|
||||
try {
|
||||
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getContext());
|
||||
|
||||
alertBuilder.setTitle("Configuration");
|
||||
|
||||
CharSequence functions[] = new CharSequence[]{
|
||||
"Move",
|
||||
"Resize",
|
||||
/*election
|
||||
"Set n
|
||||
Disable color sormal color",
|
||||
"Set pressed color",
|
||||
*/
|
||||
"Cancel"
|
||||
};
|
||||
|
||||
alertBuilder.setItems(functions, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case 0: { // move
|
||||
actionEnableMove();
|
||||
break;
|
||||
}
|
||||
case 1: { // resize
|
||||
actionEnableResize();
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case 2: { // set default color
|
||||
actionShowNormalColorChooser();
|
||||
break;
|
||||
}
|
||||
case 3: { // set pressed color
|
||||
actionShowPressedColorChooser();
|
||||
break;
|
||||
}
|
||||
*/
|
||||
default: { // cancel
|
||||
actionCancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alert = alertBuilder.create();
|
||||
// show menu
|
||||
alert.show();
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (virtualController.getControllerMode() == VirtualController.ControllerMode.Active) {
|
||||
return onElementTouchEvent(event);
|
||||
}
|
||||
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
position_pressed_x = event.getX();
|
||||
position_pressed_y = event.getY();
|
||||
startSize_x = getWidth();
|
||||
startSize_y = getHeight();
|
||||
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
switch (currentMode) {
|
||||
case Move: {
|
||||
moveElement(
|
||||
(int) position_pressed_x,
|
||||
(int) position_pressed_y,
|
||||
(int) event.getX(),
|
||||
(int) event.getY());
|
||||
break;
|
||||
}
|
||||
case Resize: {
|
||||
resizeElement(
|
||||
(int) position_pressed_x,
|
||||
(int) position_pressed_y,
|
||||
(int) event.getX(),
|
||||
(int) event.getY());
|
||||
break;
|
||||
}
|
||||
case Normal: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
currentMode = Mode.Normal;
|
||||
showConfigurationDialog();
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract protected void onElementDraw(Canvas canvas);
|
||||
abstract public boolean onElementTouchEvent(MotionEvent event);
|
||||
|
||||
protected static final void _DBG(String text) {
|
||||
if (_PRINT_DEBUG_INFORMATION) {
|
||||
System.out.println(text);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColors(int normalColor, int pressedColor)
|
||||
{
|
||||
public void setColors(int normalColor, int pressedColor) {
|
||||
this.normalColor = normalColor;
|
||||
this.pressedColor = pressedColor;
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
protected final float getPercent(float value, float percent)
|
||||
{
|
||||
protected final float getPercent(float value, float percent) {
|
||||
return value / 100 * percent;
|
||||
}
|
||||
|
||||
protected final int getCorrectWidth()
|
||||
{
|
||||
return getWidth() > getHeight() ? getHeight() : getWidth();
|
||||
}
|
||||
protected final int getCorrectWidth() {
|
||||
return getWidth() > getHeight() ? getHeight() : getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
public JSONObject getConfiguration () {
|
||||
JSONObject configuration = new JSONObject();
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public void loadConfiguration (JSONObject configuration) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
package com.limelight.binding.input.virtual_controller;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.limelight.R;
|
||||
|
||||
/**
|
||||
* Created by Karim on 26.01.2015.
|
||||
*/
|
||||
public class VirtualControllerSettings extends Activity
|
||||
{
|
||||
private VirtualController controller = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
// We don't want a title bar
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
// Inflate the content
|
||||
setContentView(R.layout.activity_virtual_controller_settings);
|
||||
|
||||
Toast.makeText(getApplicationContext(), "Not implemented yet!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
@ -188,7 +188,6 @@ public class PreferenceConfiguration {
|
||||
config.multiController = prefs.getBoolean(MULTI_CONTROLLER_PREF_STRING, DEFAULT_MULTI_CONTROLLER);
|
||||
config.enable51Surround = prefs.getBoolean(ENABLE_51_SURROUND_PREF_STRING, DEFAULT_ENABLE_51_SURROUND);
|
||||
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
|
||||
|
||||
config.virtualController_enable = prefs.getBoolean(VIRTUAL_CONTROLLER_ENABLE, VIRTUAL_CONTROLLER_ENABLE_DEFAULT);
|
||||
|
||||
return config;
|
||||
|
@ -11,8 +11,6 @@ import android.preference.PreferenceManager;
|
||||
|
||||
import com.limelight.PcView;
|
||||
import com.limelight.R;
|
||||
import com.limelight.binding.input.virtual_controller.VirtualController;
|
||||
import com.limelight.binding.input.virtual_controller.VirtualControllerConfiguration;
|
||||
import com.limelight.utils.UiHelper;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -82,19 +80,6 @@ public class StreamSettings extends Activity {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Preference siteVirtualControllerButton = (Preference)findPreference("button_open_virtual_controller_configuration");
|
||||
siteVirtualControllerButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference arg0)
|
||||
{
|
||||
Intent virtualControllerConfiguration = new Intent(getActivity(), VirtualControllerConfiguration.class);
|
||||
startActivity(virtualControllerConfiguration);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,11 @@
|
||||
android:title="@string/title_checkbox_xb1_driver"
|
||||
android:summary="@string/summary_checkbox_xb1_driver"
|
||||
android:defaultValue="true" />
|
||||
<CheckBoxPreference
|
||||
android:key="virtual_controller_checkbox_enable"
|
||||
android:title="Enable virtual onscreen controller"
|
||||
android:summary="Show virtual controller overlay on game screen"
|
||||
android:defaultValue="true"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/category_host_settings">
|
||||
<CheckBoxPreference
|
||||
@ -90,15 +95,4 @@
|
||||
android:summary="@string/summary_video_format"
|
||||
android:defaultValue="auto" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="Virtual Controller">
|
||||
<CheckBoxPreference
|
||||
android:key="virtual_controller_checkbox_enable"
|
||||
android:title="Enable virtual controller"
|
||||
android:summary="Show virtual controller overlay on game screen"
|
||||
android:defaultValue="true"/>
|
||||
<Preference android:title="Site virtual controller items"
|
||||
android:key="button_open_virtual_controller_configuration"
|
||||
android:summary="tbd"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="limelight-android" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<module external.linked.project.id="moonlight-new" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
Loading…
x
Reference in New Issue
Block a user