Feat[controls]: Add conditional visibility

This commit is contained in:
Mathias-Boulay 2023-05-15 20:38:59 +02:00 committed by ArtDev
parent aed6c00c40
commit 58a29ee2ca
5 changed files with 94 additions and 8 deletions

View File

@ -100,6 +100,9 @@ public class ControlData {
public float cornerRadius; //0-100% public float cornerRadius; //0-100%
public boolean isSwipeable; public boolean isSwipeable;
public boolean displayInGame;
public boolean displayInMenu;
public ControlData() { public ControlData() {
this("button"); this("button");
} }
@ -142,10 +145,10 @@ public class ControlData {
} }
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); 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) { 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) {
this.name = name; this.name = name;
this.keycodes = inflateKeycodeArray(keycodes); this.keycodes = inflateKeycodeArray(keycodes);
this.dynamicX = dynamicX; this.dynamicX = dynamicX;
@ -159,6 +162,8 @@ public class ControlData {
this.strokeColor = strokeColor; this.strokeColor = strokeColor;
this.strokeWidth = strokeWidth; this.strokeWidth = strokeWidth;
this.cornerRadius = cornerRadius; this.cornerRadius = cornerRadius;
this.displayInGame = displayInGame;
this.displayInMenu = displayInMenu;
} }
//Deep copy constructor //Deep copy constructor
@ -175,7 +180,9 @@ public class ControlData {
controlData.bgColor, controlData.bgColor,
controlData.strokeColor, controlData.strokeColor,
controlData.strokeWidth, controlData.strokeWidth,
controlData.cornerRadius controlData.cornerRadius,
controlData.displayInGame,
controlData.displayInMenu
); );
} }

View File

@ -247,6 +247,12 @@ public class ControlLayout extends FrameLayout {
removeEditWindow(); removeEditWindow();
} }
mModifiable = isModifiable; mModifiable = isModifiable;
if(isModifiable){
// In edit mode, all controls have to be shown
for(ControlInterface button : getButtonChildren()){
button.setVisible(true);
}
}
} }
public boolean getModifiable(){ public boolean getModifiable(){

View File

@ -4,14 +4,17 @@ import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_BUTTONSIZE;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.CallSuper; import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.core.math.MathUtils; import androidx.core.math.MathUtils;
import net.kdt.pojavlaunch.GrabListener;
import net.kdt.pojavlaunch.Tools; import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.customcontrols.ControlData; import net.kdt.pojavlaunch.customcontrols.ControlData;
import net.kdt.pojavlaunch.customcontrols.ControlLayout; import net.kdt.pojavlaunch.customcontrols.ControlLayout;
@ -24,7 +27,7 @@ import org.lwjgl.glfw.CallbackBridge;
* Most of the injected behavior is editing behavior, * Most of the injected behavior is editing behavior,
* sending keys has to be implemented by sub classes. * sending keys has to be implemented by sub classes.
*/ */
public interface ControlInterface extends View.OnLongClickListener { public interface ControlInterface extends View.OnLongClickListener, GrabListener {
View getControlView(); View getControlView();
ControlData getProperties(); ControlData getProperties();
@ -45,8 +48,13 @@ public interface ControlInterface extends View.OnLongClickListener {
/** 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
default void onGrabState(boolean isGrabbing) {
if(getControlLayoutParent() != null && getControlLayoutParent().getModifiable()) return; // Disable when edited
setVisible((getProperties().displayInGame && isGrabbing) || (getProperties().displayInMenu && !isGrabbing));
}
default ControlLayout getControlLayoutParent(){ default ControlLayout getControlLayoutParent() {
return (ControlLayout) getControlView().getParent(); return (ControlLayout) getControlView().getParent();
} }
@ -269,6 +277,31 @@ public interface ControlInterface extends View.OnLongClickListener {
injectProperties(); injectProperties();
injectTouchEventBehavior(); injectTouchEventBehavior();
injectLayoutParamBehavior(); injectLayoutParamBehavior();
injectGrabListenerBehavior();
}
/** Inject the grab listener, remove it when the view is gone */
default void injectGrabListenerBehavior(){
if(getControlView() == null){
Log.e(ControlInterface.class.toString(), "Failed to inject grab listener behavior !");
return;
}
getControlView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(@NonNull View v) {
CallbackBridge.addGrabListener(ControlInterface.this);
}
@Override
public void onViewDetachedFromWindow(@NonNull View v) {
getControlView().removeOnAttachStateChangeListener(this);
CallbackBridge.removeGrabListener(ControlInterface.this);
}
});
} }
default void injectProperties(){ default void injectProperties(){

View File

@ -19,6 +19,8 @@ import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText; import android.widget.EditText;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.Spinner; import android.widget.Spinner;
@ -84,6 +86,7 @@ public class EditControlPopup {
protected TextView mSelectBackgroundColor, mSelectStrokeColor; protected TextView mSelectBackgroundColor, mSelectStrokeColor;
protected ArrayAdapter<String> mAdapter; protected ArrayAdapter<String> mAdapter;
protected List<String> mSpecialArray; protected List<String> mSpecialArray;
protected CheckBox mDisplayInGameCheckbox, mDisplayInMenuCheckbox;
// Decorative textviews // Decorative textviews
private TextView mOrientationTextView, mMappingTextView, mNameTextView, mCornerRadiusTextView; private TextView mOrientationTextView, mMappingTextView, mNameTextView, mCornerRadiusTextView;
@ -269,6 +272,9 @@ public class EditControlPopup {
mPassthroughSwitch.setChecked(data.passThruEnabled); mPassthroughSwitch.setChecked(data.passThruEnabled);
mSwipeableSwitch.setChecked(data.isSwipeable); mSwipeableSwitch.setChecked(data.isSwipeable);
mDisplayInGameCheckbox.setChecked(data.displayInGame);
mDisplayInMenuCheckbox.setChecked(data.displayInMenu);
for(int i = 0; i< data.keycodes.length; i++){ for(int i = 0; i< data.keycodes.length; i++){
if (data.keycodes[i] < 0) { if (data.keycodes[i] < 0) {
mKeycodeSpinners[i].setSelection(data.keycodes[i] + mSpecialArray.size()); mKeycodeSpinners[i].setSelection(data.keycodes[i] + mSpecialArray.size());
@ -343,6 +349,8 @@ public class EditControlPopup {
mStrokePercentTextView = mScrollView.findViewById(R.id.editStrokeWidth_textView_percent); mStrokePercentTextView = mScrollView.findViewById(R.id.editStrokeWidth_textView_percent);
mAlphaPercentTextView = mScrollView.findViewById(R.id.editButtonOpacity_textView_percent); mAlphaPercentTextView = mScrollView.findViewById(R.id.editButtonOpacity_textView_percent);
mCornerRadiusPercentTextView = mScrollView.findViewById(R.id.editCornerRadius_textView_percent); mCornerRadiusPercentTextView = mScrollView.findViewById(R.id.editCornerRadius_textView_percent);
mDisplayInGameCheckbox = mScrollView.findViewById(R.id.visibility_game_checkbox);
mDisplayInMenuCheckbox = mScrollView.findViewById(R.id.visibility_menu_checkbox);
//Decorative stuff //Decorative stuff
mMappingTextView = mScrollView.findViewById(R.id.editMapping_textView); mMappingTextView = mScrollView.findViewById(R.id.editMapping_textView);
@ -504,6 +512,15 @@ public class EditControlPopup {
public void onNothingSelected(AdapterView<?> parent) {} public void onNothingSelected(AdapterView<?> parent) {}
}); });
mDisplayInGameCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(internalChanges) return;
mCurrentlyEditedButton.getProperties().displayInGame = isChecked;
});
mDisplayInMenuCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(internalChanges) return;
mCurrentlyEditedButton.getProperties().displayInMenu = isChecked;
});
mSelectStrokeColor.setOnClickListener(v -> { mSelectStrokeColor.setOnClickListener(v -> {
mColorSelector.setAlphaEnabled(false); mColorSelector.setAlphaEnabled(false);

View File

@ -220,7 +220,7 @@
<Switch <Switch
android:id="@+id/checkboxToggle" android:id="@+id/checkboxToggle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="30dp" android:layout_height="wrap_content"
android:text="@string/customctrl_toggle" android:text="@string/customctrl_toggle"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -373,8 +373,6 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="30dp" android:layout_height="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/editButtonOpacity_textView" /> app:layout_constraintTop_toBottomOf="@id/editButtonOpacity_textView" />
@ -390,6 +388,31 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/editButtonOpacity_textView" /> app:layout_constraintTop_toTopOf="@id/editButtonOpacity_textView" />
<!-- Button visibility -->
<TextView
android:id="@+id/visibility_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Visibility"
app:layout_constraintTop_toBottomOf="@+id/editButtonOpacity_seekbar"
tools:layout_editor_absoluteX="6dp" />
<CheckBox
android:id="@+id/visibility_game_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="In game"
app:layout_constraintTop_toBottomOf="@+id/visibility_textview"
/>
<CheckBox
android:id="@+id/visibility_menu_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="In Menu"
app:layout_constraintTop_toBottomOf="@+id/visibility_game_checkbox"
/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>