Skip to content

Commit

Permalink
Add change screen gamepad: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielBRDeveloper committed Jan 2, 2024
1 parent 49ab77c commit 0811e17
Show file tree
Hide file tree
Showing 30 changed files with 1,023 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,22 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {

try {
Class<?> clazz = getClassLoader().loadClass(intent.getStringExtra(Constants.ACTIVITY_PARAMETER_FRAGMENT));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, (Fragment) clazz.newInstance()).commitNow();
Fragment fragment = (Fragment) clazz.newInstance();
fragment.setArguments(intent.getExtras());
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commitNow();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static void launch(Context context, Class<? extends Fragment> clazz) {
launch(context, clazz, new Intent());
}

public static void launch(Context context, Class<? extends Fragment> clazz, Intent extras) {
context.startActivity(new Intent(context, PreferenceActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtras(extras)
.putExtra(Constants.ACTIVITY_PARAMETER_FRAGMENT, clazz.getName()));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.panda3ds.pandroid.app.base;

import android.content.Context;
import android.view.Gravity;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.LinearLayoutCompat;

import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.lang.Function;

public class BottomAlertDialog extends AlertDialog.Builder {
private final LinearLayoutCompat layoutCompat;

public BottomAlertDialog(@NonNull Context context) {
super(context, R.style.AlertDialog);
layoutCompat = new LinearLayoutCompat(context);
layoutCompat.setOrientation(LinearLayoutCompat.VERTICAL);

int padding = getContext().getResources().getDimensionPixelSize(androidx.appcompat.R.dimen.abc_dialog_padding_material);
layoutCompat.setPadding(padding, 0, padding, 0);

setView(layoutCompat);
}

@NonNull
@Override
public AlertDialog create() {
AlertDialog dialog = super.create();
dialog.getWindow().setGravity(Gravity.BOTTOM | Gravity.CENTER);
dialog.getWindow().getAttributes().y = Math.round(getContext().getResources().getDisplayMetrics().density * 15);
return dialog;
}

public BottomAlertDialog setTextInput(String hint, Function<String> listener) {
AppCompatEditText edit = new AppCompatEditText(getContext());
edit.setHint(hint);
int margin = layoutCompat.getPaddingLeft() / 2;
LinearLayoutCompat.LayoutParams params = new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0, margin, 0, margin);
layoutCompat.addView(edit, params);
setPositiveButton(android.R.string.ok, (dialog, which) -> listener.run(String.valueOf(edit.getText())));
setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss());
return this;
}

@Override
public AlertDialog show() {
AlertDialog dialog = create();
dialog.show();
return dialog;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.app.PreferenceActivity;
import com.panda3ds.pandroid.app.base.BasePreferenceFragment;
import com.panda3ds.pandroid.app.preferences.InputMapPreferences;
import com.panda3ds.pandroid.app.preferences.AppearancePreferences;
import com.panda3ds.pandroid.app.preferences.InputPreferences;

public class SettingsFragment extends BasePreferenceFragment {
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
setPreferencesFromResource(R.xml.start_preferences, rootKey);
setItemClick("inputMap", (item) -> PreferenceActivity.launch(requireContext(), InputMapPreferences.class));
setItemClick("input", (item) -> PreferenceActivity.launch(requireContext(), InputPreferences.class));
setItemClick("appearance", (item)-> PreferenceActivity.launch(requireContext(), AppearancePreferences.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.panda3ds.pandroid.app.preferences;

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.app.BaseActivity;
import com.panda3ds.pandroid.app.base.BottomAlertDialog;
import com.panda3ds.pandroid.view.controller.map.ControllerMapper;
import com.panda3ds.pandroid.view.controller.map.ControllerProfileManager;
import com.panda3ds.pandroid.view.controller.map.NodeID;
import com.panda3ds.pandroid.view.controller.map.Profile;

public class ControllerMapperPreferences extends Fragment {

private Profile currentProfile;
private ControllerMapper mapper;
private View saveButton;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.preference_controller_mapper, container, false);
}


@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);


currentProfile = ControllerProfileManager.get(getArguments().getString("profile")).clone();

((BaseActivity) requireActivity()).getSupportActionBar().hide();
mapper = view.findViewById(R.id.mapper);
mapper.initialize(this::onLocationChanged, currentProfile);

view.findViewById(R.id.change_visibility).setOnClickListener(v -> {
BottomAlertDialog builder = new BottomAlertDialog(v.getContext());
builder.setTitle("Visibility");
boolean[] visibleList = {
currentProfile.isVisible(NodeID.START),
currentProfile.isVisible(NodeID.SELECT),
currentProfile.isVisible(NodeID.L),
currentProfile.isVisible(NodeID.R),
currentProfile.isVisible(NodeID.DPAD),
currentProfile.isVisible(NodeID.JOYSTICK),
currentProfile.isVisible(NodeID.GAMEPAD),
};
builder.setMultiChoiceItems(new CharSequence[]{
"Start", "Select", "L", "R", "Dpad", getString(R.string.axis), "A/B/X/Y"
}, visibleList, (dialog, index, visibility) -> {
visibleList[index] = visibility;
}).setPositiveButton(android.R.string.ok, (dialog, which) -> {

saveButton.setVisibility(View.VISIBLE);

currentProfile.setVisible(NodeID.START, visibleList[0]);
currentProfile.setVisible(NodeID.SELECT, visibleList[1]);
currentProfile.setVisible(NodeID.L, visibleList[2]);
currentProfile.setVisible(NodeID.R, visibleList[3]);
currentProfile.setVisible(NodeID.DPAD, visibleList[4]);
currentProfile.setVisible(NodeID.JOYSTICK, visibleList[5]);
currentProfile.setVisible(NodeID.GAMEPAD, visibleList[6]);

mapper.refreshLayout();
}).setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss());
builder.show();
});

saveButton = view.findViewById(R.id.save);
saveButton.setOnClickListener(v -> {
ControllerProfileManager.add(currentProfile);
Toast.makeText(v.getContext(), R.string.saved, Toast.LENGTH_SHORT).show();
requireActivity().finish();
});

view.findViewById(R.id.delete).setOnClickListener(v -> {
ControllerProfileManager.remove(currentProfile.getId());
requireActivity().finish();
});

view.findViewById(R.id.rotate).setOnClickListener(v->{
requireActivity().setRequestedOrientation(mapper.getCurrentWidth() > mapper.getCurrentHeight() ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
});

view.findViewById(R.id.delete).setVisibility(ControllerProfileManager.getProfileCount() > 1 ? View.VISIBLE : View.GONE);

saveButton.setVisibility(View.GONE);
}

public void onLocationChanged(NodeID id) {
saveButton.setVisibility(View.VISIBLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.panda3ds.pandroid.app.preferences;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;

import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.app.BaseActivity;
import com.panda3ds.pandroid.app.PreferenceActivity;
import com.panda3ds.pandroid.app.base.BasePreferenceFragment;
import com.panda3ds.pandroid.app.base.BottomAlertDialog;
import com.panda3ds.pandroid.view.controller.map.ControllerProfileManager;
import com.panda3ds.pandroid.view.controller.map.Profile;

import java.util.List;
import java.util.Objects;

public class InputPreferences extends BasePreferenceFragment {
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
setPreferencesFromResource(R.xml.input_preference, rootKey);
setItemClick("inputMap", (item) -> PreferenceActivity.launch(requireContext(), InputMapPreferences.class));
setItemClick("add_screen_profile", (item) -> {
new BottomAlertDialog(requireContext())
.setTextInput(getString(R.string.name), (name) -> {
name = formatName(name);
if (name.length() > 0) {
Profile profile = ControllerProfileManager.makeDefaultProfile();
profile.setName(name);
ControllerProfileManager.add(profile);
refreshScreenProfileList();
}
}).setTitle(R.string.create_profile).show();
});

setItemClick("defaultControllerProfile", (item)->{
List<Profile> profiles = ControllerProfileManager.listAll();
String defaultProfileId = ControllerProfileManager.getDefaultProfile().getId();
int defaultProfileIndex = 0;
CharSequence[] names = new CharSequence[profiles.size()];
for (int i = 0; i < names.length; i++){
names[i] = profiles.get(i).getName();
if (Objects.equals(profiles.get(i).getId(), defaultProfileId)){
defaultProfileIndex = i;
}
}
new BottomAlertDialog(item.getContext())
.setSingleChoiceItems(names, defaultProfileIndex, (dialog, which) -> {
dialog.dismiss();
ControllerProfileManager.setDefaultId(profiles.get(which).getId());
item.setSummary(profiles.get(which).getName());
}).setTitle(R.string.pref_default_controller_title).show();
});

((BaseActivity)requireActivity()).getSupportActionBar().setTitle(R.string.input);
}


@Override
public void onResume() {
super.onResume();
refresh();
}

public String formatName(String name) {
name = String.valueOf(name);
while (name.startsWith(" ")) {
name = name.substring(1);
}
while (name.endsWith(" ")) {
name = name.substring(0, name.length() - 1);
}
name = name.replaceAll("\\s\\s", " ");
return name;
}

private void refresh() {
findPreference("defaultControllerProfile").setSummary(ControllerProfileManager.getDefaultProfile().getName());
refreshScreenProfileList();
}

@SuppressLint("RestrictedApi")
private void refreshScreenProfileList() {
PreferenceCategory category = findPreference("screenGamepadProfiles");
Preference add = category.getPreference(category.getPreferenceCount() - 1);
category.removeAll();
category.setOrderingAsAdded(true);

for (Profile profile : ControllerProfileManager.listAll()) {
Preference item = new Preference(category.getContext());
item.setOnPreferenceClickListener(preference -> {
category.performClick();
PreferenceActivity.launch(requireActivity(), ControllerMapperPreferences.class, new Intent().putExtra("profile", profile.getId()));
return false;
});
item.setOrder(category.getPreferenceCount());
item.setIconSpaceReserved(false);
item.setTitle(profile.getName());
category.addPreference(item);
}

add.setOrder(category.getPreferenceCount());
category.addPreference(add);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ public class Constants {
public static final String PREF_GLOBAL_CONFIG = "app.GlobalConfig";
public static final String PREF_GAME_UTILS = "app.GameUtils";
public static final String PREF_INPUT_MAP = "app.InputMap";
public static final String PREF_SCREEN_CONTROLLER_PROFILES = "app.input.overlay";
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@
import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.utils.Constants;
import com.panda3ds.pandroid.view.controller.ControllerLayout;
import com.panda3ds.pandroid.view.controller.map.ControllerProfileManager;
import com.panda3ds.pandroid.view.controller.map.NodeID;
import com.panda3ds.pandroid.view.controller.map.Profile;
import com.panda3ds.pandroid.view.controller.nodes.Button;
import com.panda3ds.pandroid.view.controller.nodes.Joystick;

public class PandaLayoutController extends ControllerLayout {

private int width = -1;
private int height = -1;

public PandaLayoutController(Context context) { super(context); }
public PandaLayoutController(Context context, AttributeSet attrs) { super(context, attrs); }
public PandaLayoutController(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
Expand Down Expand Up @@ -44,5 +51,29 @@ public void initialize() {
});

refreshChildren();
measure(MeasureSpec.EXACTLY, MeasureSpec.EXACTLY);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredWidth = getMeasuredWidth();
int measuredHeight = getMeasuredHeight();
if (measuredWidth != width || measuredHeight != height){
width = measuredWidth;
height = measuredHeight;
applyProfileMap();
}
}

private void applyProfileMap() {
Profile profile = ControllerProfileManager.getDefaultProfile();
profile.applyToView(NodeID.L,findViewById(R.id.button_l), width, height);
profile.applyToView(NodeID.R, findViewById(R.id.button_r), width, height);
profile.applyToView(NodeID.START, findViewById(R.id.button_start), width, height);
profile.applyToView(NodeID.SELECT, findViewById(R.id.button_select), width, height);
profile.applyToView(NodeID.JOYSTICK, findViewById(R.id.left_analog), width, height);
profile.applyToView(NodeID.GAMEPAD, findViewById(R.id.gamepad), width, height);
profile.applyToView(NodeID.DPAD, findViewById(R.id.dpad), width, height);
}
}
Loading

0 comments on commit 0811e17

Please sign in to comment.