mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 22:55:40 +12:00
Android cleanup and bugfixing
This commit is contained in:
parent
02496b57eb
commit
914193a765
34 changed files with 153 additions and 332 deletions
|
@ -30,7 +30,8 @@ public class BaseActivity extends AppCompatActivity {
|
||||||
private void applyTheme() {
|
private void applyTheme() {
|
||||||
currentTheme = PandroidApplication.getThemeId();
|
currentTheme = PandroidApplication.getThemeId();
|
||||||
setTheme(currentTheme);
|
setTheme(currentTheme);
|
||||||
if (GlobalConfig.get(GlobalConfig.KEY_APP_THEME) == GlobalConfig.THEME_ANDROID){
|
|
||||||
|
if (GlobalConfig.get(GlobalConfig.KEY_APP_THEME) == GlobalConfig.THEME_ANDROID) {
|
||||||
DynamicColors.applyToActivityIfAvailable(this);
|
DynamicColors.applyToActivityIfAvailable(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class GameActivity extends BaseActivity implements EmulatorCallback {
|
||||||
swapScreens(GlobalConfig.get(GlobalConfig.KEY_CURRENT_DS_LAYOUT));
|
swapScreens(GlobalConfig.get(GlobalConfig.KEY_CURRENT_DS_LAYOUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeOverlayVisibility(boolean visible){
|
private void changeOverlayVisibility(boolean visible) {
|
||||||
findViewById(R.id.overlay_controller).setVisibility(visible ? View.VISIBLE : View.GONE);
|
findViewById(R.id.overlay_controller).setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||||
findViewById(R.id.overlay_controller).invalidate();
|
findViewById(R.id.overlay_controller).invalidate();
|
||||||
findViewById(R.id.overlay_controller).requestLayout();
|
findViewById(R.id.overlay_controller).requestLayout();
|
||||||
|
@ -95,13 +95,14 @@ public class GameActivity extends BaseActivity implements EmulatorCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void goToPictureInPicture() {
|
private void enablePIP() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();
|
PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
builder.setAutoEnterEnabled(true);
|
builder.setAutoEnterEnabled(true);
|
||||||
builder.setSeamlessResizeEnabled(true);
|
builder.setSeamlessResizeEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setAspectRatio(new Rational(10, 14));
|
builder.setAspectRatio(new Rational(10, 14));
|
||||||
enterPictureInPictureMode(builder.build());
|
enterPictureInPictureMode(builder.build());
|
||||||
}
|
}
|
||||||
|
@ -114,7 +115,7 @@ public class GameActivity extends BaseActivity implements EmulatorCallback {
|
||||||
InputHandler.reset();
|
InputHandler.reset();
|
||||||
if (GlobalConfig.get(GlobalConfig.KEY_PICTURE_IN_PICTURE)) {
|
if (GlobalConfig.get(GlobalConfig.KEY_PICTURE_IN_PICTURE)) {
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
|
||||||
goToPictureInPicture();
|
enablePIP();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
drawerFragment.open();
|
drawerFragment.open();
|
||||||
|
@ -142,7 +143,7 @@ public class GameActivity extends BaseActivity implements EmulatorCallback {
|
||||||
@Override
|
@Override
|
||||||
public void swapScreens(int index) {
|
public void swapScreens(int index) {
|
||||||
currentDsLayout = index;
|
currentDsLayout = index;
|
||||||
GlobalConfig.set(GlobalConfig.KEY_CURRENT_DS_LAYOUT,index);
|
GlobalConfig.set(GlobalConfig.KEY_CURRENT_DS_LAYOUT, index);
|
||||||
renderer.setLayout(DsLayoutManager.createLayout(currentDsLayout));
|
renderer.setLayout(DsLayoutManager.createLayout(currentDsLayout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,11 +159,13 @@ public class GameActivity extends BaseActivity implements EmulatorCallback {
|
||||||
@Override
|
@Override
|
||||||
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
|
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
|
||||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
|
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
|
||||||
|
|
||||||
changeOverlayVisibility(!isInPictureInPictureMode && GlobalConfig.get(GlobalConfig.KEY_SCREEN_GAMEPAD_VISIBLE));
|
changeOverlayVisibility(!isInPictureInPictureMode && GlobalConfig.get(GlobalConfig.KEY_SCREEN_GAMEPAD_VISIBLE));
|
||||||
findViewById(R.id.hide_screen_controller).setVisibility(isInPictureInPictureMode ? View.INVISIBLE : View.VISIBLE);
|
findViewById(R.id.hide_screen_controller).setVisibility(isInPictureInPictureMode ? View.INVISIBLE : View.VISIBLE);
|
||||||
if (isInPictureInPictureMode){
|
|
||||||
|
if (isInPictureInPictureMode) {
|
||||||
getWindow().getDecorView().postDelayed(drawerFragment::close, 250);
|
getWindow().getDecorView().postDelayed(drawerFragment::close, 250);
|
||||||
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S){
|
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
ActivityManager manager = ((ActivityManager) getSystemService(ACTIVITY_SERVICE));
|
ActivityManager manager = ((ActivityManager) getSystemService(ACTIVITY_SERVICE));
|
||||||
manager.getAppTasks().forEach(ActivityManager.AppTask::moveToFront);
|
manager.getAppTasks().forEach(ActivityManager.AppTask::moveToFront);
|
||||||
}
|
}
|
||||||
|
@ -173,6 +176,7 @@ public class GameActivity extends BaseActivity implements EmulatorCallback {
|
||||||
if (AlberDriver.HasRomLoaded()) {
|
if (AlberDriver.HasRomLoaded()) {
|
||||||
AlberDriver.Finalize();
|
AlberDriver.Finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,12 @@ public class MainActivity extends BaseActivity implements NavigationBarView.OnIt
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (navigationBar.getSelectedItemId() != R.id.games){
|
if (navigationBar.getSelectedItemId() != R.id.games) {
|
||||||
navigationBar.setSelectedItemId(R.id.games);
|
navigationBar.setSelectedItemId(R.id.games);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setSwitchValue(String id, boolean value){
|
protected void setSwitchValue(String id, boolean value) {
|
||||||
((SwitchPreferenceCompat)findPreference(id)).setChecked(value);
|
((SwitchPreferenceCompat)findPreference(id)).setChecked(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,15 @@ public class BaseSheetDialog extends BottomSheetDialog {
|
||||||
private final LinearLayout contentView;
|
private final LinearLayout contentView;
|
||||||
public BaseSheetDialog(@NonNull Context context) {
|
public BaseSheetDialog(@NonNull Context context) {
|
||||||
super(CompatUtils.findActivity(context));
|
super(CompatUtils.findActivity(context));
|
||||||
|
|
||||||
int width = CompatUtils.findActivity(context).getWindow().getDecorView().getMeasuredWidth();
|
int width = CompatUtils.findActivity(context).getWindow().getDecorView().getMeasuredWidth();
|
||||||
int height = CompatUtils.findActivity(context).getWindow().getDecorView().getMeasuredHeight();
|
int height = CompatUtils.findActivity(context).getWindow().getDecorView().getMeasuredHeight();
|
||||||
getBehavior().setPeekHeight((int) (height*0.87));
|
float heightScale = 0.87f; // What percentage of the screen's height to use up
|
||||||
|
|
||||||
|
getBehavior().setPeekHeight((int) (height * heightScale));
|
||||||
|
getBehavior().setMaxHeight((int) (height * heightScale));
|
||||||
getBehavior().setMaxWidth(width);
|
getBehavior().setMaxWidth(width);
|
||||||
getBehavior().setMaxHeight((int) (height*0.87));
|
|
||||||
super.setContentView(R.layout.dialog_bottom_sheet);
|
super.setContentView(R.layout.dialog_bottom_sheet);
|
||||||
contentView = super.findViewById(R.id.content);
|
contentView = super.findViewById(R.id.content);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,14 +61,16 @@ public class GameAboutDialog extends BaseSheetDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make a shortcut for a specific game
|
||||||
private void makeShortcut() {
|
private void makeShortcut() {
|
||||||
Context context = CompatUtils.findActivity(getContext());
|
Context context = CompatUtils.findActivity(getContext());
|
||||||
ShortcutInfoCompat.Builder shortcut = new ShortcutInfoCompat.Builder(context, game.getId());
|
ShortcutInfoCompat.Builder shortcut = new ShortcutInfoCompat.Builder(context, game.getId());
|
||||||
if (game.getIcon() != null){
|
if (game.getIcon() != null) {
|
||||||
shortcut.setIcon(IconCompat.createWithAdaptiveBitmap(game.getIcon()));
|
shortcut.setIcon(IconCompat.createWithAdaptiveBitmap(game.getIcon()));
|
||||||
} else {
|
} else {
|
||||||
shortcut.setIcon(IconCompat.createWithResource(getContext(), R.mipmap.ic_launcher));
|
shortcut.setIcon(IconCompat.createWithResource(getContext(), R.mipmap.ic_launcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
shortcut.setActivity(new ComponentName(context, GameLauncher.class));
|
shortcut.setActivity(new ComponentName(context, GameLauncher.class));
|
||||||
shortcut.setLongLabel(game.getTitle());
|
shortcut.setLongLabel(game.getTitle());
|
||||||
shortcut.setShortLabel(game.getTitle());
|
shortcut.setShortLabel(game.getTitle());
|
||||||
|
@ -76,6 +78,6 @@ public class GameAboutDialog extends BaseSheetDialog {
|
||||||
intent.setAction(Intent.ACTION_VIEW);
|
intent.setAction(Intent.ACTION_VIEW);
|
||||||
intent.setData(new Uri.Builder().scheme("pandroid-game").authority(game.getId()).build());
|
intent.setData(new Uri.Builder().scheme("pandroid-game").authority(game.getId()).build());
|
||||||
shortcut.setIntent(intent);
|
shortcut.setIntent(intent);
|
||||||
ShortcutManagerCompat.requestPinShortcut(context,shortcut.build(),null);
|
ShortcutManagerCompat.requestPinShortcut(context, shortcut.build(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import com.panda3ds.pandroid.R;
|
||||||
public class LoadingAlertDialog extends BottomAlertDialog {
|
public class LoadingAlertDialog extends BottomAlertDialog {
|
||||||
public LoadingAlertDialog(@NonNull Context context, @StringRes int title) {
|
public LoadingAlertDialog(@NonNull Context context, @StringRes int title) {
|
||||||
super(context);
|
super(context);
|
||||||
View view = LayoutInflater.from(context).inflate(R.layout.dialog_loading,null, false);
|
View view = LayoutInflater.from(context).inflate(R.layout.dialog_loading, null, false);
|
||||||
setView(view);
|
setView(view);
|
||||||
setCancelable(false);
|
setCancelable(false);
|
||||||
((AppCompatTextView)view.findViewById(R.id.title))
|
((AppCompatTextView)view.findViewById(R.id.title))
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class AlberInputListener implements Function<InputEvent> {
|
||||||
axisChanged = true;
|
axisChanged = true;
|
||||||
break;
|
break;
|
||||||
case CHANGE_DS_LAYOUT:
|
case CHANGE_DS_LAYOUT:
|
||||||
if (!event.isDown()){
|
if (!event.isDown()) {
|
||||||
emulator.swapScreens();
|
emulator.swapScreens();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class DrawerFragment extends Fragment implements DrawerLayout.DrawerListe
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh(){
|
private void refresh() {
|
||||||
game = GameUtils.getCurrentGame();
|
game = GameUtils.getCurrentGame();
|
||||||
if (game.getIcon() != null && !game.getIcon().isRecycled()) {
|
if (game.getIcon() != null && !game.getIcon().isRecycled()) {
|
||||||
((GameIconView) drawerLayout.findViewById(R.id.game_icon)).setImageBitmap(game.getIcon());
|
((GameIconView) drawerLayout.findViewById(R.id.game_icon)).setImageBitmap(game.getIcon());
|
||||||
|
@ -61,7 +61,6 @@ public class DrawerFragment extends Fragment implements DrawerLayout.DrawerListe
|
||||||
}
|
}
|
||||||
((AppCompatTextView)drawerLayout.findViewById(R.id.game_title)).setText(game.getTitle());
|
((AppCompatTextView)drawerLayout.findViewById(R.id.game_title)).setText(game.getTitle());
|
||||||
((AppCompatTextView)drawerLayout.findViewById(R.id.game_publisher)).setText(game.getPublisher());
|
((AppCompatTextView)drawerLayout.findViewById(R.id.game_publisher)).setText(game.getPublisher());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,7 +5,8 @@ import com.panda3ds.pandroid.data.config.GlobalConfig;
|
||||||
public interface EmulatorCallback {
|
public interface EmulatorCallback {
|
||||||
void onBackPressed();
|
void onBackPressed();
|
||||||
void swapScreens(int index);
|
void swapScreens(int index);
|
||||||
|
|
||||||
default void swapScreens() {
|
default void swapScreens() {
|
||||||
swapScreens(GlobalConfig.get(GlobalConfig.KEY_CURRENT_DS_LAYOUT)+1);
|
swapScreens(GlobalConfig.get(GlobalConfig.KEY_CURRENT_DS_LAYOUT) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,17 +21,19 @@ public class GameLauncher extends BaseActivity {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(new TextView(this));
|
setContentView(new TextView(this));
|
||||||
Uri uri = getIntent().getData();
|
Uri uri = getIntent().getData();
|
||||||
if(uri != null && uri.getScheme().equals("pandroid-game")){
|
if (uri != null && uri.getScheme().equals("pandroid-game")) {
|
||||||
String gameId = uri.getAuthority();
|
String gameId = uri.getAuthority();
|
||||||
GameMetadata game = GameUtils.findGameById(gameId);
|
GameMetadata game = GameUtils.findGameById(gameId);
|
||||||
if (game != null){
|
|
||||||
|
if (game != null) {
|
||||||
GameUtils.launch(this, game);
|
GameUtils.launch(this, game);
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this, R.string.invalid_game,Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.invalid_game, Toast.LENGTH_LONG).show();
|
||||||
ShortcutManagerCompat.removeDynamicShortcuts(this, Arrays.asList(gameId));
|
ShortcutManagerCompat.removeDynamicShortcuts(this, Arrays.asList(gameId));
|
||||||
ShortcutManagerCompat.removeLongLivedShortcuts(this, Arrays.asList(gameId));
|
ShortcutManagerCompat.removeLongLivedShortcuts(this, Arrays.asList(gameId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ public class SettingsFragment extends BasePreferenceFragment {
|
||||||
try {
|
try {
|
||||||
Context context = PandroidApplication.getAppContext();
|
Context context = PandroidApplication.getAppContext();
|
||||||
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
|
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
|
||||||
} catch (Exception e){
|
} catch (Exception e) {
|
||||||
return "???";
|
return "Error: Unknown version";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,14 +51,14 @@ public class GamesFoldersPreferences extends BasePreferenceFragment implements A
|
||||||
screen.addPreference(preference);
|
screen.addPreference(preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
Preference add = new Preference(screen.getContext());
|
Preference pref = new Preference(screen.getContext());
|
||||||
add.setTitle(R.string.import_folder);
|
pref.setTitle(R.string.import_folder);
|
||||||
add.setIcon(R.drawable.ic_add);
|
pref.setIcon(R.drawable.ic_add);
|
||||||
add.setOnPreferenceClickListener(preference -> {
|
pref.setOnPreferenceClickListener(preference -> {
|
||||||
pickFolderRequest.launch(null);
|
pickFolderRequest.launch(null);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
screen.addPreference(add);
|
screen.addPreference(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFolderInfo(GamesFolder folder) {
|
private void showFolderInfo(GamesFolder folder) {
|
||||||
|
@ -83,6 +83,7 @@ public class GamesFoldersPreferences extends BasePreferenceFragment implements A
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|
||||||
if (pickFolderRequest != null) {
|
if (pickFolderRequest != null) {
|
||||||
pickFolderRequest.unregister();
|
pickFolderRequest.unregister();
|
||||||
pickFolderRequest = null;
|
pickFolderRequest = null;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class GeneralPreferences extends BasePreferenceFragment {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh(){
|
private void refresh() {
|
||||||
setSwitchValue("behavior.pictureInPicture", GlobalConfig.get(GlobalConfig.KEY_PICTURE_IN_PICTURE));
|
setSwitchValue("behavior.pictureInPicture", GlobalConfig.get(GlobalConfig.KEY_PICTURE_IN_PICTURE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class InputPreferences extends BasePreferenceFragment {
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
private void refreshScreenProfileList() {
|
private void refreshScreenProfileList() {
|
||||||
PreferenceCategory category = findPreference(ID_GAMEPAD_PROFILE_LIST);
|
PreferenceCategory category = findPreference(ID_GAMEPAD_PROFILE_LIST);
|
||||||
Preference add = category.getPreference(category.getPreferenceCount() - 1);
|
Preference pref = category.getPreference(category.getPreferenceCount() - 1);
|
||||||
category.removeAll();
|
category.removeAll();
|
||||||
category.setOrderingAsAdded(true);
|
category.setOrderingAsAdded(true);
|
||||||
|
|
||||||
|
@ -97,8 +97,8 @@ public class InputPreferences extends BasePreferenceFragment {
|
||||||
category.addPreference(item);
|
category.addPreference(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
add.setOrder(category.getPreferenceCount());
|
pref.setOrder(category.getPreferenceCount());
|
||||||
category.addPreference(add);
|
category.addPreference(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,13 +20,14 @@ public class ScreenLayoutsPreference extends BasePreferenceFragment {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh(){
|
public void refresh() {
|
||||||
PreferenceScreen screen = getPreferenceScreen();
|
PreferenceScreen screen = getPreferenceScreen();
|
||||||
screen.removeAll();
|
screen.removeAll();
|
||||||
for (int i = 0; i < DsLayoutManager.getLayoutCount(); i++){
|
|
||||||
|
for (int i = 0; i < DsLayoutManager.getLayoutCount(); i++) {
|
||||||
Preference pref = new Preference(getPreferenceScreen().getContext());
|
Preference pref = new Preference(getPreferenceScreen().getContext());
|
||||||
pref.setIconSpaceReserved(false);
|
pref.setIconSpaceReserved(false);
|
||||||
pref.setTitle("Layout "+(i+1));
|
pref.setTitle("Layout "+ (i + 1));
|
||||||
pref.setSummary(R.string.click_to_change);
|
pref.setSummary(R.string.click_to_change);
|
||||||
pref.setIcon(R.drawable.ic_edit);
|
pref.setIcon(R.drawable.ic_edit);
|
||||||
pref.setKey(String.valueOf(i));
|
pref.setKey(String.valueOf(i));
|
||||||
|
|
|
@ -79,6 +79,7 @@ public class AppDataDocumentProvider extends DocumentsProvider {
|
||||||
.add(Root.COLUMN_TITLE, context().getString(R.string.app_name))
|
.add(Root.COLUMN_TITLE, context().getString(R.string.app_name))
|
||||||
.add(Root.COLUMN_MIME_TYPES, "*/*")
|
.add(Root.COLUMN_MIME_TYPES, "*/*")
|
||||||
.add(Root.COLUMN_ICON, R.mipmap.ic_launcher);
|
.add(Root.COLUMN_ICON, R.mipmap.ic_launcher);
|
||||||
|
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +88,7 @@ public class AppDataDocumentProvider extends DocumentsProvider {
|
||||||
File file = obtainFile(documentId);
|
File file = obtainFile(documentId);
|
||||||
MatrixCursor cursor = new MatrixCursor(projection == null ? DEFAULT_DOCUMENT_PROJECTION : projection);
|
MatrixCursor cursor = new MatrixCursor(projection == null ? DEFAULT_DOCUMENT_PROJECTION : projection);
|
||||||
includeFile(cursor, file);
|
includeFile(cursor, file);
|
||||||
|
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,20 +127,20 @@ public class AppDataDocumentProvider extends DocumentsProvider {
|
||||||
public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException {
|
public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException {
|
||||||
File parent = obtainFile(parentDocumentId);
|
File parent = obtainFile(parentDocumentId);
|
||||||
File file = new File(parent, displayName);
|
File file = new File(parent, displayName);
|
||||||
if (!parent.exists()){
|
if (!parent.exists()) {
|
||||||
throw new FileNotFoundException("Parent don't exists");
|
throw new FileNotFoundException("Parent doesn't exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Objects.equals(mimeType, Document.MIME_TYPE_DIR)){
|
if (Objects.equals(mimeType, Document.MIME_TYPE_DIR)) {
|
||||||
if (!file.mkdirs()){
|
if (!file.mkdirs()) {
|
||||||
throw new FileNotFoundException("Error on create directory");
|
throw new FileNotFoundException("Error while creating directory");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (!file.createNewFile()){
|
if (!file.createNewFile()) {
|
||||||
throw new Exception("Error on create file");
|
throw new Exception("Error while creating file");
|
||||||
}
|
}
|
||||||
} catch (Exception e){
|
} catch (Exception e) {
|
||||||
throw new FileNotFoundException(e.getMessage());
|
throw new FileNotFoundException(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +150,7 @@ public class AppDataDocumentProvider extends DocumentsProvider {
|
||||||
@Override
|
@Override
|
||||||
public void deleteDocument(String documentId) throws FileNotFoundException {
|
public void deleteDocument(String documentId) throws FileNotFoundException {
|
||||||
File file = obtainFile(documentId);
|
File file = obtainFile(documentId);
|
||||||
if (file.exists()){
|
if (file.exists()) {
|
||||||
FileUtils.delete(file.getAbsolutePath());
|
FileUtils.delete(file.getAbsolutePath());
|
||||||
} else {
|
} else {
|
||||||
throw new FileNotFoundException("File not exists");
|
throw new FileNotFoundException("File not exists");
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class GsonConfigParser {
|
||||||
new Task(()->{
|
new Task(()->{
|
||||||
if (FileUtils.exists(getPath())) {
|
if (FileUtils.exists(getPath())) {
|
||||||
String src = FileUtils.readTextFile(getPath());
|
String src = FileUtils.readTextFile(getPath());
|
||||||
if(src != null && src.length() > 2){
|
if (src != null && src.length() > 2) {
|
||||||
content[0] = src;
|
content[0] = src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,17 +60,19 @@ public class GlobalConfig {
|
||||||
writeChanges();
|
writeChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Object> T getExtra(Key<String> key, Class<T> dataClass){
|
public static <T extends Object> T getExtra(Key<String> key, Class<T> dataClass) {
|
||||||
if (data.extras.has(key.name)){
|
if (data.extras.has(key.name)) {
|
||||||
return gson.fromJson(data.extras.getAsJsonObject(key.name), dataClass);
|
return gson.fromJson(data.extras.getAsJsonObject(key.name), dataClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gson.fromJson("{}", dataClass);
|
return gson.fromJson("{}", dataClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void putExtra(Key<String> key, Object value){
|
public static synchronized void putExtra(Key<String> key, Object value) {
|
||||||
if (data.extras.has(key.name)){
|
if (data.extras.has(key.name)) {
|
||||||
data.extras.remove(key.name);
|
data.extras.remove(key.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.extras.add(key.name, gson.toJsonTree(value));
|
data.extras.add(key.name, gson.toJsonTree(value));
|
||||||
writeChanges();
|
writeChanges();
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,9 +83,10 @@ public class GameMetadata {
|
||||||
this.title = smdh.getTitle();
|
this.title = smdh.getTitle();
|
||||||
this.publisher = smdh.getPublisher();
|
this.publisher = smdh.getPublisher();
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
if (icon != null){
|
if (icon != null) {
|
||||||
GameUtils.setGameIcon(id, icon);
|
GameUtils.setGameIcon(id, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.regions = new GameRegion[]{smdh.getRegion()};
|
this.regions = new GameRegion[]{smdh.getRegion()};
|
||||||
GameUtils.writeChanges();
|
GameUtils.writeChanges();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ public enum GameRegion {
|
||||||
Taiwan,
|
Taiwan,
|
||||||
None;
|
None;
|
||||||
|
|
||||||
public int localizedName(){
|
public int localizedName() {
|
||||||
switch (this){
|
switch (this) {
|
||||||
case NorthAmerican:
|
case NorthAmerican:
|
||||||
return R.string.region_north_armerican;
|
return R.string.region_north_armerican;
|
||||||
case Japan:
|
case Japan:
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GamesFolder {
|
public class GamesFolder {
|
||||||
|
|
||||||
private final String id = UUID.randomUUID().toString();
|
private final String id = UUID.randomUUID().toString();
|
||||||
private final String path;
|
private final String path;
|
||||||
private final HashMap<String, GameMetadata> games = new HashMap<>();
|
private final HashMap<String, GameMetadata> games = new HashMap<>();
|
||||||
|
@ -21,7 +20,7 @@ public class GamesFolder {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid(){
|
public boolean isValid() {
|
||||||
return FileUtils.exists(path);
|
return FileUtils.exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,22 +38,24 @@ public class GamesFolder {
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
String[] gamesId = games.keySet().toArray(new String[0]);
|
String[] gamesId = games.keySet().toArray(new String[0]);
|
||||||
for (String file: gamesId){
|
for (String file: gamesId) {
|
||||||
if (!FileUtils.exists(path+"/"+file)){
|
if (!FileUtils.exists(path + "/" + file)) {
|
||||||
games.remove(file);
|
games.remove(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String unknown = PandroidApplication.getAppContext().getString(R.string.unknown);
|
String unknown = PandroidApplication.getAppContext().getString(R.string.unknown);
|
||||||
|
|
||||||
for (String file: FileUtils.listFiles(path)){
|
for (String file: FileUtils.listFiles(path)) {
|
||||||
String path = FileUtils.getChild(this.path, file);
|
String path = FileUtils.getChild(this.path, file);
|
||||||
if (FileUtils.isDirectory(path) || games.containsKey(file)){
|
if (FileUtils.isDirectory(path) || games.containsKey(file)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ext = FileUtils.extension(path);
|
String ext = FileUtils.extension(path);
|
||||||
if (ext.equals("3ds") || ext.equals("3dsx")){
|
if (ext.equals("3ds") || ext.equals("3dsx") || ext.equals("cci") || ext.equals("cxi") || ext.equals("app") || ext.equals("ncch")) {
|
||||||
String name = FileUtils.getName(path).trim().split("\\.")[0];
|
String name = FileUtils.getName(path).trim().split("\\.")[0];
|
||||||
games.put(file, new GameMetadata(new Uri.Builder().path(file).authority(id).scheme("folder").build().toString(),name, unknown));
|
games.put(file, new GameMetadata(new Uri.Builder().path(file).authority(id).scheme("folder").build().toString(), name, unknown));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,13 +110,14 @@ public class InputHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String code = KeyEvent.keyCodeToString(event.getKeyCode());
|
String code = KeyEvent.keyCodeToString(event.getKeyCode());
|
||||||
if (event.getAction() == KeyEvent.ACTION_UP){
|
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
keyDownEvents.remove(code);
|
keyDownEvents.remove(code);
|
||||||
handleEvent(new InputEvent(code, 0.0f));
|
handleEvent(new InputEvent(code, 0.0f));
|
||||||
} else if (!keyDownEvents.containsKey(code)){
|
} else if (!keyDownEvents.containsKey(code)) {
|
||||||
keyDownEvents.put(code, new InputEvent(code, 1.0f));
|
keyDownEvents.put(code, new InputEvent(code, 1.0f));
|
||||||
}
|
}
|
||||||
for (InputEvent env: keyDownEvents.values()){
|
|
||||||
|
for (InputEvent env: keyDownEvents.values()) {
|
||||||
handleEvent(env);
|
handleEvent(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,21 +19,22 @@ public class CompatUtils {
|
||||||
} else if ((context instanceof ContextWrapper)) {
|
} else if ((context instanceof ContextWrapper)) {
|
||||||
return findActivity(((ContextWrapper) context).getBaseContext());
|
return findActivity(((ContextWrapper) context).getBaseContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((Activity) context);
|
return ((Activity) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int resolveColor(Context context, @AttrRes int id){
|
public static int resolveColor(Context context, @AttrRes int id) {
|
||||||
try {
|
try {
|
||||||
TypedArray values = context.obtainStyledAttributes(new int[]{id});
|
TypedArray values = context.obtainStyledAttributes(new int[]{id});
|
||||||
int color = values.getColor(0, Color.RED);
|
int color = values.getColor(0, Color.RED);
|
||||||
values.recycle();
|
values.recycle();
|
||||||
return color;
|
return color;
|
||||||
} catch (Exception e){
|
} catch (Exception e) {
|
||||||
return Color.rgb(255,0,255);
|
return Color.rgb(255,0,255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float applyDimen(int unit, int size) {
|
public static float applyDimensions(int unit, int size) {
|
||||||
return TypedValue.applyDimension(unit, size, PandroidApplication.getAppContext().getResources().getDisplayMetrics());
|
return TypedValue.applyDimension(unit, size, PandroidApplication.getAppContext().getResources().getDisplayMetrics());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,13 @@ public class FileUtils {
|
||||||
}
|
}
|
||||||
Uri uri = Uri.parse(path);
|
Uri uri = Uri.parse(path);
|
||||||
DocumentFile singleFile = DocumentFile.fromSingleUri(getContext(), uri);
|
DocumentFile singleFile = DocumentFile.fromSingleUri(getContext(), uri);
|
||||||
if (singleFile.length() > 0 && singleFile.length() != 4096){
|
if (singleFile.length() > 0 && singleFile.length() != 4096) {
|
||||||
return singleFile;
|
return singleFile;
|
||||||
}
|
}
|
||||||
if (uri.getScheme().equals("content") && uri.getPath().startsWith("/"+TREE_URI)){
|
if (uri.getScheme().equals("content") && uri.getPath().startsWith("/" + TREE_URI)) {
|
||||||
return DocumentFile.fromTreeUri(getContext(), uri);
|
return DocumentFile.fromTreeUri(getContext(), uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
return singleFile;
|
return singleFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,22 +265,26 @@ public class FileUtils {
|
||||||
FileUtils.createFile(path, name);
|
FileUtils.createFile(path, name);
|
||||||
InputStream in = getInputStream(source);
|
InputStream in = getInputStream(source);
|
||||||
OutputStream out = getOutputStream(fullPath);
|
OutputStream out = getOutputStream(fullPath);
|
||||||
byte[] buffer = new byte[1024 * 128]; //128 KB
|
// Make a 128KB temp buffer used for copying in chunks
|
||||||
|
byte[] buffer = new byte[1024 * 128];
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
while ((length = in.read(buffer)) != -1) {
|
while ((length = in.read(buffer)) != -1) {
|
||||||
out.write(buffer, 0, length);
|
out.write(buffer, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
in.close();
|
in.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(Constants.LOG_TAG, "ERROR ON COPY FILE", e);
|
Log.e(Constants.LOG_TAG, "Error while trying to copy file", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getChild(String path, String name){
|
public static String getChild(String path, String name) {
|
||||||
return parseFile(path).findFile(name).getUri().toString();
|
return parseFile(path).findFile(name).getUri().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class GameUtils {
|
||||||
String[] keys = data.folders.keySet().toArray(new String[0]);
|
String[] keys = data.folders.keySet().toArray(new String[0]);
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
GamesFolder folder = data.folders.get(key);
|
GamesFolder folder = data.folders.get(key);
|
||||||
if (!folder.isValid()){
|
if (!folder.isValid()) {
|
||||||
data.folders.remove(key);
|
data.folders.remove(key);
|
||||||
} else {
|
} else {
|
||||||
folder.refresh();
|
folder.refresh();
|
||||||
|
@ -100,7 +100,7 @@ public class GameUtils {
|
||||||
public static ArrayList<GameMetadata> getGames() {
|
public static ArrayList<GameMetadata> getGames() {
|
||||||
ArrayList<GameMetadata> games = new ArrayList<>();
|
ArrayList<GameMetadata> games = new ArrayList<>();
|
||||||
games.addAll(data.games);
|
games.addAll(data.games);
|
||||||
for (GamesFolder folder: data.folders.values()){
|
for (GamesFolder folder: data.folders.values()) {
|
||||||
games.addAll(folder.getGames());
|
games.addAll(folder.getGames());
|
||||||
}
|
}
|
||||||
return games;
|
return games;
|
||||||
|
@ -144,9 +144,9 @@ public class GameUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerFolder(String path) {
|
public static void registerFolder(String path) {
|
||||||
if (!data.folders.containsKey(path)){
|
if (!data.folders.containsKey(path)) {
|
||||||
GamesFolder folder = new GamesFolder(path);
|
GamesFolder folder = new GamesFolder(path);
|
||||||
data.folders.put(folder.getId(),folder);
|
data.folders.put(folder.getId(), folder);
|
||||||
folder.refresh();
|
folder.refresh();
|
||||||
writeChanges();
|
writeChanges();
|
||||||
}
|
}
|
||||||
|
@ -158,11 +158,12 @@ public class GameUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameMetadata findGameById(String id) {
|
public static GameMetadata findGameById(String id) {
|
||||||
for (GameMetadata game: getGames()){
|
for (GameMetadata game: getGames()) {
|
||||||
if (game.getId().equals(id)){
|
if (game.getId().equals(id)) {
|
||||||
return game;
|
return game;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,24 +8,24 @@ class Bounds {
|
||||||
public int top = 0;
|
public int top = 0;
|
||||||
public int bottom = 0;
|
public int bottom = 0;
|
||||||
|
|
||||||
public void normalize(){
|
public void normalize() {
|
||||||
left = Math.abs(left);
|
left = Math.abs(left);
|
||||||
right = Math.abs(right);
|
right = Math.abs(right);
|
||||||
top = Math.abs(top);
|
top = Math.abs(top);
|
||||||
bottom = Math.abs(bottom);
|
bottom = Math.abs(bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyWithAspect(Rect rect, int width, double aspectRatio){
|
public void applyWithAspect(Rect rect, int width, double aspectRatio) {
|
||||||
normalize();
|
normalize();
|
||||||
rect.set(left, top, width-right, (int) Math.round((width-right-left)*aspectRatio)+top);
|
rect.set(left, top, width-right, (int) Math.round((width-right-left)*aspectRatio)+top);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply(Rect rect, int width, int height){
|
public void apply(Rect rect, int width, int height) {
|
||||||
normalize();
|
normalize();
|
||||||
rect.set(left, top, width-right, height-bottom);
|
rect.set(left, top, width-right, height-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void move(int x, int y){
|
public void move(int x, int y) {
|
||||||
left += x;
|
left += x;
|
||||||
right -= x;
|
right -= x;
|
||||||
|
|
||||||
|
@ -35,12 +35,14 @@ class Bounds {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixOverlay(int width, int height, int size) {
|
public void fixOverlay(int width, int height, int size) {
|
||||||
if (left > (width-right) - size){
|
if (left > (width - right) - size) {
|
||||||
right = (width-left) - size;
|
right = (width - left) - size;
|
||||||
}
|
}
|
||||||
if (top > (height - bottom) - size){
|
|
||||||
|
if (top > (height - bottom) - size) {
|
||||||
bottom = (height - top) - size;
|
bottom = (height - top) - size;
|
||||||
}
|
}
|
||||||
|
|
||||||
normalize();
|
normalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -51,13 +51,13 @@ public class DsEditorView extends FrameLayout {
|
||||||
public DsEditorView(Context context, int index) {
|
public DsEditorView(Context context, int index) {
|
||||||
super(context);
|
super(context);
|
||||||
layout = (DsLayout) DsLayoutManager.createLayout(index);
|
layout = (DsLayout) DsLayoutManager.createLayout(index);
|
||||||
SIZE_DP = CompatUtils.applyDimen(TypedValue.COMPLEX_UNIT_DIP, 1);
|
SIZE_DP = CompatUtils.applyDimensions(TypedValue.COMPLEX_UNIT_DIP, 1);
|
||||||
int colorBottomSelection = CompatUtils.resolveColor(context, androidx.appcompat.R.attr.colorPrimary);
|
int colorBottomSelection = CompatUtils.resolveColor(context, androidx.appcompat.R.attr.colorPrimary);
|
||||||
int colorTopSelection = CompatUtils.resolveColor(context, com.google.android.material.R.attr.colorAccent);
|
int colorTopSelection = CompatUtils.resolveColor(context, com.google.android.material.R.attr.colorAccent);
|
||||||
|
|
||||||
selectionPaint.setColor(colorTopSelection);
|
selectionPaint.setColor(colorTopSelection);
|
||||||
selectionPaint.setStrokeWidth(SIZE_DP * 2);
|
selectionPaint.setStrokeWidth(SIZE_DP * 2);
|
||||||
selectionPaint.setPathEffect(new DashPathEffect(new float[]{SIZE_DP * 10, SIZE_DP * 10}, 0.0f));
|
selectionPaint.setPathEffect(new DashPathEffect(new float[] { SIZE_DP * 10, SIZE_DP * 10 }, 0.0f));
|
||||||
selectionPaint.setStyle(Paint.Style.STROKE);
|
selectionPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
layout.setTopDisplaySourceSize(Constants.N3DS_WIDTH, Constants.N3DS_HALF_HEIGHT);
|
layout.setTopDisplaySourceSize(Constants.N3DS_WIDTH, Constants.N3DS_HALF_HEIGHT);
|
||||||
|
@ -71,14 +71,17 @@ public class DsEditorView extends FrameLayout {
|
||||||
layout.getCurrentModel().gravity = Gravity.TOP;
|
layout.getCurrentModel().gravity = Gravity.TOP;
|
||||||
refreshLayout();
|
refreshLayout();
|
||||||
});
|
});
|
||||||
|
|
||||||
gravityAnchor.findViewById(R.id.center).setOnClickListener(v -> {
|
gravityAnchor.findViewById(R.id.center).setOnClickListener(v -> {
|
||||||
layout.getCurrentModel().gravity = Gravity.CENTER;
|
layout.getCurrentModel().gravity = Gravity.CENTER;
|
||||||
refreshLayout();
|
refreshLayout();
|
||||||
});
|
});
|
||||||
|
|
||||||
gravityAnchor.findViewById(R.id.down).setOnClickListener(v -> {
|
gravityAnchor.findViewById(R.id.down).setOnClickListener(v -> {
|
||||||
layout.getCurrentModel().gravity = Gravity.BOTTOM;
|
layout.getCurrentModel().gravity = Gravity.BOTTOM;
|
||||||
refreshLayout();
|
refreshLayout();
|
||||||
});
|
});
|
||||||
|
|
||||||
gravityAnchor.findViewById(R.id.revert).setOnClickListener(v -> {
|
gravityAnchor.findViewById(R.id.revert).setOnClickListener(v -> {
|
||||||
layout.getCurrentModel().reverse = !layout.getCurrentModel().reverse;
|
layout.getCurrentModel().reverse = !layout.getCurrentModel().reverse;
|
||||||
refreshLayout();
|
refreshLayout();
|
||||||
|
@ -87,7 +90,7 @@ public class DsEditorView extends FrameLayout {
|
||||||
{
|
{
|
||||||
modeSelectorLayout = (LinearLayout) inflater.inflate(R.layout.ds_editor_spinner, this, false);
|
modeSelectorLayout = (LinearLayout) inflater.inflate(R.layout.ds_editor_spinner, this, false);
|
||||||
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(getContext(), R.layout.ds_editor_spinner_label);
|
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(getContext(), R.layout.ds_editor_spinner_label);
|
||||||
spinnerAdapter.addAll("SINGLE", "RELATIVE", "ABSOLUTE");
|
spinnerAdapter.addAll("Single", "Relative", "Absolute");
|
||||||
modeSelector = modeSelectorLayout.findViewById(R.id.spinner);
|
modeSelector = modeSelectorLayout.findViewById(R.id.spinner);
|
||||||
modeSelector.setAdapter(spinnerAdapter);
|
modeSelector.setAdapter(spinnerAdapter);
|
||||||
modeSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
modeSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@ -149,6 +152,7 @@ public class DsEditorView extends FrameLayout {
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
super.draw(canvas);
|
super.draw(canvas);
|
||||||
|
|
||||||
if (this.width != getWidth() || this.height != getHeight()) {
|
if (this.width != getWidth() || this.height != getHeight()) {
|
||||||
this.width = getWidth();
|
this.width = getWidth();
|
||||||
this.height = getHeight();
|
this.height = getHeight();
|
||||||
|
@ -172,12 +176,12 @@ public class DsEditorView extends FrameLayout {
|
||||||
spacePoint.setCenterPosition(primaryDisplay.width(), (int) (SIZE_DP * 15));
|
spacePoint.setCenterPosition(primaryDisplay.width(), (int) (SIZE_DP * 15));
|
||||||
spacePoint.setText(String.valueOf((int) (data.space * 100)));
|
spacePoint.setText(String.valueOf((int) (data.space * 100)));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SINGLE:
|
case SINGLE:
|
||||||
case ABSOLUTE: {
|
case ABSOLUTE: break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.topDisplay.setSize(topDisplay.width(), topDisplay.height());
|
this.topDisplay.setSize(topDisplay.width(), topDisplay.height());
|
||||||
|
@ -212,19 +216,23 @@ public class DsEditorView extends FrameLayout {
|
||||||
if (landscape) {
|
if (landscape) {
|
||||||
addView(spacePoint);
|
addView(spacePoint);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ABSOLUTE: {
|
case ABSOLUTE: {
|
||||||
addView(aspectRatioFixLayout, new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.CENTER | Gravity.TOP));
|
addView(aspectRatioFixLayout, new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.CENTER | Gravity.TOP));
|
||||||
addView(topDisplayResizer);
|
addView(topDisplayResizer);
|
||||||
addView(bottomDisplayResizer);
|
addView(bottomDisplayResizer);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SINGLE: {
|
case SINGLE: {
|
||||||
addView(aspectRatioFixLayout, new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.CENTER | Gravity.TOP));
|
addView(aspectRatioFixLayout, new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.CENTER | Gravity.TOP));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
((MaterialCheckBox) aspectRatioFixLayout.findViewById(R.id.checkbox)).setChecked(layout.getCurrentModel().lockAspect);
|
((MaterialCheckBox) aspectRatioFixLayout.findViewById(R.id.checkbox)).setChecked(layout.getCurrentModel().lockAspect);
|
||||||
|
|
||||||
modeSelector.setSelection(layout.getCurrentModel().mode.ordinal());
|
modeSelector.setSelection(layout.getCurrentModel().mode.ordinal());
|
||||||
|
@ -233,7 +241,6 @@ public class DsEditorView extends FrameLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PointView extends AppCompatTextView {
|
private class PointView extends AppCompatTextView {
|
||||||
|
|
||||||
public PointView() {
|
public PointView() {
|
||||||
super(DsEditorView.this.getContext());
|
super(DsEditorView.this.getContext());
|
||||||
setLayoutParams(new FrameLayout.LayoutParams((int) (SIZE_DP * 30), (int) (SIZE_DP * 30)));
|
setLayoutParams(new FrameLayout.LayoutParams((int) (SIZE_DP * 30), (int) (SIZE_DP * 30)));
|
||||||
|
@ -302,6 +309,7 @@ public class DsEditorView extends FrameLayout {
|
||||||
downEvent = new Vector2(event.getRawX(), event.getRawY());
|
downEvent = new Vector2(event.getRawX(), event.getRawY());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
preferred.move((int) (event.getRawX() - downEvent.x), (int) (event.getRawY() - downEvent.y));
|
preferred.move((int) (event.getRawX() - downEvent.x), (int) (event.getRawY() - downEvent.y));
|
||||||
downEvent.set(event.getRawX(), event.getRawY());
|
downEvent.set(event.getRawX(), event.getRawY());
|
||||||
refreshPoints();
|
refreshPoints();
|
||||||
|
@ -330,6 +338,7 @@ public class DsEditorView extends FrameLayout {
|
||||||
refreshPoints();
|
refreshPoints();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,12 +102,7 @@ class DsLayout implements ConsoleLayout {
|
||||||
(data.onlyTop ? bottomDisplay : topDisplay).set(0, 0, 0, 0);
|
(data.onlyTop ? bottomDisplay : topDisplay).set(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Relative layout: Organize screen position based on gravity and space, the space determined by the top screen size in landscape mode
|
||||||
/***
|
|
||||||
* RELATIVE LAYOUT:
|
|
||||||
* ORGANIZE SCREEN IN POSITION BASED IN GRAVITY
|
|
||||||
* AND SPACE, THE SPACE DETERMINE LANDSCAPE TOP SCREEN SIZE
|
|
||||||
*/
|
|
||||||
private void relative(Model data) {
|
private void relative(Model data) {
|
||||||
int screenWidth = (int) screenSize.x;
|
int screenWidth = (int) screenSize.x;
|
||||||
int screenHeight = (int) screenSize.y;
|
int screenHeight = (int) screenSize.y;
|
||||||
|
@ -144,14 +139,15 @@ class DsLayout implements ConsoleLayout {
|
||||||
case Gravity.CENTER: {
|
case Gravity.CENTER: {
|
||||||
bottomDisplay.offset(0, (screenHeight - bottomDisplay.height()) / 2);
|
bottomDisplay.offset(0, (screenHeight - bottomDisplay.height()) / 2);
|
||||||
topDisplay.offset(0, (screenHeight - topDisplay.height()) / 2);
|
topDisplay.offset(0, (screenHeight - topDisplay.height()) / 2);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Gravity.BOTTOM: {
|
case Gravity.BOTTOM: {
|
||||||
bottomDisplay.offset(0, (screenHeight - bottomDisplay.height()));
|
bottomDisplay.offset(0, (screenHeight - bottomDisplay.height()));
|
||||||
topDisplay.offset(0, (screenHeight - topDisplay.height()));
|
topDisplay.offset(0, (screenHeight - topDisplay.height()));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int topScreenHeight = (int) ((screenWidth / topSourceSize.x) * topSourceSize.y);
|
int topScreenHeight = (int) ((screenWidth / topSourceSize.x) * topSourceSize.y);
|
||||||
|
|
|
@ -10,7 +10,7 @@ public class DsLayoutManager {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
data = GlobalConfig.getExtra(GlobalConfig.KEY_DS_LAYOUTS, DataModel.class);
|
data = GlobalConfig.getExtra(GlobalConfig.KEY_DS_LAYOUTS, DataModel.class);
|
||||||
if (data.models.size() == 0){
|
if (data.models.size() == 0) {
|
||||||
setupBasicModels();
|
setupBasicModels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,24 +26,24 @@ public class DsLayoutManager {
|
||||||
model3.mode = Mode.SINGLE;
|
model3.mode = Mode.SINGLE;
|
||||||
model3.onlyTop = true;
|
model3.onlyTop = true;
|
||||||
|
|
||||||
data.models.add(new Model[]{model1, model1.clone()});
|
data.models.add(new Model[] {model1, model1.clone()});
|
||||||
data.models.add(new Model[]{model2, model2.clone()});
|
data.models.add(new Model[] {model2, model2.clone()});
|
||||||
data.models.add(new Model[]{model3, model3.clone()});
|
data.models.add(new Model[] {model3, model3.clone()});
|
||||||
|
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void save(){
|
public static synchronized void save() {
|
||||||
GlobalConfig.putExtra(GlobalConfig.KEY_DS_LAYOUTS, data);
|
GlobalConfig.putExtra(GlobalConfig.KEY_DS_LAYOUTS, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLayoutCount(){
|
public static int getLayoutCount() {
|
||||||
return data.models.size();
|
return data.models.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConsoleLayout createLayout(int index){
|
public static ConsoleLayout createLayout(int index) {
|
||||||
index = Math.min(getLayoutCount()-1, index);
|
index = Math.min(getLayoutCount() - 1, index);
|
||||||
return new DsLayout(data.models.get(index)[0],data.models.get(index)[1]);
|
return new DsLayout(data.models.get(index)[0], data.models.get(index)[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DataModel {
|
private static class DataModel {
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Model implements Cloneable {
|
||||||
public Model clone() {
|
public Model clone() {
|
||||||
try {
|
try {
|
||||||
return (Model) super.clone();
|
return (Model) super.clone();
|
||||||
} catch (Exception e){
|
} catch (Exception e) {
|
||||||
Log.e(Constants.LOG_TAG, "Error on clone DsModel!", e);
|
Log.e(Constants.LOG_TAG, "Error on clone DsModel!", e);
|
||||||
return new Model();
|
return new Model();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class GamesGridView extends RecyclerView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onLongClickGame(GameMetadata game) {
|
private void onLongClickGame(GameMetadata game) {
|
||||||
if (longClickListener != null){
|
if (longClickListener != null) {
|
||||||
longClickListener.run(game);
|
longClickListener.run(game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,152 +0,0 @@
|
||||||
package com.panda3ds.pandroid.view.renderer.layout;
|
|
||||||
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.view.Gravity;
|
|
||||||
|
|
||||||
import com.panda3ds.pandroid.math.Vector2;
|
|
||||||
|
|
||||||
public class RelativeScreenLayout implements ConsoleLayout {
|
|
||||||
private final Rect topDisplay = new Rect();
|
|
||||||
private final Rect bottomDisplay = new Rect();
|
|
||||||
|
|
||||||
private final Vector2 screenSize = new Vector2(1.0f, 1.0f);
|
|
||||||
private final Vector2 topSourceSize = new Vector2(1.0f, 1.0f);
|
|
||||||
private final Vector2 bottomSourceSize = new Vector2(1.0f, 1.0f);
|
|
||||||
|
|
||||||
private boolean landscapeReverse = false;
|
|
||||||
private boolean portraitReverse = false;
|
|
||||||
private float landscapeSpace = 0.6f;
|
|
||||||
private int landscapeGravity = Gravity.CENTER;
|
|
||||||
private int portraitGravity = Gravity.TOP;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(int screenWidth, int screenHeight) {
|
|
||||||
screenSize.set(screenWidth, screenHeight);
|
|
||||||
updateBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBottomDisplaySourceSize(int width, int height) {
|
|
||||||
bottomSourceSize.set(width, height);
|
|
||||||
updateBounds();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setTopDisplaySourceSize(int width, int height) {
|
|
||||||
topSourceSize.set(width, height);
|
|
||||||
updateBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPortraitGravity(int portraitGravity) {
|
|
||||||
this.portraitGravity = portraitGravity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLandscapeGravity(int landscapeGravity) {
|
|
||||||
this.landscapeGravity = landscapeGravity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLandscapeSpace(float landscapeSpace) {
|
|
||||||
this.landscapeSpace = landscapeSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLandscapeReverse(boolean landscapeReverse) {
|
|
||||||
this.landscapeReverse = landscapeReverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPortraitReverse(boolean portraitReverse) {
|
|
||||||
this.portraitReverse = portraitReverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateBounds() {
|
|
||||||
int screenWidth = (int) screenSize.x;
|
|
||||||
int screenHeight = (int) screenSize.y;
|
|
||||||
|
|
||||||
Vector2 topSourceSize = this.topSourceSize;
|
|
||||||
Vector2 bottomSourceSize = this.bottomSourceSize;
|
|
||||||
|
|
||||||
Rect topDisplay = this.topDisplay;
|
|
||||||
Rect bottomDisplay = this.bottomDisplay;
|
|
||||||
|
|
||||||
if ((landscapeReverse && screenWidth > screenHeight) || (portraitReverse && screenWidth < screenHeight)){
|
|
||||||
topSourceSize = this.bottomSourceSize;
|
|
||||||
bottomSourceSize = this.topSourceSize;
|
|
||||||
|
|
||||||
topDisplay = this.bottomDisplay;
|
|
||||||
bottomDisplay = this.topDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (screenWidth > screenHeight) {
|
|
||||||
int topDisplayWidth = (int) ((screenHeight / topSourceSize.y) * topSourceSize.x);
|
|
||||||
int topDisplayHeight = screenHeight;
|
|
||||||
|
|
||||||
if (topDisplayWidth > (screenWidth * landscapeSpace)) {
|
|
||||||
topDisplayWidth = (int) (screenWidth * landscapeSpace);
|
|
||||||
topDisplayHeight = (int) ((topDisplayWidth / topSourceSize.x) * topSourceSize.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bottomDisplayHeight = (int) (((screenWidth - topDisplayWidth) / bottomSourceSize.x) * bottomSourceSize.y);
|
|
||||||
|
|
||||||
topDisplay.set(0, 0, topDisplayWidth, topDisplayHeight);
|
|
||||||
bottomDisplay.set(topDisplayWidth, 0, topDisplayWidth + (screenWidth - topDisplayWidth), bottomDisplayHeight);
|
|
||||||
adjustHorizontalGravity();
|
|
||||||
} else {
|
|
||||||
int topScreenHeight = (int) ((screenWidth / topSourceSize.x) * topSourceSize.y);
|
|
||||||
topDisplay.set(0, 0, screenWidth, topScreenHeight);
|
|
||||||
|
|
||||||
int bottomDisplayHeight = (int) ((screenWidth / bottomSourceSize.x) * bottomSourceSize.y);
|
|
||||||
int bottomDisplayWidth = screenWidth;
|
|
||||||
int bottomDisplayX = 0;
|
|
||||||
|
|
||||||
if (topScreenHeight + bottomDisplayHeight > screenHeight) {
|
|
||||||
bottomDisplayHeight = (screenHeight - topScreenHeight);
|
|
||||||
bottomDisplayWidth = (int) ((bottomDisplayHeight / bottomSourceSize.y) * bottomSourceSize.x);
|
|
||||||
bottomDisplayX = (screenWidth - bottomDisplayX) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
topDisplay.set(0, 0, screenWidth, topScreenHeight);
|
|
||||||
bottomDisplay.set(bottomDisplayX, topScreenHeight, bottomDisplayX + bottomDisplayWidth, topScreenHeight + bottomDisplayHeight);
|
|
||||||
adjustVerticalGravity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void adjustHorizontalGravity(){
|
|
||||||
int topOffset = 0;
|
|
||||||
int bottomOffset = 0;
|
|
||||||
switch (landscapeGravity){
|
|
||||||
case Gravity.CENTER:{
|
|
||||||
topOffset = (int) (screenSize.y - topDisplay.height())/2;
|
|
||||||
bottomOffset = (int) (screenSize.y - bottomDisplay.height())/2;
|
|
||||||
}break;
|
|
||||||
case Gravity.BOTTOM:{
|
|
||||||
topOffset = (int) (screenSize.y - topDisplay.height());
|
|
||||||
bottomOffset = (int) (screenSize.y - bottomDisplay.height());
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
topDisplay.offset(0, topOffset);
|
|
||||||
bottomDisplay.offset(0, bottomOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void adjustVerticalGravity(){
|
|
||||||
int height = (topDisplay.height() + bottomDisplay.height());
|
|
||||||
int space = 0;
|
|
||||||
switch (portraitGravity){
|
|
||||||
case Gravity.CENTER:{
|
|
||||||
space = (int) (screenSize.y - height)/2;
|
|
||||||
}break;
|
|
||||||
case Gravity.BOTTOM:{
|
|
||||||
space = (int) (screenSize.y - height);
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
topDisplay.offset(0, space);
|
|
||||||
bottomDisplay.offset(0,space);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Rect getBottomDisplayBounds() {
|
|
||||||
return bottomDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Rect getTopDisplayBounds() {
|
|
||||||
return topDisplay;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package com.panda3ds.pandroid.view.renderer.layout;
|
|
||||||
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.view.Gravity;
|
|
||||||
|
|
||||||
import com.panda3ds.pandroid.math.Vector2;
|
|
||||||
|
|
||||||
public class SingleScreenLayout implements ConsoleLayout {
|
|
||||||
private final Rect topDisplay = new Rect();
|
|
||||||
private final Rect bottomDisplay = new Rect();
|
|
||||||
private final Vector2 screenSize = new Vector2(1.0f, 1.0f);
|
|
||||||
private final Vector2 topSourceSize = new Vector2(1.0f, 1.0f);
|
|
||||||
private final Vector2 bottomSourceSize = new Vector2(1.0f, 1.0f);
|
|
||||||
private boolean top = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(int screenWidth, int screenHeight) {
|
|
||||||
screenSize.set(screenWidth, screenHeight);
|
|
||||||
updateBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBottomDisplaySourceSize(int width, int height) {
|
|
||||||
bottomSourceSize.set(width, height);
|
|
||||||
updateBounds();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setTopDisplaySourceSize(int width, int height) {
|
|
||||||
topSourceSize.set(width, height);
|
|
||||||
updateBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateBounds() {
|
|
||||||
int screenWidth = (int) screenSize.x;
|
|
||||||
int screenHeight = (int) screenSize.y;
|
|
||||||
Vector2 source = top ? topSourceSize : bottomSourceSize;
|
|
||||||
Rect dest = top ? topDisplay : bottomDisplay;
|
|
||||||
|
|
||||||
int width = Math.round((screenHeight / source.y) * source.x);
|
|
||||||
int height = screenHeight;
|
|
||||||
int y = 0;
|
|
||||||
int x = (screenWidth - width) / 2;
|
|
||||||
if (width > screenWidth){
|
|
||||||
width = screenWidth;
|
|
||||||
height = Math.round((screenWidth / source.x) * source.y);
|
|
||||||
x = 0;
|
|
||||||
y = (screenHeight - height)/2;
|
|
||||||
}
|
|
||||||
dest.set(x, y, x + width, y+height);
|
|
||||||
|
|
||||||
(top ? bottomDisplay : topDisplay).set(0,0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Rect getBottomDisplayBounds() {
|
|
||||||
return bottomDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Rect getTopDisplayBounds() {
|
|
||||||
return topDisplay;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue