mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 08:35:37 -04:00
Feat[controls]: Decouple stroke width from button size
This commit is contained in:
parent
fd5f46f243
commit
b4a3e18b9a
@ -32,21 +32,19 @@ public class ControlData {
|
|||||||
public static final int SPECIALBTN_SCROLLUP = -7;
|
public static final int SPECIALBTN_SCROLLUP = -7;
|
||||||
public static final int SPECIALBTN_SCROLLDOWN = -8;
|
public static final int SPECIALBTN_SCROLLDOWN = -8;
|
||||||
public static final int SPECIALBTN_MENU = -9;
|
public static final int SPECIALBTN_MENU = -9;
|
||||||
|
|
||||||
private static ControlData[] SPECIAL_BUTTONS;
|
private static ControlData[] SPECIAL_BUTTONS;
|
||||||
private static List<String> SPECIAL_BUTTON_NAME_ARRAY;
|
private static List<String> SPECIAL_BUTTON_NAME_ARRAY;
|
||||||
|
|
||||||
// Internal usage only
|
|
||||||
public boolean isHideable;
|
|
||||||
|
|
||||||
private static WeakReference<ExpressionBuilder> builder = new WeakReference<>(null);
|
private static WeakReference<ExpressionBuilder> builder = new WeakReference<>(null);
|
||||||
private static WeakReference<ArrayMap<String , String>> conversionMap = new WeakReference<>(null);
|
private static WeakReference<ArrayMap<String, String>> conversionMap = new WeakReference<>(null);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
buildExpressionBuilder();
|
buildExpressionBuilder();
|
||||||
buildConversionMap();
|
buildConversionMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internal usage only
|
||||||
|
public boolean isHideable;
|
||||||
/**
|
/**
|
||||||
* Both fields below are dynamic position data, auto updates
|
* Both fields below are dynamic position data, auto updates
|
||||||
* X and Y position, unlike the original one which uses fixed
|
* X and Y position, unlike the original one which uses fixed
|
||||||
@ -56,63 +54,29 @@ public class ControlData {
|
|||||||
*/
|
*/
|
||||||
public String dynamicX, dynamicY;
|
public String dynamicX, dynamicY;
|
||||||
public boolean isDynamicBtn, isToggle, passThruEnabled;
|
public boolean isDynamicBtn, isToggle, passThruEnabled;
|
||||||
|
|
||||||
public static ControlData[] getSpecialButtons(){
|
|
||||||
if (SPECIAL_BUTTONS == null) {
|
|
||||||
SPECIAL_BUTTONS = new ControlData[]{
|
|
||||||
new ControlData("Keyboard", new int[]{SPECIALBTN_KEYBOARD}, "${margin} * 3 + ${width} * 2", "${margin}", false),
|
|
||||||
new ControlData("GUI", new int[]{SPECIALBTN_TOGGLECTRL}, "${margin}", "${bottom} - ${margin}"),
|
|
||||||
new ControlData("PRI", new int[]{SPECIALBTN_MOUSEPRI}, "${margin}", "${screen_height} - ${margin} * 3 - ${height} * 3"),
|
|
||||||
new ControlData("SEC", new int[]{SPECIALBTN_MOUSESEC}, "${margin} * 3 + ${width} * 2", "${screen_height} - ${margin} * 3 - ${height} * 3"),
|
|
||||||
new ControlData("Mouse", new int[]{SPECIALBTN_VIRTUALMOUSE}, "${right}", "${margin}", false),
|
|
||||||
|
|
||||||
new ControlData("MID", new int[]{SPECIALBTN_MOUSEMID}, "${margin}", "${margin}"),
|
|
||||||
new ControlData("SCROLLUP", new int[]{SPECIALBTN_SCROLLUP}, "${margin}", "${margin}"),
|
|
||||||
new ControlData("SCROLLDOWN", new int[]{SPECIALBTN_SCROLLDOWN}, "${margin}", "${margin}"),
|
|
||||||
new ControlData("MENU", new int[]{SPECIALBTN_MENU}, "${margin}", "${margin}")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return SPECIAL_BUTTONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> buildSpecialButtonArray() {
|
|
||||||
if (SPECIAL_BUTTON_NAME_ARRAY == null) {
|
|
||||||
List<String> nameList = new ArrayList<>();
|
|
||||||
for (ControlData btn : getSpecialButtons()) {
|
|
||||||
nameList.add("SPECIAL_" + btn.name);
|
|
||||||
}
|
|
||||||
SPECIAL_BUTTON_NAME_ARRAY = nameList;
|
|
||||||
Collections.reverse(SPECIAL_BUTTON_NAME_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SPECIAL_BUTTON_NAME_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name;
|
public String name;
|
||||||
private float width; //Dp instead of Px now
|
|
||||||
private float height; //Dp instead of Px now
|
|
||||||
public int[] keycodes; //Should store up to 4 keys
|
public int[] keycodes; //Should store up to 4 keys
|
||||||
public float opacity; //Alpha value from 0 to 1;
|
public float opacity; //Alpha value from 0 to 1;
|
||||||
public int bgColor;
|
public int bgColor;
|
||||||
public int strokeColor;
|
public int strokeColor;
|
||||||
public int strokeWidth; //0-100%
|
public float strokeWidth; // Dp instead of % now
|
||||||
public float cornerRadius; //0-100%
|
public float cornerRadius; //0-100%
|
||||||
public boolean isSwipeable;
|
public boolean isSwipeable;
|
||||||
|
|
||||||
public boolean displayInGame;
|
public boolean displayInGame;
|
||||||
public boolean displayInMenu;
|
public boolean displayInMenu;
|
||||||
|
private float width; //Dp instead of Px now
|
||||||
|
private float height; //Dp instead of Px now
|
||||||
|
|
||||||
public ControlData() {
|
public ControlData() {
|
||||||
this("button");
|
this("button");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlData(String name){
|
public ControlData(String name) {
|
||||||
this(name, new int[] {});
|
this(name, new int[]{});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlData(String name, int[] keycodes) {
|
public ControlData(String name, int[] keycodes) {
|
||||||
this(name, keycodes, Tools.currentDisplayMetrics.widthPixels/2f, Tools.currentDisplayMetrics.heightPixels/2f);
|
this(name, keycodes, Tools.currentDisplayMetrics.widthPixels / 2f, Tools.currentDisplayMetrics.heightPixels / 2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlData(String name, int[] keycodes, float x, float y) {
|
public ControlData(String name, int[] keycodes, float x, float y) {
|
||||||
@ -144,11 +108,11 @@ public class ControlData {
|
|||||||
this(name, keycodes, dynamicX, dynamicY, isSquare ? 50 : 80, isSquare ? 50 : 30, false);
|
this(name, keycodes, dynamicX, dynamicY, isSquare ? 50 : 80, isSquare ? 50 : 30, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle){
|
public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle) {
|
||||||
this(name, keycodes, dynamicX, dynamicY, width, height, isToggle, 1,0x4D000000, 0xFFFFFFFF,0,0, true, true);
|
this(name, keycodes, dynamicX, dynamicY, width, height, isToggle, 1, 0x4D000000, 0xFFFFFFFF, 0, 0, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle, float opacity, int bgColor, int strokeColor, int strokeWidth, float cornerRadius, boolean displayInGame, boolean displayInMenu) {
|
public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle, float opacity, int bgColor, int strokeColor, float strokeWidth, float cornerRadius, boolean displayInGame, boolean displayInMenu) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.keycodes = inflateKeycodeArray(keycodes);
|
this.keycodes = inflateKeycodeArray(keycodes);
|
||||||
this.dynamicX = dynamicX;
|
this.dynamicX = dynamicX;
|
||||||
@ -167,7 +131,7 @@ public class ControlData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Deep copy constructor
|
//Deep copy constructor
|
||||||
public ControlData(ControlData controlData){
|
public ControlData(ControlData controlData) {
|
||||||
this(
|
this(
|
||||||
controlData.name,
|
controlData.name,
|
||||||
controlData.keycodes,
|
controlData.keycodes,
|
||||||
@ -186,13 +150,36 @@ public class ControlData {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ControlData[] getSpecialButtons() {
|
||||||
public float insertDynamicPos(String dynamicPos) {
|
if (SPECIAL_BUTTONS == null) {
|
||||||
// Insert value to ${variable}
|
SPECIAL_BUTTONS = new ControlData[]{
|
||||||
String insertedPos = JSONUtils.insertSingleJSONValue(dynamicPos, fillConversionMap());
|
new ControlData("Keyboard", new int[]{SPECIALBTN_KEYBOARD}, "${margin} * 3 + ${width} * 2", "${margin}", false),
|
||||||
|
new ControlData("GUI", new int[]{SPECIALBTN_TOGGLECTRL}, "${margin}", "${bottom} - ${margin}"),
|
||||||
// Calculate, because the dynamic position contains some math equations
|
new ControlData("PRI", new int[]{SPECIALBTN_MOUSEPRI}, "${margin}", "${screen_height} - ${margin} * 3 - ${height} * 3"),
|
||||||
return calculate(insertedPos);
|
new ControlData("SEC", new int[]{SPECIALBTN_MOUSESEC}, "${margin} * 3 + ${width} * 2", "${screen_height} - ${margin} * 3 - ${height} * 3"),
|
||||||
|
new ControlData("Mouse", new int[]{SPECIALBTN_VIRTUALMOUSE}, "${right}", "${margin}", false),
|
||||||
|
|
||||||
|
new ControlData("MID", new int[]{SPECIALBTN_MOUSEMID}, "${margin}", "${margin}"),
|
||||||
|
new ControlData("SCROLLUP", new int[]{SPECIALBTN_SCROLLUP}, "${margin}", "${margin}"),
|
||||||
|
new ControlData("SCROLLDOWN", new int[]{SPECIALBTN_SCROLLDOWN}, "${margin}", "${margin}"),
|
||||||
|
new ControlData("MENU", new int[]{SPECIALBTN_MENU}, "${margin}", "${margin}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPECIAL_BUTTONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> buildSpecialButtonArray() {
|
||||||
|
if (SPECIAL_BUTTON_NAME_ARRAY == null) {
|
||||||
|
List<String> nameList = new ArrayList<>();
|
||||||
|
for (ControlData btn : getSpecialButtons()) {
|
||||||
|
nameList.add("SPECIAL_" + btn.name);
|
||||||
|
}
|
||||||
|
SPECIAL_BUTTON_NAME_ARRAY = nameList;
|
||||||
|
Collections.reverse(SPECIAL_BUTTON_NAME_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPECIAL_BUTTON_NAME_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float calculate(String math) {
|
private static float calculate(String math) {
|
||||||
@ -200,44 +187,16 @@ public class ControlData {
|
|||||||
return (float) builder.get().build().evaluate();
|
return (float) builder.get().build().evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] inflateKeycodeArray(int[] keycodes){
|
private static int[] inflateKeycodeArray(int[] keycodes) {
|
||||||
int[] inflatedArray = new int[]{GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN};
|
int[] inflatedArray = new int[]{GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN};
|
||||||
System.arraycopy(keycodes, 0, inflatedArray, 0, keycodes.length);
|
System.arraycopy(keycodes, 0, inflatedArray, 0, keycodes.length);
|
||||||
return inflatedArray;
|
return inflatedArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
public boolean containsKeycode(int keycodeToCheck){
|
|
||||||
for(int keycode : keycodes)
|
|
||||||
if(keycodeToCheck == keycode)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Getters || setters (with conversion for ease of use)
|
|
||||||
public float getWidth() {
|
|
||||||
return Tools.dpToPx(width);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getHeight(){
|
|
||||||
return Tools.dpToPx(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setWidth(float widthInPx){
|
|
||||||
width = Tools.pxToDp(widthInPx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeight(float heightInPx){
|
|
||||||
height = Tools.pxToDp(heightInPx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a builder, keep a weak reference to it to use it with all views on first inflation
|
* Create a builder, keep a weak reference to it to use it with all views on first inflation
|
||||||
*/
|
*/
|
||||||
private static void buildExpressionBuilder(){
|
private static void buildExpressionBuilder() {
|
||||||
ExpressionBuilder expressionBuilder = new ExpressionBuilder("1 + 1")
|
ExpressionBuilder expressionBuilder = new ExpressionBuilder("1 + 1")
|
||||||
.function(new Function("dp", 1) {
|
.function(new Function("dp", 1) {
|
||||||
@Override
|
@Override
|
||||||
@ -256,10 +215,11 @@ public class ControlData {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* wrapper for the WeakReference to the expressionField.
|
* wrapper for the WeakReference to the expressionField.
|
||||||
|
*
|
||||||
* @param stringExpression the expression to set.
|
* @param stringExpression the expression to set.
|
||||||
*/
|
*/
|
||||||
private static void setExpression(String stringExpression){
|
private static void setExpression(String stringExpression) {
|
||||||
if(builder.get() == null) buildExpressionBuilder();
|
if (builder.get() == null) buildExpressionBuilder();
|
||||||
builder.get().expression(stringExpression);
|
builder.get().expression(stringExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +236,7 @@ public class ControlData {
|
|||||||
keyValueMap.put("bottom", "DUMMY_BOTTOM");
|
keyValueMap.put("bottom", "DUMMY_BOTTOM");
|
||||||
keyValueMap.put("width", "DUMMY_WIDTH");
|
keyValueMap.put("width", "DUMMY_WIDTH");
|
||||||
keyValueMap.put("height", "DUMMY_HEIGHT");
|
keyValueMap.put("height", "DUMMY_HEIGHT");
|
||||||
keyValueMap.put("screen_width", "DUMMY_DATA" );
|
keyValueMap.put("screen_width", "DUMMY_DATA");
|
||||||
keyValueMap.put("screen_height", "DUMMY_DATA");
|
keyValueMap.put("screen_height", "DUMMY_DATA");
|
||||||
keyValueMap.put("margin", Integer.toString((int) Tools.dpToPx(2)));
|
keyValueMap.put("margin", Integer.toString((int) Tools.dpToPx(2)));
|
||||||
keyValueMap.put("preferred_scale", "DUMMY_DATA");
|
keyValueMap.put("preferred_scale", "DUMMY_DATA");
|
||||||
@ -284,14 +244,49 @@ public class ControlData {
|
|||||||
conversionMap = new WeakReference<>(keyValueMap);
|
conversionMap = new WeakReference<>(keyValueMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float insertDynamicPos(String dynamicPos) {
|
||||||
|
// Insert value to ${variable}
|
||||||
|
String insertedPos = JSONUtils.insertSingleJSONValue(dynamicPos, fillConversionMap());
|
||||||
|
|
||||||
|
// Calculate, because the dynamic position contains some math equations
|
||||||
|
return calculate(insertedPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||||
|
public boolean containsKeycode(int keycodeToCheck) {
|
||||||
|
for (int keycode : keycodes)
|
||||||
|
if (keycodeToCheck == keycode)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Getters || setters (with conversion for ease of use)
|
||||||
|
public float getWidth() {
|
||||||
|
return Tools.dpToPx(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(float widthInPx) {
|
||||||
|
width = Tools.pxToDp(widthInPx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHeight() {
|
||||||
|
return Tools.dpToPx(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(float heightInPx) {
|
||||||
|
height = Tools.pxToDp(heightInPx);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill the conversionMap with controlData dependent values.
|
* Fill the conversionMap with controlData dependent values.
|
||||||
* The returned valueMap should NOT be kept in memory.
|
* The returned valueMap should NOT be kept in memory.
|
||||||
|
*
|
||||||
* @return the valueMap to use.
|
* @return the valueMap to use.
|
||||||
*/
|
*/
|
||||||
private Map<String, String> fillConversionMap(){
|
private Map<String, String> fillConversionMap() {
|
||||||
ArrayMap<String, String> valueMap = conversionMap.get();
|
ArrayMap<String, String> valueMap = conversionMap.get();
|
||||||
if (valueMap == null){
|
if (valueMap == null) {
|
||||||
buildConversionMap();
|
buildConversionMap();
|
||||||
valueMap = conversionMap.get();
|
valueMap = conversionMap.get();
|
||||||
}
|
}
|
||||||
@ -300,8 +295,8 @@ public class ControlData {
|
|||||||
valueMap.put("bottom", Float.toString(CallbackBridge.physicalHeight - getHeight()));
|
valueMap.put("bottom", Float.toString(CallbackBridge.physicalHeight - getHeight()));
|
||||||
valueMap.put("width", Float.toString(getWidth()));
|
valueMap.put("width", Float.toString(getWidth()));
|
||||||
valueMap.put("height", Float.toString(getHeight()));
|
valueMap.put("height", Float.toString(getHeight()));
|
||||||
valueMap.put("screen_width",Integer.toString(CallbackBridge.physicalWidth));
|
valueMap.put("screen_width", Integer.toString(CallbackBridge.physicalWidth));
|
||||||
valueMap.put("screen_height",Integer.toString(CallbackBridge.physicalHeight));
|
valueMap.put("screen_height", Integer.toString(CallbackBridge.physicalHeight));
|
||||||
valueMap.put("preferred_scale", Float.toString(LauncherPreferences.PREF_BUTTONSIZE));
|
valueMap.put("preferred_scale", Float.toString(LauncherPreferences.PREF_BUTTONSIZE));
|
||||||
|
|
||||||
return valueMap;
|
return valueMap;
|
||||||
|
@ -20,105 +20,159 @@ public class LayoutConverter {
|
|||||||
try {
|
try {
|
||||||
JSONObject layoutJobj = new JSONObject(jsonLayoutData);
|
JSONObject layoutJobj = new JSONObject(jsonLayoutData);
|
||||||
|
|
||||||
if(!layoutJobj.has("version")) { //v1 layout
|
if (!layoutJobj.has("version")) { //v1 layout
|
||||||
CustomControls layout = LayoutConverter.convertV1Layout(layoutJobj);
|
CustomControls layout = LayoutConverter.convertV1Layout(layoutJobj);
|
||||||
layout.save(jsonPath);
|
layout.save(jsonPath);
|
||||||
return layout;
|
return layout;
|
||||||
}else if (layoutJobj.getInt("version") == 2) {
|
} else if (layoutJobj.getInt("version") == 2) {
|
||||||
CustomControls layout = LayoutConverter.convertV2Layout(layoutJobj);
|
CustomControls layout = LayoutConverter.convertV2Layout(layoutJobj);
|
||||||
layout.save(jsonPath);
|
layout.save(jsonPath);
|
||||||
return layout;
|
return layout;
|
||||||
}else if (layoutJobj.getInt("version") >= 3 && layoutJobj.getInt("version") <= 5) {
|
}else if (layoutJobj.getInt("version") >= 3 && layoutJobj.getInt("version") <= 5) {
|
||||||
|
return LayoutConverter.convertV3_4Layout(layoutJobj);
|
||||||
|
} else if (layoutJobj.getInt("version") == 6) {
|
||||||
return Tools.GLOBAL_GSON.fromJson(jsonLayoutData, CustomControls.class);
|
return Tools.GLOBAL_GSON.fromJson(jsonLayoutData, CustomControls.class);
|
||||||
}else{
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
throw new JsonSyntaxException("Failed to load",e);
|
throw new JsonSyntaxException("Failed to load", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the layout to v5 from v3/4: The stroke width is no longer dependant on the button size
|
||||||
|
*/
|
||||||
|
public static CustomControls convertV3_4Layout(JSONObject oldLayoutJson) {
|
||||||
|
CustomControls layout = Tools.GLOBAL_GSON.fromJson(oldLayoutJson.toString(), CustomControls.class);
|
||||||
|
convertStrokeWidth(layout);
|
||||||
|
layout.version = 5;
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static CustomControls convertV2Layout(JSONObject oldLayoutJson) throws JSONException {
|
public static CustomControls convertV2Layout(JSONObject oldLayoutJson) throws JSONException {
|
||||||
CustomControls layout = Tools.GLOBAL_GSON.fromJson(oldLayoutJson.toString(), CustomControls.class);
|
CustomControls layout = Tools.GLOBAL_GSON.fromJson(oldLayoutJson.toString(), CustomControls.class);
|
||||||
JSONArray layoutMainArray = oldLayoutJson.getJSONArray("mControlDataList");
|
JSONArray layoutMainArray = oldLayoutJson.getJSONArray("mControlDataList");
|
||||||
layout.mControlDataList = new ArrayList<>(layoutMainArray.length());
|
layout.mControlDataList = new ArrayList<>(layoutMainArray.length());
|
||||||
for(int i = 0; i < layoutMainArray.length(); i++) {
|
for (int i = 0; i < layoutMainArray.length(); i++) {
|
||||||
JSONObject button = layoutMainArray.getJSONObject(i);
|
JSONObject button = layoutMainArray.getJSONObject(i);
|
||||||
ControlData n_button = Tools.GLOBAL_GSON.fromJson(button.toString(), ControlData.class);
|
ControlData n_button = Tools.GLOBAL_GSON.fromJson(button.toString(), ControlData.class);
|
||||||
if(!Tools.isValidString(n_button.dynamicX) && button.has("x")) {
|
if (!Tools.isValidString(n_button.dynamicX) && button.has("x")) {
|
||||||
double buttonC = button.getDouble("x");
|
double buttonC = button.getDouble("x");
|
||||||
double ratio = buttonC/CallbackBridge.physicalWidth;
|
double ratio = buttonC / CallbackBridge.physicalWidth;
|
||||||
n_button.dynamicX = ratio + " * ${screen_width}";
|
n_button.dynamicX = ratio + " * ${screen_width}";
|
||||||
}
|
}
|
||||||
if(!Tools.isValidString(n_button.dynamicY) && button.has("y")) {
|
if (!Tools.isValidString(n_button.dynamicY) && button.has("y")) {
|
||||||
double buttonC = button.getDouble("y");
|
double buttonC = button.getDouble("y");
|
||||||
double ratio = buttonC/CallbackBridge.physicalHeight;
|
double ratio = buttonC / CallbackBridge.physicalHeight;
|
||||||
n_button.dynamicY = ratio + " * ${screen_height}";
|
n_button.dynamicY = ratio + " * ${screen_height}";
|
||||||
}
|
}
|
||||||
layout.mControlDataList.add(n_button);
|
layout.mControlDataList.add(n_button);
|
||||||
}
|
}
|
||||||
JSONArray layoutDrawerArray = oldLayoutJson.getJSONArray("mDrawerDataList");
|
JSONArray layoutDrawerArray = oldLayoutJson.getJSONArray("mDrawerDataList");
|
||||||
layout.mDrawerDataList = new ArrayList<>();
|
layout.mDrawerDataList = new ArrayList<>();
|
||||||
for(int i = 0; i < layoutDrawerArray.length(); i++) {
|
for (int i = 0; i < layoutDrawerArray.length(); i++) {
|
||||||
JSONObject button = layoutDrawerArray.getJSONObject(i);
|
JSONObject button = layoutDrawerArray.getJSONObject(i);
|
||||||
JSONObject buttonProperties = button.getJSONObject("properties");
|
JSONObject buttonProperties = button.getJSONObject("properties");
|
||||||
ControlDrawerData n_button = Tools.GLOBAL_GSON.fromJson(button.toString(), ControlDrawerData.class);
|
ControlDrawerData n_button = Tools.GLOBAL_GSON.fromJson(button.toString(), ControlDrawerData.class);
|
||||||
if(!Tools.isValidString(n_button.properties.dynamicX) && buttonProperties.has("x")) {
|
if (!Tools.isValidString(n_button.properties.dynamicX) && buttonProperties.has("x")) {
|
||||||
double buttonC = buttonProperties.getDouble("x");
|
double buttonC = buttonProperties.getDouble("x");
|
||||||
double ratio = buttonC/CallbackBridge.physicalWidth;
|
double ratio = buttonC / CallbackBridge.physicalWidth;
|
||||||
n_button.properties.dynamicX = ratio + " * ${screen_width}";
|
n_button.properties.dynamicX = ratio + " * ${screen_width}";
|
||||||
}
|
}
|
||||||
if(!Tools.isValidString(n_button.properties.dynamicY) && buttonProperties.has("y")) {
|
if (!Tools.isValidString(n_button.properties.dynamicY) && buttonProperties.has("y")) {
|
||||||
double buttonC = buttonProperties.getDouble("y");
|
double buttonC = buttonProperties.getDouble("y");
|
||||||
double ratio = buttonC/CallbackBridge.physicalHeight;
|
double ratio = buttonC / CallbackBridge.physicalHeight;
|
||||||
n_button.properties.dynamicY = ratio + " * ${screen_height}";
|
n_button.properties.dynamicY = ratio + " * ${screen_height}";
|
||||||
}
|
}
|
||||||
layout.mDrawerDataList.add(n_button);
|
layout.mDrawerDataList.add(n_button);
|
||||||
}
|
}
|
||||||
|
convertStrokeWidth(layout);
|
||||||
|
|
||||||
layout.version = 3;
|
layout.version = 3;
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CustomControls convertV1Layout(JSONObject oldLayoutJson) throws JSONException {
|
public static CustomControls convertV1Layout(JSONObject oldLayoutJson) throws JSONException {
|
||||||
CustomControls empty = new CustomControls();
|
CustomControls empty = new CustomControls();
|
||||||
JSONArray layoutMainArray = oldLayoutJson.getJSONArray("mControlDataList");
|
JSONArray layoutMainArray = oldLayoutJson.getJSONArray("mControlDataList");
|
||||||
for(int i = 0; i < layoutMainArray.length(); i++) {
|
for (int i = 0; i < layoutMainArray.length(); i++) {
|
||||||
JSONObject button = layoutMainArray.getJSONObject(i);
|
JSONObject button = layoutMainArray.getJSONObject(i);
|
||||||
ControlData n_button = new ControlData();
|
ControlData n_button = new ControlData();
|
||||||
int[] keycodes = new int[] {LwjglGlfwKeycode.GLFW_KEY_UNKNOWN,
|
int[] keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_UNKNOWN,
|
||||||
LwjglGlfwKeycode.GLFW_KEY_UNKNOWN,
|
LwjglGlfwKeycode.GLFW_KEY_UNKNOWN,
|
||||||
LwjglGlfwKeycode.GLFW_KEY_UNKNOWN,
|
LwjglGlfwKeycode.GLFW_KEY_UNKNOWN,
|
||||||
LwjglGlfwKeycode.GLFW_KEY_UNKNOWN};
|
LwjglGlfwKeycode.GLFW_KEY_UNKNOWN};
|
||||||
n_button.isDynamicBtn = button.getBoolean("isDynamicBtn");
|
n_button.isDynamicBtn = button.getBoolean("isDynamicBtn");
|
||||||
n_button.dynamicX = button.getString("dynamicX");
|
n_button.dynamicX = button.getString("dynamicX");
|
||||||
n_button.dynamicY = button.getString("dynamicY");
|
n_button.dynamicY = button.getString("dynamicY");
|
||||||
if(!Tools.isValidString(n_button.dynamicX) && button.has("x")) {
|
if (!Tools.isValidString(n_button.dynamicX) && button.has("x")) {
|
||||||
double buttonC = button.getDouble("x");
|
double buttonC = button.getDouble("x");
|
||||||
double ratio = buttonC/CallbackBridge.physicalWidth;
|
double ratio = buttonC / CallbackBridge.physicalWidth;
|
||||||
n_button.dynamicX = ratio + " * ${screen_width}";
|
n_button.dynamicX = ratio + " * ${screen_width}";
|
||||||
}
|
}
|
||||||
if(!Tools.isValidString(n_button.dynamicY) && button.has("y")) {
|
if (!Tools.isValidString(n_button.dynamicY) && button.has("y")) {
|
||||||
double buttonC = button.getDouble("y");
|
double buttonC = button.getDouble("y");
|
||||||
double ratio = buttonC/CallbackBridge.physicalHeight;
|
double ratio = buttonC / CallbackBridge.physicalHeight;
|
||||||
n_button.dynamicY = ratio + " * ${screen_height}";
|
n_button.dynamicY = ratio + " * ${screen_height}";
|
||||||
}
|
}
|
||||||
n_button.name = button.getString("name");
|
n_button.name = button.getString("name");
|
||||||
n_button.opacity = ((float)((button.getInt("transparency")-100)*-1))/100f;
|
n_button.opacity = ((float) ((button.getInt("transparency") - 100) * -1)) / 100f;
|
||||||
n_button.passThruEnabled = button.getBoolean("passThruEnabled");
|
n_button.passThruEnabled = button.getBoolean("passThruEnabled");
|
||||||
n_button.isToggle = button.getBoolean("isToggle");
|
n_button.isToggle = button.getBoolean("isToggle");
|
||||||
n_button.setHeight(button.getInt("height"));
|
n_button.setHeight(button.getInt("height"));
|
||||||
n_button.setWidth(button.getInt("width"));
|
n_button.setWidth(button.getInt("width"));
|
||||||
n_button.bgColor = 0x4d000000;
|
n_button.bgColor = 0x4d000000;
|
||||||
n_button.strokeWidth = 0;
|
n_button.strokeWidth = 0;
|
||||||
if(button.getBoolean("isRound")) { n_button.cornerRadius = 35f; }
|
if (button.getBoolean("isRound")) {
|
||||||
|
n_button.cornerRadius = 35f;
|
||||||
|
}
|
||||||
int next_idx = 0;
|
int next_idx = 0;
|
||||||
if(button.getBoolean("holdShift")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT; next_idx++; }
|
if (button.getBoolean("holdShift")) {
|
||||||
if(button.getBoolean("holdCtrl")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL; next_idx++; }
|
keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT;
|
||||||
if(button.getBoolean("holdAlt")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_ALT; next_idx++; }
|
next_idx++;
|
||||||
|
}
|
||||||
|
if (button.getBoolean("holdCtrl")) {
|
||||||
|
keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL;
|
||||||
|
next_idx++;
|
||||||
|
}
|
||||||
|
if (button.getBoolean("holdAlt")) {
|
||||||
|
keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_ALT;
|
||||||
|
next_idx++;
|
||||||
|
}
|
||||||
keycodes[next_idx] = button.getInt("keycode");
|
keycodes[next_idx] = button.getInt("keycode");
|
||||||
n_button.keycodes = keycodes;
|
n_button.keycodes = keycodes;
|
||||||
empty.mControlDataList.add(n_button);
|
empty.mControlDataList.add(n_button);
|
||||||
}
|
}
|
||||||
empty.scaledAt = (float)oldLayoutJson.getDouble("scaledAt");
|
empty.scaledAt = (float) oldLayoutJson.getDouble("scaledAt");
|
||||||
empty.version = 3;
|
empty.version = 3;
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the layout stroke width to the V5 form
|
||||||
|
*/
|
||||||
|
private static void convertStrokeWidth(CustomControls layout) {
|
||||||
|
for (ControlData data : layout.mControlDataList) {
|
||||||
|
data.strokeWidth = Tools.pxToDp(computeStrokeWidth(data.strokeWidth, data.getWidth(), data.getHeight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ControlDrawerData data : layout.mDrawerDataList) {
|
||||||
|
data.properties.strokeWidth = Tools.pxToDp(computeStrokeWidth(data.properties.strokeWidth, data.properties.getWidth(), data.properties.getHeight()));
|
||||||
|
for (ControlData subButtonData : data.buttonProperties) {
|
||||||
|
subButtonData.strokeWidth = Tools.pxToDp(computeStrokeWidth(subButtonData.strokeWidth, data.properties.getWidth(), data.properties.getWidth()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a size percentage into a px size, used by older layout versions
|
||||||
|
*/
|
||||||
|
static int computeStrokeWidth(float widthInPercent, float width, float height) {
|
||||||
|
float maxSize = Math.max(width, height);
|
||||||
|
return (int) ((maxSize / 2) * (widthInPercent / 100));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,27 +30,37 @@ import org.lwjgl.glfw.CallbackBridge;
|
|||||||
public interface ControlInterface extends View.OnLongClickListener, GrabListener {
|
public interface ControlInterface extends View.OnLongClickListener, GrabListener {
|
||||||
|
|
||||||
View getControlView();
|
View getControlView();
|
||||||
|
|
||||||
ControlData getProperties();
|
ControlData getProperties();
|
||||||
|
|
||||||
/** Remove the button presence from the CustomControl object
|
default void setProperties(ControlData properties) {
|
||||||
|
setProperties(properties, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the button presence from the CustomControl object
|
||||||
* You need to use {getControlParent()} for this.
|
* You need to use {getControlParent()} for this.
|
||||||
*/
|
*/
|
||||||
void removeButton();
|
void removeButton();
|
||||||
|
|
||||||
/** Duplicate the data of the button and add a view with the duplicated data
|
/**
|
||||||
|
* Duplicate the data of the button and add a view with the duplicated data
|
||||||
* Relies on the ControlLayout for the implementation.
|
* Relies on the ControlLayout for the implementation.
|
||||||
*/
|
*/
|
||||||
void cloneButton();
|
void cloneButton();
|
||||||
|
|
||||||
void setVisible(boolean isVisible);
|
void setVisible(boolean isVisible);
|
||||||
|
|
||||||
void sendKeyPresses(boolean isDown);
|
void sendKeyPresses(boolean isDown);
|
||||||
|
|
||||||
/** Load the values and hide non useful forms */
|
/**
|
||||||
|
* Load the values and hide non useful forms
|
||||||
|
*/
|
||||||
void loadEditValues(EditControlPopup editControlPopup);
|
void loadEditValues(EditControlPopup editControlPopup);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void onGrabState(boolean isGrabbing) {
|
default void onGrabState(boolean isGrabbing) {
|
||||||
if(getControlLayoutParent() != null && getControlLayoutParent().getModifiable()) return; // Disable when edited
|
if (getControlLayoutParent() != null && getControlLayoutParent().getModifiable()) return; // Disable when edited
|
||||||
setVisible((getProperties().displayInGame && isGrabbing) || (getProperties().displayInMenu && !isGrabbing));
|
setVisible((getProperties().displayInGame && isGrabbing) || (getProperties().displayInMenu && !isGrabbing));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,8 +68,10 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
return (ControlLayout) getControlView().getParent();
|
return (ControlLayout) getControlView().getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Apply conversion steps for when the view is created */
|
/**
|
||||||
default ControlData preProcessProperties(ControlData properties, ControlLayout layout){
|
* Apply conversion steps for when the view is created
|
||||||
|
*/
|
||||||
|
default ControlData preProcessProperties(ControlData properties, ControlLayout layout) {
|
||||||
//Size
|
//Size
|
||||||
properties.setWidth(properties.getWidth() / layout.getLayoutScale() * PREF_BUTTONSIZE);
|
properties.setWidth(properties.getWidth() / layout.getLayoutScale() * PREF_BUTTONSIZE);
|
||||||
properties.setHeight(properties.getHeight() / layout.getLayoutScale() * PREF_BUTTONSIZE);
|
properties.setHeight(properties.getHeight() / layout.getLayoutScale() * PREF_BUTTONSIZE);
|
||||||
@ -74,10 +86,6 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
setProperties(getProperties());
|
setProperties(getProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setProperties(ControlData properties) {
|
|
||||||
setProperties(properties, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function should be overridden to store the properties */
|
/* This function should be overridden to store the properties */
|
||||||
@CallSuper
|
@CallSuper
|
||||||
default void setProperties(ControlData properties, boolean changePos) {
|
default void setProperties(ControlData properties, boolean changePos) {
|
||||||
@ -88,19 +96,22 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
|
|
||||||
// Recycle layout params
|
// Recycle layout params
|
||||||
ViewGroup.LayoutParams params = getControlView().getLayoutParams();
|
ViewGroup.LayoutParams params = getControlView().getLayoutParams();
|
||||||
if(params == null) params = new FrameLayout.LayoutParams((int) properties.getWidth(), (int) properties.getHeight());
|
if (params == null)
|
||||||
|
params = new FrameLayout.LayoutParams((int) properties.getWidth(), (int) properties.getHeight());
|
||||||
params.width = (int) properties.getWidth();
|
params.width = (int) properties.getWidth();
|
||||||
params.height = (int) properties.getHeight();
|
params.height = (int) properties.getHeight();
|
||||||
getControlView().setLayoutParams(params);
|
getControlView().setLayoutParams(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Apply the background according to properties */
|
/**
|
||||||
default void setBackground(){
|
* Apply the background according to properties
|
||||||
GradientDrawable gd = getControlView().getBackground() instanceof GradientDrawable
|
*/
|
||||||
|
default void setBackground() {
|
||||||
|
GradientDrawable gd = getControlView().getBackground() instanceof GradientDrawable
|
||||||
? (GradientDrawable) getControlView().getBackground()
|
? (GradientDrawable) getControlView().getBackground()
|
||||||
: new GradientDrawable();
|
: new GradientDrawable();
|
||||||
gd.setColor(getProperties().bgColor);
|
gd.setColor(getProperties().bgColor);
|
||||||
gd.setStroke(computeStrokeWidth(getProperties().strokeWidth), getProperties().strokeColor);
|
gd.setStroke((int) Tools.dpToPx(getProperties().strokeWidth), getProperties().strokeColor);
|
||||||
gd.setCornerRadius(computeCornerRadius(getProperties().cornerRadius));
|
gd.setCornerRadius(computeCornerRadius(getProperties().cornerRadius));
|
||||||
|
|
||||||
getControlView().setBackground(gd);
|
getControlView().setBackground(gd);
|
||||||
@ -108,50 +119,56 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the dynamic equation on the x axis.
|
* Apply the dynamic equation on the x axis.
|
||||||
|
*
|
||||||
* @param dynamicX The equation to compute the position from
|
* @param dynamicX The equation to compute the position from
|
||||||
*/
|
*/
|
||||||
default void setDynamicX(String dynamicX){
|
default void setDynamicX(String dynamicX) {
|
||||||
getProperties().dynamicX = dynamicX;
|
getProperties().dynamicX = dynamicX;
|
||||||
getControlView().setX(getProperties().insertDynamicPos(dynamicX));
|
getControlView().setX(getProperties().insertDynamicPos(dynamicX));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the dynamic equation on the y axis.
|
* Apply the dynamic equation on the y axis.
|
||||||
|
*
|
||||||
* @param dynamicY The equation to compute the position from
|
* @param dynamicY The equation to compute the position from
|
||||||
*/
|
*/
|
||||||
default void setDynamicY(String dynamicY){
|
default void setDynamicY(String dynamicY) {
|
||||||
getProperties().dynamicY = dynamicY;
|
getProperties().dynamicY = dynamicY;
|
||||||
getControlView().setY(getProperties().insertDynamicPos(dynamicY));
|
getControlView().setY(getProperties().insertDynamicPos(dynamicY));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a dynamic equation from an absolute position, used to scale properly across devices
|
* Generate a dynamic equation from an absolute position, used to scale properly across devices
|
||||||
|
*
|
||||||
* @param x The absolute position on the horizontal axis
|
* @param x The absolute position on the horizontal axis
|
||||||
* @return The equation as a String
|
* @return The equation as a String
|
||||||
*/
|
*/
|
||||||
default String generateDynamicX(float x){
|
default String generateDynamicX(float x) {
|
||||||
if(x + (getProperties().getWidth()/2f) > CallbackBridge.physicalWidth/2f){
|
if (x + (getProperties().getWidth() / 2f) > CallbackBridge.physicalWidth / 2f) {
|
||||||
return (x + getProperties().getWidth()) / CallbackBridge.physicalWidth + " * ${screen_width} - ${width}";
|
return (x + getProperties().getWidth()) / CallbackBridge.physicalWidth + " * ${screen_width} - ${width}";
|
||||||
}else{
|
} else {
|
||||||
return x / CallbackBridge.physicalWidth + " * ${screen_width}";
|
return x / CallbackBridge.physicalWidth + " * ${screen_width}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a dynamic equation from an absolute position, used to scale properly across devices
|
* Generate a dynamic equation from an absolute position, used to scale properly across devices
|
||||||
|
*
|
||||||
* @param y The absolute position on the vertical axis
|
* @param y The absolute position on the vertical axis
|
||||||
* @return The equation as a String
|
* @return The equation as a String
|
||||||
*/
|
*/
|
||||||
default String generateDynamicY(float y){
|
default String generateDynamicY(float y) {
|
||||||
if(y + (getProperties().getHeight()/2f) > CallbackBridge.physicalHeight/2f){
|
if (y + (getProperties().getHeight() / 2f) > CallbackBridge.physicalHeight / 2f) {
|
||||||
return (y + getProperties().getHeight()) / CallbackBridge.physicalHeight + " * ${screen_height} - ${height}";
|
return (y + getProperties().getHeight()) / CallbackBridge.physicalHeight + " * ${screen_height} - ${height}";
|
||||||
}else{
|
} else {
|
||||||
return y / CallbackBridge.physicalHeight + " * ${screen_height}";
|
return y / CallbackBridge.physicalHeight + " * ${screen_height}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Regenerate and apply coordinates with supposedly modified properties */
|
/**
|
||||||
default void regenerateDynamicCoordinates(){
|
* Regenerate and apply coordinates with supposedly modified properties
|
||||||
|
*/
|
||||||
|
default void regenerateDynamicCoordinates() {
|
||||||
getProperties().dynamicX = generateDynamicX(getControlView().getX());
|
getProperties().dynamicX = generateDynamicX(getControlView().getX());
|
||||||
getProperties().dynamicY = generateDynamicY(getControlView().getY());
|
getProperties().dynamicY = generateDynamicY(getControlView().getY());
|
||||||
updateProperties();
|
updateProperties();
|
||||||
@ -160,30 +177,28 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
/**
|
/**
|
||||||
* Do a pre-conversion of an equation using values from a button,
|
* Do a pre-conversion of an equation using values from a button,
|
||||||
* so the variables can be used for another button
|
* so the variables can be used for another button
|
||||||
*
|
* <p>
|
||||||
* Internal use only.
|
* Internal use only.
|
||||||
|
*
|
||||||
* @param equation The dynamic position as a String
|
* @param equation The dynamic position as a String
|
||||||
* @param button The button to get the values from.
|
* @param button The button to get the values from.
|
||||||
* @return The pre-processed equation as a String.
|
* @return The pre-processed equation as a String.
|
||||||
*/
|
*/
|
||||||
default String applySize(String equation, ControlInterface button){
|
default String applySize(String equation, ControlInterface button) {
|
||||||
return equation
|
return equation
|
||||||
.replace("${right}", "(${screen_width} - ${width})")
|
.replace("${right}", "(${screen_width} - ${width})")
|
||||||
.replace("${bottom}","(${screen_height} - ${height})")
|
.replace("${bottom}", "(${screen_height} - ${height})")
|
||||||
.replace("${height}", "(px(" + Tools.pxToDp(button.getProperties().getHeight()) + ") /" + PREF_BUTTONSIZE + " * ${preferred_scale})")
|
.replace("${height}", "(px(" + Tools.pxToDp(button.getProperties().getHeight()) + ") /" + PREF_BUTTONSIZE + " * ${preferred_scale})")
|
||||||
.replace("${width}", "(px(" + Tools.pxToDp(button.getProperties().getWidth()) + ") / " + PREF_BUTTONSIZE + " * ${preferred_scale})");
|
.replace("${width}", "(px(" + Tools.pxToDp(button.getProperties().getWidth()) + ") / " + PREF_BUTTONSIZE + " * ${preferred_scale})");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Convert a size percentage into a px size */
|
|
||||||
default int computeStrokeWidth(float widthInPercent){
|
|
||||||
float maxSize = Math.max(getProperties().getWidth(), getProperties().getHeight());
|
|
||||||
return (int)((maxSize/2) * (widthInPercent/100));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Convert a corner radius percentage into a px corner radius */
|
/**
|
||||||
default float computeCornerRadius(float radiusInPercent){
|
* Convert a corner radius percentage into a px corner radius
|
||||||
|
*/
|
||||||
|
default float computeCornerRadius(float radiusInPercent) {
|
||||||
float minSize = Math.min(getProperties().getWidth(), getProperties().getHeight());
|
float minSize = Math.min(getProperties().getWidth(), getProperties().getHeight());
|
||||||
return (minSize/2) * (radiusInPercent/100);
|
return (minSize / 2) * (radiusInPercent / 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,10 +208,10 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
* @return whether or not the button
|
* @return whether or not the button
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||||
default boolean canSnap(ControlInterface button){
|
default boolean canSnap(ControlInterface button) {
|
||||||
float MIN_DISTANCE = Tools.dpToPx(8);
|
float MIN_DISTANCE = Tools.dpToPx(8);
|
||||||
|
|
||||||
if(button == this) return false;
|
if (button == this) return false;
|
||||||
return !(net.kdt.pojavlaunch.utils.MathUtils.dist(
|
return !(net.kdt.pojavlaunch.utils.MathUtils.dist(
|
||||||
button.getControlView().getX() + button.getControlView().getWidth() / 2f,
|
button.getControlView().getX() + button.getControlView().getWidth() / 2f,
|
||||||
button.getControlView().getY() + button.getControlView().getHeight() / 2f,
|
button.getControlView().getY() + button.getControlView().getHeight() / 2f,
|
||||||
@ -210,13 +225,13 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
* Try to snap, then align to neighboring buttons, given the provided coordinates.
|
* Try to snap, then align to neighboring buttons, given the provided coordinates.
|
||||||
* The new position is automatically applied to the View,
|
* The new position is automatically applied to the View,
|
||||||
* regardless of if the View snapped or not.
|
* regardless of if the View snapped or not.
|
||||||
*
|
* <p>
|
||||||
* The new position is always dynamic, thus replacing previous dynamic positions
|
* The new position is always dynamic, thus replacing previous dynamic positions
|
||||||
*
|
*
|
||||||
* @param x Coordinate on the x axis
|
* @param x Coordinate on the x axis
|
||||||
* @param y Coordinate on the y axis
|
* @param y Coordinate on the y axis
|
||||||
*/
|
*/
|
||||||
default void snapAndAlign(float x, float y){
|
default void snapAndAlign(float x, float y) {
|
||||||
float MIN_DISTANCE = Tools.dpToPx(8);
|
float MIN_DISTANCE = Tools.dpToPx(8);
|
||||||
String dynamicX = generateDynamicX(x);
|
String dynamicX = generateDynamicX(x);
|
||||||
String dynamicY = generateDynamicY(y);
|
String dynamicY = generateDynamicY(y);
|
||||||
@ -224,9 +239,9 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
getControlView().setX(x);
|
getControlView().setX(x);
|
||||||
getControlView().setY(y);
|
getControlView().setY(y);
|
||||||
|
|
||||||
for(ControlInterface button : ((ControlLayout) getControlView().getParent()).getButtonChildren()){
|
for (ControlInterface button : ((ControlLayout) getControlView().getParent()).getButtonChildren()) {
|
||||||
//Step 1: Filter unwanted buttons
|
//Step 1: Filter unwanted buttons
|
||||||
if(!canSnap(button)) continue;
|
if (!canSnap(button)) continue;
|
||||||
|
|
||||||
//Step 2: Get Coordinates
|
//Step 2: Get Coordinates
|
||||||
float button_top = button.getControlView().getY();
|
float button_top = button.getControlView().getY();
|
||||||
@ -240,28 +255,28 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
float right = getControlView().getX() + getControlView().getWidth();
|
float right = getControlView().getX() + getControlView().getWidth();
|
||||||
|
|
||||||
//Step 3: For each axis, we try to snap to the nearest
|
//Step 3: For each axis, we try to snap to the nearest
|
||||||
if(Math.abs(top - button_bottom) < MIN_DISTANCE){ // Bottom snap
|
if (Math.abs(top - button_bottom) < MIN_DISTANCE) { // Bottom snap
|
||||||
dynamicY = applySize(button.getProperties().dynamicY, button) + applySize(" + ${height}", button) + " + ${margin}" ;
|
dynamicY = applySize(button.getProperties().dynamicY, button) + applySize(" + ${height}", button) + " + ${margin}";
|
||||||
}else if(Math.abs(button_top - bottom) < MIN_DISTANCE){ //Top snap
|
} else if (Math.abs(button_top - bottom) < MIN_DISTANCE) { //Top snap
|
||||||
dynamicY = applySize(button.getProperties().dynamicY, button) + " - ${height} - ${margin}";
|
dynamicY = applySize(button.getProperties().dynamicY, button) + " - ${height} - ${margin}";
|
||||||
}
|
}
|
||||||
if(!dynamicY.equals(generateDynamicY(getControlView().getY()))){ //If we snapped
|
if (!dynamicY.equals(generateDynamicY(getControlView().getY()))) { //If we snapped
|
||||||
if(Math.abs(button_left - left) < MIN_DISTANCE){ //Left align snap
|
if (Math.abs(button_left - left) < MIN_DISTANCE) { //Left align snap
|
||||||
dynamicX = applySize(button.getProperties().dynamicX, button);
|
dynamicX = applySize(button.getProperties().dynamicX, button);
|
||||||
}else if(Math.abs(button_right - right) < MIN_DISTANCE){ //Right align snap
|
} else if (Math.abs(button_right - right) < MIN_DISTANCE) { //Right align snap
|
||||||
dynamicX = applySize(button.getProperties().dynamicX, button) + applySize(" + ${width}", button) + " - ${width}";
|
dynamicX = applySize(button.getProperties().dynamicX, button) + applySize(" + ${width}", button) + " - ${width}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Math.abs(button_left - right) < MIN_DISTANCE){ //Left snap
|
if (Math.abs(button_left - right) < MIN_DISTANCE) { //Left snap
|
||||||
dynamicX = applySize(button.getProperties().dynamicX, button) + " - ${width} - ${margin}";
|
dynamicX = applySize(button.getProperties().dynamicX, button) + " - ${width} - ${margin}";
|
||||||
}else if(Math.abs(left - button_right) < MIN_DISTANCE){ //Right snap
|
} else if (Math.abs(left - button_right) < MIN_DISTANCE) { //Right snap
|
||||||
dynamicX = applySize(button.getProperties().dynamicX, button) + applySize(" + ${width}", button) + " + ${margin}";
|
dynamicX = applySize(button.getProperties().dynamicX, button) + applySize(" + ${width}", button) + " + ${margin}";
|
||||||
}
|
}
|
||||||
if(!dynamicX.equals(generateDynamicX(getControlView().getX()))){ //If we snapped
|
if (!dynamicX.equals(generateDynamicX(getControlView().getX()))) { //If we snapped
|
||||||
if(Math.abs(button_top - top) < MIN_DISTANCE){ //Top align snap
|
if (Math.abs(button_top - top) < MIN_DISTANCE) { //Top align snap
|
||||||
dynamicY = applySize(button.getProperties().dynamicY, button);
|
dynamicY = applySize(button.getProperties().dynamicY, button);
|
||||||
}else if(Math.abs(button_bottom - bottom) < MIN_DISTANCE){ //Bottom align snap
|
} else if (Math.abs(button_bottom - bottom) < MIN_DISTANCE) { //Bottom align snap
|
||||||
dynamicY = applySize(button.getProperties().dynamicY, button) + applySize(" + ${height}", button) + " - ${height}";
|
dynamicY = applySize(button.getProperties().dynamicY, button) + applySize(" + ${height}", button) + " - ${height}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,17 +287,21 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
setDynamicY(dynamicY);
|
setDynamicY(dynamicY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Wrapper for multiple injections at once */
|
/**
|
||||||
default void injectBehaviors(){
|
* Wrapper for multiple injections at once
|
||||||
|
*/
|
||||||
|
default void injectBehaviors() {
|
||||||
injectProperties();
|
injectProperties();
|
||||||
injectTouchEventBehavior();
|
injectTouchEventBehavior();
|
||||||
injectLayoutParamBehavior();
|
injectLayoutParamBehavior();
|
||||||
injectGrabListenerBehavior();
|
injectGrabListenerBehavior();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Inject the grab listener, remove it when the view is gone */
|
/**
|
||||||
default void injectGrabListenerBehavior(){
|
* Inject the grab listener, remove it when the view is gone
|
||||||
if(getControlView() == null){
|
*/
|
||||||
|
default void injectGrabListenerBehavior() {
|
||||||
|
if (getControlView() == null) {
|
||||||
Log.e(ControlInterface.class.toString(), "Failed to inject grab listener behavior !");
|
Log.e(ControlInterface.class.toString(), "Failed to inject grab listener behavior !");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -304,12 +323,14 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void injectProperties(){
|
default void injectProperties() {
|
||||||
getControlView().post(() -> getControlView().setTranslationZ(10));
|
getControlView().post(() -> getControlView().setTranslationZ(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Inject a touch listener on the view to make editing controls straight forward */
|
/**
|
||||||
default void injectTouchEventBehavior(){
|
* Inject a touch listener on the view to make editing controls straight forward
|
||||||
|
*/
|
||||||
|
default void injectTouchEventBehavior() {
|
||||||
getControlView().setOnTouchListener(new View.OnTouchListener() {
|
getControlView().setOnTouchListener(new View.OnTouchListener() {
|
||||||
private boolean mCanTriggerLongClick = true;
|
private boolean mCanTriggerLongClick = true;
|
||||||
private float downX, downY;
|
private float downX, downY;
|
||||||
@ -318,7 +339,7 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View view, MotionEvent event) {
|
public boolean onTouch(View view, MotionEvent event) {
|
||||||
if(!getControlLayoutParent().getModifiable()){
|
if (!getControlLayoutParent().getModifiable()) {
|
||||||
// Basically, editing behavior is forced while in game behavior is specific
|
// Basically, editing behavior is forced while in game behavior is specific
|
||||||
view.onTouchEvent(event);
|
view.onTouchEvent(event);
|
||||||
return true;
|
return true;
|
||||||
@ -342,7 +363,7 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
case MotionEvent.ACTION_MOVE:
|
||||||
if(Math.abs(event.getRawX() - downRawX) > 8 || Math.abs(event.getRawY() - downRawY) > 8)
|
if (Math.abs(event.getRawX() - downRawX) > 8 || Math.abs(event.getRawY() - downRawY) > 8)
|
||||||
mCanTriggerLongClick = false;
|
mCanTriggerLongClick = false;
|
||||||
getControlLayoutParent().adaptPanelPosition();
|
getControlLayoutParent().adaptPanelPosition();
|
||||||
|
|
||||||
@ -360,17 +381,17 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
default void injectLayoutParamBehavior(){
|
default void injectLayoutParamBehavior() {
|
||||||
getControlView().addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
|
getControlView().addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
|
||||||
getProperties().setWidth(right-left);
|
getProperties().setWidth(right - left);
|
||||||
getProperties().setHeight(bottom-top);
|
getProperties().setHeight(bottom - top);
|
||||||
setBackground();
|
setBackground();
|
||||||
|
|
||||||
// Re-calculate position
|
// Re-calculate position
|
||||||
if(!getProperties().isDynamicBtn){
|
if (!getProperties().isDynamicBtn) {
|
||||||
getControlView().setX(getControlView().getX());
|
getControlView().setX(getControlView().getX());
|
||||||
getControlView().setY(getControlView().getY());
|
getControlView().setY(getControlView().getY());
|
||||||
}else {
|
} else {
|
||||||
getControlView().setX(getProperties().insertDynamicPos(getProperties().dynamicX));
|
getControlView().setX(getProperties().insertDynamicPos(getProperties().dynamicX));
|
||||||
getControlView().setY(getProperties().insertDynamicPos(getProperties().dynamicY));
|
getControlView().setY(getProperties().insertDynamicPos(getProperties().dynamicY));
|
||||||
}
|
}
|
||||||
@ -378,7 +399,7 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default boolean onLongClick(View v){
|
default boolean onLongClick(View v) {
|
||||||
if (getControlLayoutParent().getModifiable()) {
|
if (getControlLayoutParent().getModifiable()) {
|
||||||
getControlLayoutParent().editControlButton(this);
|
getControlLayoutParent().editControlButton(this);
|
||||||
getControlLayoutParent().mActionRow.setFollowedButton(this);
|
getControlLayoutParent().mActionRow.setFollowedButton(this);
|
||||||
|
@ -26,26 +26,28 @@ import io.github.controlwear.virtual.joystick.android.JoystickView;
|
|||||||
|
|
||||||
@SuppressLint("ViewConstructor")
|
@SuppressLint("ViewConstructor")
|
||||||
public class ControlJoystick extends JoystickView implements ControlInterface {
|
public class ControlJoystick extends JoystickView implements ControlInterface {
|
||||||
public ControlJoystick(ControlLayout parent, ControlData data) {
|
|
||||||
super(parent.getContext());
|
|
||||||
init(data, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public final static int DIRECTION_FORWARD_LOCK = 8;
|
public final static int DIRECTION_FORWARD_LOCK = 8;
|
||||||
|
|
||||||
private ControlData mControlData;
|
|
||||||
private int mLastDirectionInt = GamepadJoystick.DIRECTION_NONE;
|
|
||||||
private int mCurrentDirectionInt = GamepadJoystick.DIRECTION_NONE;
|
|
||||||
|
|
||||||
// Directions keycode
|
// Directions keycode
|
||||||
private final int[] mDirectionForwardLock = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL};
|
private final int[] mDirectionForwardLock = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL};
|
||||||
private final int[] mDirectionForward = new int[]{LwjglGlfwKeycode.GLFW_KEY_W};
|
private final int[] mDirectionForward = new int[]{LwjglGlfwKeycode.GLFW_KEY_W};
|
||||||
private final int[] mDirectionRight = new int[]{LwjglGlfwKeycode.GLFW_KEY_D};
|
private final int[] mDirectionRight = new int[]{LwjglGlfwKeycode.GLFW_KEY_D};
|
||||||
private final int[] mDirectionBackward = new int[]{LwjglGlfwKeycode.GLFW_KEY_S};
|
private final int[] mDirectionBackward = new int[]{LwjglGlfwKeycode.GLFW_KEY_S};
|
||||||
private final int[] mDirectionLeft = new int[]{LwjglGlfwKeycode.GLFW_KEY_A};
|
private final int[] mDirectionLeft = new int[]{LwjglGlfwKeycode.GLFW_KEY_A};
|
||||||
|
private ControlData mControlData;
|
||||||
|
private int mLastDirectionInt = GamepadJoystick.DIRECTION_NONE;
|
||||||
|
private int mCurrentDirectionInt = GamepadJoystick.DIRECTION_NONE;
|
||||||
|
public ControlJoystick(ControlLayout parent, ControlData data) {
|
||||||
|
super(parent.getContext());
|
||||||
|
init(data, parent);
|
||||||
|
}
|
||||||
|
|
||||||
private void init(ControlData data, ControlLayout layout){
|
private static void sendInput(int[] keys, boolean isDown) {
|
||||||
|
for (int key : keys) {
|
||||||
|
CallbackBridge.sendKeyPress(key, CallbackBridge.getCurrentMods(), isDown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(ControlData data, ControlLayout layout) {
|
||||||
mControlData = data;
|
mControlData = data;
|
||||||
setProperties(preProcessProperties(data, layout));
|
setProperties(preProcessProperties(data, layout));
|
||||||
setDeadzone(35);
|
setDeadzone(35);
|
||||||
@ -61,7 +63,7 @@ public class ControlJoystick extends JoystickView implements ControlInterface {
|
|||||||
mLastDirectionInt = mCurrentDirectionInt;
|
mLastDirectionInt = mCurrentDirectionInt;
|
||||||
mCurrentDirectionInt = getDirectionInt(angle, strength);
|
mCurrentDirectionInt = getDirectionInt(angle, strength);
|
||||||
|
|
||||||
if(mLastDirectionInt != mCurrentDirectionInt){
|
if (mLastDirectionInt != mCurrentDirectionInt) {
|
||||||
sendDirectionalKeycode(mLastDirectionInt, false);
|
sendDirectionalKeycode(mLastDirectionInt, false);
|
||||||
sendDirectionalKeycode(mCurrentDirectionInt, true);
|
sendDirectionalKeycode(mCurrentDirectionInt, true);
|
||||||
}
|
}
|
||||||
@ -75,7 +77,9 @@ public class ControlJoystick extends JoystickView implements ControlInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getControlView() {return this;}
|
public View getControlView() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControlData getProperties() {
|
public ControlData getProperties() {
|
||||||
@ -107,7 +111,7 @@ public class ControlJoystick extends JoystickView implements ControlInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBackground() {
|
public void setBackground() {
|
||||||
setBorderWidth(computeStrokeWidth(getProperties().strokeWidth));
|
setBorderWidth((int) Tools.dpToPx(getProperties().strokeWidth));
|
||||||
setBorderColor(getProperties().strokeColor);
|
setBorderColor(getProperties().strokeColor);
|
||||||
setBackgroundColor(getProperties().bgColor);
|
setBackgroundColor(getProperties().bgColor);
|
||||||
}
|
}
|
||||||
@ -120,13 +124,13 @@ public class ControlJoystick extends JoystickView implements ControlInterface {
|
|||||||
editControlPopup.loadJoystickValues(mControlData);
|
editControlPopup.loadJoystickValues(mControlData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getDirectionInt(int angle, int intensity){
|
private int getDirectionInt(int angle, int intensity) {
|
||||||
if(intensity == 0) return DIRECTION_NONE;
|
if (intensity == 0) return DIRECTION_NONE;
|
||||||
return (int) (((angle+22.5)/45) % 8);
|
return (int) (((angle + 22.5) / 45) % 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendDirectionalKeycode(int direction, boolean isDown){
|
private void sendDirectionalKeycode(int direction, boolean isDown) {
|
||||||
switch (direction){
|
switch (direction) {
|
||||||
case DIRECTION_NORTH:
|
case DIRECTION_NORTH:
|
||||||
sendInput(mDirectionForward, isDown);
|
sendInput(mDirectionForward, isDown);
|
||||||
break;
|
break;
|
||||||
@ -161,10 +165,4 @@ public class ControlJoystick extends JoystickView implements ControlInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendInput(int[] keys, boolean isDown){
|
|
||||||
for(int key : keys){
|
|
||||||
CallbackBridge.sendKeyPress(key, CallbackBridge.getCurrentMods(), isDown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -269,11 +269,11 @@ public class EditControlPopup {
|
|||||||
mHeightEditText.setText(String.valueOf(data.getHeight()));
|
mHeightEditText.setText(String.valueOf(data.getHeight()));
|
||||||
|
|
||||||
mAlphaSeekbar.setProgress((int) (data.opacity * 100));
|
mAlphaSeekbar.setProgress((int) (data.opacity * 100));
|
||||||
mStrokeWidthSeekbar.setProgress(data.strokeWidth);
|
mStrokeWidthSeekbar.setProgress((int) data.strokeWidth * 10);
|
||||||
mCornerRadiusSeekbar.setProgress((int) data.cornerRadius);
|
mCornerRadiusSeekbar.setProgress((int) data.cornerRadius);
|
||||||
|
|
||||||
setPercentageText(mAlphaPercentTextView, (int) (data.opacity * 100));
|
setPercentageText(mAlphaPercentTextView, (int) (data.opacity * 100));
|
||||||
setPercentageText(mStrokePercentTextView, data.strokeWidth);
|
setPercentageText(mStrokePercentTextView, (int) data.strokeWidth * 10);
|
||||||
setPercentageText(mCornerRadiusPercentTextView, (int) data.cornerRadius);
|
setPercentageText(mCornerRadiusPercentTextView, (int) data.cornerRadius);
|
||||||
|
|
||||||
mToggleSwitch.setChecked(data.isToggle);
|
mToggleSwitch.setChecked(data.isToggle);
|
||||||
@ -498,7 +498,7 @@ public class EditControlPopup {
|
|||||||
@Override
|
@Override
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
if (internalChanges) return;
|
if (internalChanges) return;
|
||||||
mCurrentlyEditedButton.getProperties().strokeWidth = mStrokeWidthSeekbar.getProgress();
|
mCurrentlyEditedButton.getProperties().strokeWidth = mStrokeWidthSeekbar.getProgress() / 10F;
|
||||||
mCurrentlyEditedButton.setBackground();
|
mCurrentlyEditedButton.setBackground();
|
||||||
setPercentageText(mStrokePercentTextView, progress);
|
setPercentageText(mStrokePercentTextView, progress);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user