Closed Kurtoid closed 1 year ago
Two questions for the maintainers: 1) how is widget data stored? Do I need to do anything to save the checkbox state? 2) what do I need to do to make the stick re-draw itself when the checkbox changes? Right now, the stick only changes it's border once its touched, triggering a re-draw.
Two questions for the maintainers:
- how is widget data stored? Do I need to do anything to save the checkbox state?
- what do I need to do to make the stick re-draw itself when the checkbox changes? Right now, the stick only changes it's border once its touched, triggering a re-draw.
Thanks for your contribution!
To answer your questions:
You did everything that was necessary. All variables in the JoystickEntity class or general WidgetEntity will automatically be saved to the storage and loaded from the last state.
Since it is not updating on its own, you can try to force a redraw by calling "forceWidgetUpdate" from the ViewHolder class like in BatteryViewHolder.
Maybe two suggestions to discuss about the widget update:
What do you think?
(sorry for the commit spam - should I squash it?) I changed it to "Use Rectangular Stick Limits" - but if it should be worded differently, go for it.
Thank you for the advice on re-drawing the widget. It looks like forceSetChecked
in BatteryDetailVH (and now JoystickDetailVH) prevents some kind of update loop?
Right now, making the Joy widget rectangular (width != height) in rectangular mode causes some graphics weirdness. In the original circular mode, the circle diameter is constrained to min(height, width). Should I try fixing the stick boundary checks in that case, or just force the joystick area to be square instead?
It looks like forceSetChecked in BatteryDetailVH (and now JoystickDetailVH) prevents some kind of update loop? Yep, right!
I think its okay if its rectangular, so you have to limit the stick movement to your new boundary. Until now - good work!
To restrict the stick movement I would differentiate between circle and rectangular boundaries in the "pixel to whatever" conversions like this:
private float[] convertFromPxToRelative(float x, float y) {
float middleX = getWidth() / 2f;
float middleY = getHeight() / 2f;
float[] relPos = new float[2];
float dx = x - middleX;
float dy = y - middleY;
if (rectangular) {
float maxW = middleX - joystickRadius;
float maxH = middleY - joystickRadius;
relPos[0] = Math.min(1, Math.max(-1, dx / maxW));
relPos[1] = Math.min(1, Math.max(-1, -dy / maxH));
} else {
float r = middleX - joystickRadius;
double rad = Math.atan2(dy, dx);
double len = Math.sqrt(dx * dx + dy * dy) / r;
len = Math.min(1, len);
relPos[0] = (float) (Math.cos(rad) * len);
relPos[1] = (float) (-Math.sin(rad) * len);
}
return relPos;
}
and the other way around:
private float[] convertFromRelativeToPx(float x, float y) {
float middleX = getWidth() / 2f;
float middleY = getHeight() / 2f;
float[] px = new float[2];
if (rectangular) {
float maxW = middleX - joystickRadius;
float maxH = middleY - joystickRadius;
px[0] = middleX + x * maxW;
px[1] = middleY - y * maxH;
} else {
float r = middleX - joystickRadius;
px[0] = middleX + x * r;
px[1] = middleY - y * r;
}
return px;
}
Adds a checkbox, "Use Realistic Stick Limits", to the joystick widget. It's checked by default, keeping the default behavior the same, where the joystick areas is a circle, and the corners can't be reached. When unchecked, the boundaries of the virtual joystick change to a square (or rectangle, if the width/height are not equal), making the corners reachable.
The new checkbox:
Joystick in square/rect mode:
Joystick in realistic mode: