some fixes

This commit is contained in:
gabriel 2024-02-28 20:40:55 -04:00
parent 329fa7a158
commit d0b4e09069
27 changed files with 342 additions and 240 deletions

View file

@ -126,6 +126,16 @@ public class GameActivity extends BaseActivity implements EmulatorCallback {
return super.dispatchGenericMotionEvent(ev);
}
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
}
@Override
protected void onUserLeaveHint() {
super.onUserLeaveHint();
}
@Override
protected void onDestroy() {
if (AlberDriver.HasRomLoaded()) {

View file

@ -0,0 +1,46 @@
package com.panda3ds.pandroid.app.base;
import android.content.Context;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.utils.CompatUtils;
import org.jetbrains.annotations.NotNull;
public class BaseSheetDialog extends BottomSheetDialog {
private final LinearLayout contentView;
public BaseSheetDialog(@NonNull Context context) {
super(CompatUtils.findActivity(context));
int width = CompatUtils.findActivity(context).getWindow().getDecorView().getMeasuredWidth();
int height = CompatUtils.findActivity(context).getWindow().getDecorView().getMeasuredHeight();
getBehavior().setPeekHeight((int) (height*0.87));
getBehavior().setMaxWidth(width);
getBehavior().setMaxHeight((int) (height*0.87));
super.setContentView(R.layout.dialog_bottom_sheet);
contentView = super.findViewById(R.id.content);
}
@Override
public void setContentView(View view) {
contentView.removeAllViews();
contentView.addView(view);
}
@Override
public void setContentView(int layoutResId) {
setContentView(LayoutInflater.from(getContext()).inflate(layoutResId, null, false));
}
@NotNull
@Override
public <T extends View> T findViewById(int id) {
return contentView.findViewById(id);
}
}

View file

@ -1,6 +1,7 @@
package com.panda3ds.pandroid.app.base;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
@ -14,28 +15,37 @@ import com.panda3ds.pandroid.utils.FileUtils;
import com.panda3ds.pandroid.utils.GameUtils;
import com.panda3ds.pandroid.view.gamesgrid.GameIconView;
public class GameAboutDialog extends BottomSheetDialog {
public class GameAboutDialog extends BaseSheetDialog {
private final GameMetadata game;
public GameAboutDialog(@NonNull Context context, GameMetadata game) {
super(context);
View content = LayoutInflater.from(context).inflate(R.layout.dialog_game_about, null, false);
setContentView(content);
this.game = game;
}
((GameIconView)content.findViewById(R.id.game_icon)).setImageBitmap(game.getIcon());
((TextView)content.findViewById(R.id.game_title)).setText(game.getTitle());
((TextView)content.findViewById(R.id.game_publisher)).setText(game.getPublisher());
((TextView)content.findViewById(R.id.region)).setText(game.getRegions()[0].name());
((TextView)content.findViewById(R.id.directory)).setText(FileUtils.obtainUri(game.getRealPath()).getPath());
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_game_about);
content.findViewById(R.id.play).setOnClickListener(v -> {
((GameIconView) findViewById(R.id.game_icon)).setImageBitmap(game.getIcon());
((TextView) findViewById(R.id.game_title)).setText(game.getTitle());
((TextView) findViewById(R.id.game_publisher)).setText(game.getPublisher());
((TextView) findViewById(R.id.region)).setText(game.getRegions()[0].localizedName());
((TextView) findViewById(R.id.directory)).setText(FileUtils.obtainUri(game.getRealPath()).getPath());
findViewById(R.id.play).setOnClickListener(v -> {
dismiss();
GameUtils.launch(getContext(), game);
});
if (game.getRomPath().startsWith("folder:")){
content.findViewById(R.id.remove).setVisibility(View.GONE);
if (game.getRomPath().startsWith("folder:")) {
findViewById(R.id.remove).setVisibility(View.GONE);
} else {
content.findViewById(R.id.remove).setOnClickListener(v-> {
findViewById(R.id.remove).setOnClickListener(v -> {
dismiss();
if (game.getRomPath().startsWith("elf:")) {
FileUtils.delete(game.getRealPath());
}
GameUtils.removeGame(game);
});
}

View file

@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.fragment.app.Fragment;
import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.app.base.GameAboutDialog;
import com.panda3ds.pandroid.data.game.GameMetadata;
import com.panda3ds.pandroid.utils.GameUtils;
import com.panda3ds.pandroid.utils.SearchAgent;
@ -33,6 +34,11 @@ public class SearchFragment extends Fragment {
super.onViewCreated(view, savedInstanceState);
gamesListView = view.findViewById(R.id.games);
gamesListView.setItemLongClick((game)->{
GameAboutDialog dialog = new GameAboutDialog(requireActivity(), game);
dialog.setOnDismissListener((x)-> search(((AppCompatEditText) view.findViewById(R.id.search_bar)).getText().toString()));
dialog.show();
});
((AppCompatEditText) view.findViewById(R.id.search_bar)).addTextChangedListener((SimpleTextWatcher) this::search);
}

View file

@ -17,6 +17,7 @@ import androidx.preference.PreferenceScreen;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.app.base.BasePreferenceFragment;
import com.panda3ds.pandroid.app.base.BaseSheetDialog;
import com.panda3ds.pandroid.data.game.GamesFolder;
import com.panda3ds.pandroid.utils.FileUtils;
import com.panda3ds.pandroid.utils.GameUtils;
@ -34,13 +35,13 @@ public class GamesFoldersPreferences extends BasePreferenceFragment implements A
}
@SuppressLint("RestrictedApi")
private void refreshList(){
private void refreshList() {
GamesFolder[] folders = GameUtils.getFolders();
PreferenceScreen screen = getPreferenceScreen();
screen.removeAll();
for (GamesFolder folder: folders){
for (GamesFolder folder : folders) {
Preference preference = new Preference(screen.getContext());
preference.setOnPreferenceClickListener((item)-> {
preference.setOnPreferenceClickListener((item) -> {
showFolderInfo(folder);
screen.performClick();
return false;
@ -62,12 +63,12 @@ public class GamesFoldersPreferences extends BasePreferenceFragment implements A
}
private void showFolderInfo(GamesFolder folder) {
BottomSheetDialog dialog = new BottomSheetDialog(requireActivity());
View layout = LayoutInflater.from(requireActivity()).inflate(R.layout.games_folder_about, null, false);
BaseSheetDialog dialog = new BaseSheetDialog(requireActivity());
View layout = LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_games_folder, null, false);
dialog.setContentView(layout);
((TextView) layout.findViewById(R.id.name)).setText(FileUtils.getName(folder.getPath()));
((TextView) layout.findViewById(R.id.directory)).setText(folder.getPath());
((TextView) layout.findViewById(R.id.directory)).setText(FileUtils.obtainUri(folder.getPath()).getPath());
((TextView) layout.findViewById(R.id.games)).setText(String.valueOf(folder.getGames().size()));
layout.findViewById(R.id.ok).setOnClickListener(v -> dialog.dismiss());
@ -83,7 +84,7 @@ public class GamesFoldersPreferences extends BasePreferenceFragment implements A
@Override
public void onDestroy() {
super.onDestroy();
if (pickFolderRequest != null){
if (pickFolderRequest != null) {
pickFolderRequest.unregister();
pickFolderRequest = null;
}
@ -91,7 +92,7 @@ public class GamesFoldersPreferences extends BasePreferenceFragment implements A
@Override
public void onActivityResult(Uri result) {
if (result != null){
if (result != null) {
FileUtils.makeUriPermanent(result.toString(), "r");
GameUtils.registerFolder(result.toString());
refreshList();

View file

@ -1,7 +1,7 @@
package com.panda3ds.pandroid.app.preferences;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
@ -12,42 +12,43 @@ import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatRadioButton;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.app.base.BaseSheetDialog;
import com.panda3ds.pandroid.utils.CompatUtils;
import com.panda3ds.pandroid.data.config.GlobalConfig;
import com.panda3ds.pandroid.view.recycler.AutoFitGridLayout;
import com.panda3ds.pandroid.view.recycler.SimpleListAdapter;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.Predicate;
public class ThemeSelectorDialog extends BottomSheetDialog {
public class ThemeSelectorDialog extends BaseSheetDialog {
private final SimpleListAdapter<Theme> adapter;
private final SimpleListAdapter<Theme> adapter = new SimpleListAdapter<>(R.layout.hold_theme_preview_base, this::bindItemView);
private final int currentTheme = GlobalConfig.get(GlobalConfig.KEY_APP_THEME);
private static final Theme[] themes = {
private static final ArrayList<Theme> themes = new ArrayList<>(Arrays.asList(
new Theme(R.style.Theme_Pandroid, R.string.theme_device, GlobalConfig.THEME_ANDROID),
new Theme(R.style.Theme_Pandroid_Light, R.string.light, GlobalConfig.THEME_LIGHT),
new Theme(R.style.Theme_Pandroid_Dark, R.string.dark, GlobalConfig.THEME_DARK),
new Theme(R.style.Theme_Pandroid_Black, R.string.black, GlobalConfig.THEME_BLACK)
};
));
public ThemeSelectorDialog(@NonNull Context context) {
super(context);
View content = LayoutInflater.from(context).inflate(R.layout.dialog_select_theme, null, false);
setContentView(content);
adapter = new SimpleListAdapter<>(R.layout.hold_theme_preview_summary, this::bindItemView);
adapter.clear();
ArrayList<Theme> themeList = new ArrayList<>(Arrays.asList(themes));
themeList.sort((o1, o2) -> o1.id == currentTheme ? -1 : 0);
adapter.addAll(themeList);
}
((RecyclerView) content.findViewById(R.id.recycler)).setAdapter(adapter);
((RecyclerView) content.findViewById(R.id.recycler)).setLayoutManager(new AutoFitGridLayout(getContext(), 150));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_select_theme);
adapter.clear();
themes.sort((o1, o2) -> o1.value == currentTheme ? -1 : 0);
adapter.addAll(themes);
RecyclerView recycler = findViewById(R.id.recycler);
recycler.setAdapter(adapter);
recycler.setLayoutManager(new AutoFitGridLayout(getContext(), 150));
}
private void bindItemView(int i, Theme theme, View view) {
@ -55,12 +56,12 @@ public class ThemeSelectorDialog extends BottomSheetDialog {
container.removeAllViews();
container.addView(LayoutInflater.from(new ContextThemeWrapper(getContext(), theme.style)).inflate(R.layout.hold_theme_preview, null, false));
((TextView) view.findViewById(R.id.title)).setText(theme.name);
((AppCompatRadioButton) view.findViewById(R.id.checkbox)).setChecked(GlobalConfig.get(GlobalConfig.KEY_APP_THEME) == theme.id);
((AppCompatRadioButton) view.findViewById(R.id.checkbox)).setChecked(GlobalConfig.get(GlobalConfig.KEY_APP_THEME) == theme.value);
view.setOnClickListener(v -> {
dismiss();
if (theme.id != GlobalConfig.get(GlobalConfig.KEY_APP_THEME)) {
GlobalConfig.set(GlobalConfig.KEY_APP_THEME, theme.id);
((Activity) v.getContext()).recreate();
if (theme.value != GlobalConfig.get(GlobalConfig.KEY_APP_THEME)) {
GlobalConfig.set(GlobalConfig.KEY_APP_THEME, theme.value);
CompatUtils.findActivity(getContext()).recreate();
}
});
}
@ -68,12 +69,12 @@ public class ThemeSelectorDialog extends BottomSheetDialog {
private static final class Theme {
private final int style;
private final int name;
private final int id;
private final int value;
private Theme(int style, int name, int value) {
this.style = style;
this.name = name;
this.id = value;
this.value = value;
}
}
}

View file

@ -24,6 +24,7 @@ public class DsEditorPreferences extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
layout = new LinearLayout(container.getContext());
layout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_FULLSCREEN|View.SYSTEM_UI_FLAG_IMMERSIVE);
return layout;
}
@ -36,12 +37,6 @@ public class DsEditorPreferences extends Fragment {
((BaseActivity)requireActivity()).getSupportActionBar().hide();
}
@Override
public void onResume() {
super.onResume();
requireActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN|View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_IMMERSIVE);
}
@Override
public void onDestroy() {
super.onDestroy();

View file

@ -88,10 +88,14 @@ public class AppDataDocumentProvider extends DocumentsProvider {
}
private void includeFile(MatrixCursor cursor, File file) {
int flags = 0;
if (file.isFile()) {
flags = Document.FLAG_SUPPORTS_WRITE;
}
cursor.newRow()
.add(Document.COLUMN_DOCUMENT_ID, obtainDocumentId(file))
.add(Document.COLUMN_MIME_TYPE, file.isDirectory() ? Document.MIME_TYPE_DIR : "application/octect-stream")
.add(Document.COLUMN_FLAGS, 0)
.add(Document.COLUMN_FLAGS, flags)
.add(Document.COLUMN_LAST_MODIFIED, file.lastModified())
.add(Document.COLUMN_DISPLAY_NAME, file.getName())
.add(Document.COLUMN_SIZE, file.length());

View file

@ -1,5 +1,7 @@
package com.panda3ds.pandroid.data.game;
import com.panda3ds.pandroid.R;
public enum GameRegion {
NorthAmerican,
Japan,
@ -8,5 +10,23 @@ public enum GameRegion {
China,
Korean,
Taiwan,
None
None;
public int localizedName(){
switch (this){
case NorthAmerican:
return R.string.region_north_armerican;
case Japan:
return R.string.region_japan;
case Europe:
return R.string.region_europe;
case Australia:
return R.string.region_australia;
case Korean:
return R.string.region_korean;
case Taiwan:
return R.string.region_taiwan;
}
return R.string.unknown;
}
}

View file

@ -1,32 +0,0 @@
package com.panda3ds.pandroid.math;
public class Shape {
public int x = 0, y = 0, width = 1, height = 1;
public Shape() {
}
public Shape(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void move(int x, int y) {
this.x += x;
this.y += y;
}
public void normalize() {
this.x = Math.max(x, 0);
this.y = Math.max(y, 0);
this.width = Math.max(width, 1);
this.height = Math.max(height, 1);
}
public void maxSize(int w, int h) {
this.width = Math.max(w, this.width);
this.height = Math.max(h, this.height);
}
}

View file

@ -0,0 +1,38 @@
package com.panda3ds.pandroid.utils;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.TypedValue;
import androidx.annotation.AttrRes;
import com.panda3ds.pandroid.app.PandroidApplication;
public class CompatUtils {
public static Activity findActivity(Context context) {
if (context instanceof Activity) {
return (Activity) context;
} else if ((context instanceof ContextWrapper)) {
return findActivity(((ContextWrapper) context).getBaseContext());
}
return ((Activity) context);
}
public static int resolveColor(Context context, @AttrRes int id){
try {
TypedArray values = context.obtainStyledAttributes(new int[]{id});
int color = values.getColor(0, Color.RED);
values.recycle();
return color;
} catch (Exception e){
return Color.rgb(255,0,255);
}
}
public static float applyDimen(int unit, int size) {
return TypedValue.applyDimension(unit, size, PandroidApplication.getAppContext().getResources().getDisplayMetrics());
}
}

View file

@ -24,7 +24,6 @@ import java.util.Objects;
public class FileUtils {
public static final String MODE_READ = "r";
private static final String TREE_URI = "tree";
public static final int CANONICAL_SEARCH_DEEP = 8;
private static DocumentFile parseFile(String path) {
if (path.startsWith("/")) {
@ -204,47 +203,6 @@ public class FileUtils {
getContext().getContentResolver().takePersistableUriPermission(Uri.parse(uri), flags);
}
/**
* When call ContentProvider.openFileDescriptor() android opens a file descriptor
* on app process in /proc/self/fd/[file descriptor id] this is a link to real file path
* can use File.getCanonicalPath() for get a link origin, but in some android version
* need use Os.readlink(path) to get a real path.
*/
public static String obtainRealPath(String uri) {
try {
ParcelFileDescriptor parcelDescriptor = getContext().getContentResolver().openFileDescriptor(Uri.parse(uri), "r");
int fd = parcelDescriptor.getFd();
File file = new File("/proc/self/fd/" + fd).getAbsoluteFile();
for (int i = 0; i < CANONICAL_SEARCH_DEEP; i++) {
try {
String canonical = file.getCanonicalPath();
if (!Objects.equals(canonical, file.getAbsolutePath())) {
file = new File(canonical).getAbsoluteFile();
}
} catch (Exception x) {
break;
}
}
if (!file.getAbsolutePath().startsWith("/proc/self/")) {
parcelDescriptor.close();
return file.getAbsolutePath();
}
String path = Os.readlink(file.getAbsolutePath());
parcelDescriptor.close();
if (new File(path).exists()) {
return path;
}
return null;
} catch (Exception e) {
return null;
}
}
public static void updateFile(String path) {
DocumentFile file = parseFile(path);
Uri uri = file.getUri();

View file

@ -21,7 +21,7 @@ import java.util.Objects;
public class GameUtils {
private static final Bitmap DEFAULT_ICON = Bitmap.createBitmap(48, 48, Bitmap.Config.ARGB_8888);
private static GsonConfigParser parser = new GsonConfigParser(Constants.PREF_GAME_UTILS);
private final static GsonConfigParser parser = new GsonConfigParser(Constants.PREF_GAME_UTILS);
private static DataModel data;

View file

@ -0,0 +1,46 @@
package com.panda3ds.pandroid.view.ds;
import android.graphics.Rect;
class Bounds {
public int left = 0;
public int right = 0;
public int top = 0;
public int bottom = 0;
public void normalize(){
left = Math.abs(left);
right = Math.abs(right);
top = Math.abs(top);
bottom = Math.abs(bottom);
}
public void applyWithAspect(Rect rect, int width, double aspectRatio){
normalize();
rect.set(left, top, width-right, (int) Math.round((width-right-left)*aspectRatio)+top);
}
public void apply(Rect rect, int width, int height){
normalize();
rect.set(left, top, width-right, height-bottom);
}
public void move(int x, int y){
left += x;
right -= x;
top += y;
bottom -= y;
normalize();
}
public void fixOverlay(int width, int height, int size) {
if (left > (width-right) - size){
right = (width-left) - size;
}
if (top > (height - bottom) - size){
bottom = (height - top) - size;
}
normalize();
}
}

View file

@ -26,14 +26,14 @@ import androidx.appcompat.widget.AppCompatTextView;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.panda3ds.pandroid.R;
import com.panda3ds.pandroid.math.Shape;
import com.panda3ds.pandroid.math.Vector2;
import com.panda3ds.pandroid.utils.CompatUtils;
import com.panda3ds.pandroid.utils.Constants;
public class DsEditorView extends FrameLayout {
private static final int COLOR_TOP_SELECTION = Color.RED;
private static final int COLOR_BOTTOM_SELECTION = Color.BLUE;
private final int COLOR_TOP_SELECTION;
private final int COLOR_BOTTOM_SELECTION;
private final float SIZE_DP;
private final Paint selectionPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ -53,8 +53,9 @@ public class DsEditorView extends FrameLayout {
public DsEditorView(Context context, int index) {
super(context);
layout = (DsLayout) DsLayoutManager.createLayout(index);
SIZE_DP = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
SIZE_DP = CompatUtils.applyDimen(TypedValue.COMPLEX_UNIT_DIP, 1);
COLOR_BOTTOM_SELECTION = CompatUtils.resolveColor(context, androidx.appcompat.R.attr.colorPrimary);
COLOR_TOP_SELECTION = CompatUtils.resolveColor(context, com.google.android.material.R.attr.colorAccent);
selectionPaint.setColor(COLOR_TOP_SELECTION);
selectionPaint.setStrokeWidth(SIZE_DP * 2);
@ -105,16 +106,11 @@ public class DsEditorView extends FrameLayout {
});
}
{
aspectRatioFixLayout = (LinearLayout) inflater.inflate(R.layout.ds_editor_lock_aspect, this, false);
((MaterialCheckBox) aspectRatioFixLayout.findViewById(R.id.checkbox)).setOnCheckedChangeListener((buttonView, checked) -> {
layout.getCurrentModel().lockAspect = checked;
if (checked) {
fixAspect();
}
refreshPoints();
});
}
spacePoint = new PointView();
spacePoint.setColor(Color.WHITE, COLOR_TOP_SELECTION);
@ -136,11 +132,13 @@ public class DsEditorView extends FrameLayout {
topDisplay = new PointView();
topDisplay.setText(R.string.top_display);
topDisplay.setOnTouchListener(new DisplayTouchEvent(true));
topDisplay.setTextColor(COLOR_TOP_SELECTION);
topDisplay.setBackground(new SelectionDrawable(COLOR_TOP_SELECTION));
bottomDisplay = new PointView();
bottomDisplay.setText(R.string.bottom_display);
bottomDisplay.setOnTouchListener(new DisplayTouchEvent(false));
bottomDisplay.setTextColor(COLOR_BOTTOM_SELECTION);
bottomDisplay.setBackground(new SelectionDrawable(COLOR_BOTTOM_SELECTION));
topDisplayResizer = new PointView();
@ -164,16 +162,10 @@ public class DsEditorView extends FrameLayout {
}
}
private void fixAspect() {
Shape top = layout.getCurrentModel().preferredTop;
Shape bottom = layout.getCurrentModel().preferredBottom;
top.height = (int) (((float) top.width / Constants.N3DS_WIDTH) * Constants.N3DS_HALF_HEIGHT);
bottom.height = (int) (((float) bottom.width / (Constants.N3DS_WIDTH - 80)) * Constants.N3DS_HALF_HEIGHT);
}
private void refreshPoints() {
Model data = layout.getCurrentModel();
data.preferredTop.fixOverlay(width, height, (int) (SIZE_DP*5));
data.preferredBottom.fixOverlay(width, height, (int) (SIZE_DP*30));
layout.update(width, height);
Rect bottomDisplay = layout.getBottomDisplayBounds();
Rect topDisplay = layout.getTopDisplayBounds();
@ -194,9 +186,6 @@ public class DsEditorView extends FrameLayout {
break;
}
data.preferredTop.maxSize((int) (SIZE_DP * 64), (int) (SIZE_DP * 64));
data.preferredBottom.maxSize((int) (SIZE_DP * 64), (int) (SIZE_DP * 64));
this.topDisplay.setSize(topDisplay.width(), topDisplay.height());
this.topDisplay.setPosition(topDisplay.left, topDisplay.top);
@ -305,7 +294,6 @@ public class DsEditorView extends FrameLayout {
private class DisplayTouchEvent implements OnTouchListener {
private final boolean topScreen;
private final Vector2 inner = new Vector2(0, 0);
private Vector2 downEvent = null;
private DisplayTouchEvent(boolean topScreen) {
@ -314,66 +302,39 @@ public class DsEditorView extends FrameLayout {
@Override
public boolean onTouch(View v, MotionEvent event) {
Shape preferred = topScreen ? layout.getCurrentModel().preferredTop : layout.getCurrentModel().preferredBottom;
if (layout.getCurrentModel().mode == Mode.ABSOLUTE) {
PointView point = (PointView) v;
if (event.getAction() != MotionEvent.ACTION_UP) {
Bounds preferred = topScreen ? layout.getCurrentModel().preferredTop : layout.getCurrentModel().preferredBottom;
if (layout.getCurrentModel().mode == Mode.ABSOLUTE && event.getAction() != MotionEvent.ACTION_UP) {
if (downEvent == null) {
downEvent = new Vector2(event.getRawX(), event.getRawY());
inner.set(point.x(), point.y());
return true;
}
preferred.x = (int) ((event.getRawX() - downEvent.x) + inner.x);
preferred.y = (int) ((event.getRawY() - downEvent.y) + inner.y);
preferred.normalize();
preferred.move((int) (event.getRawX() - downEvent.x), (int) (event.getRawY() - downEvent.y));
downEvent.set(event.getRawX(), event.getRawY());
refreshPoints();
return true;
}
downEvent = null;
return false;
} else if (layout.getCurrentModel().mode == Mode.SINGLE && event.getAction() == MotionEvent.ACTION_UP) {
callOnClick();
}
downEvent = null;
return false;
}
}
private class DisplayResizeTouchEvent implements OnTouchListener {
private final boolean topScreen;
private final Vector2 size = new Vector2(0, 0);
private Vector2 downEvent = null;
private DisplayResizeTouchEvent(boolean topScreen) {
this.topScreen = topScreen;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Shape preferred = topScreen ? layout.getCurrentModel().preferredTop : layout.getCurrentModel().preferredBottom;
Bounds preferred = topScreen ? layout.getCurrentModel().preferredTop : layout.getCurrentModel().preferredBottom;
if (event.getAction() != MotionEvent.ACTION_UP) {
if (downEvent == null) {
downEvent = new Vector2(event.getRawX(), event.getRawY());
size.set(preferred.width, preferred.height);
return true;
}
preferred.width = (int) (size.x + ((event.getRawX() - downEvent.x)));
if (layout.getCurrentModel().lockAspect) {
fixAspect();
} else {
preferred.height = (int) (size.y + ((event.getRawY() - downEvent.y)));
}
preferred.maxSize((int) (SIZE_DP * 32), (int) (SIZE_DP * 32));
preferred.right = (int) (width - (((PointView) v).x() + event.getX()));
preferred.bottom = (int) (height - (((PointView) v).y() + event.getY()));
refreshPoints();
return true;
}
downEvent = null;
return false;
}
}
@ -389,7 +350,7 @@ public class DsEditorView extends FrameLayout {
public void draw(Canvas canvas) {
int color = this.getColor();
selectionPaint.setColor(color);
solidPaint.setColor(Color.argb(50, Color.red(color), Color.green(color), Color.blue(color)));
solidPaint.setColor(Color.argb(65, Color.red(color), Color.green(color), Color.blue(color)));
canvas.drawRect(this.getBounds(), solidPaint);
canvas.drawRect(this.getBounds(), selectionPaint);
}

View file

@ -3,7 +3,6 @@ package com.panda3ds.pandroid.view.ds;
import android.graphics.Rect;
import android.view.Gravity;
import com.panda3ds.pandroid.math.Shape;
import com.panda3ds.pandroid.math.Vector2;
import com.panda3ds.pandroid.view.renderer.layout.ConsoleLayout;
@ -70,14 +69,13 @@ class DsLayout implements ConsoleLayout {
}
private void absolute(Model data) {
Shape top = data.preferredTop;
Shape bottom = data.preferredBottom;
top.normalize();
bottom.normalize();
topDisplay.set(top.x, top.y, top.x +top.width, top.y + top.height);
bottomDisplay.set(bottom.x, bottom.y, bottom.x +bottom.width, bottom.y + bottom.height);
if (data.lockAspect){
data.preferredTop.applyWithAspect(topDisplay, (int) screenSize.x, (double) sourceTop.y/sourceTop.x);
data.preferredBottom.applyWithAspect(bottomDisplay, (int) screenSize.x, (double) sourceBottom.y/sourceBottom.x);
} else {
data.preferredTop.apply(topDisplay, (int) screenSize.x, (int) screenSize.y);
data.preferredBottom.apply(bottomDisplay, (int) screenSize.x, (int) screenSize.y);
}
}
/**

View file

@ -5,13 +5,12 @@ import android.view.Gravity;
import androidx.annotation.NonNull;
import com.panda3ds.pandroid.math.Shape;
import com.panda3ds.pandroid.utils.Constants;
class Model implements Cloneable {
public Mode mode = Mode.RELATIVE;
public final Shape preferredTop = new Shape();
public final Shape preferredBottom = new Shape();
public final Bounds preferredTop = new Bounds();
public final Bounds preferredBottom = new Bounds();
public boolean reverse = false;
public boolean singleTop = true;
public float space = 0.6f;

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:gravity="center"
app:strokeWidth="1dp"
app:cardCornerRadius="24dp"
app:strokeColor="?colorSurfaceVariant"
android:background="@drawable/alert_dialog_background">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:background="?colorSurface">
<View
android:layout_width="128dp"
android:layout_height="4dp"
android:layout_marginVertical="8dp"
android:background="@drawable/medium_card_background"
android:backgroundTint="?colorSurfaceVariant"/>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -6,14 +6,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="top|center"
android:padding="10dp"
android:background="@drawable/alert_dialog_background">
<View
android:layout_width="128dp"
android:layout_height="4dp"
android:background="?colorSurfaceVariant"
android:layout_margin="5dp"/>
android:padding="10dp">
<com.google.android.material.card.MaterialCardView
android:layout_width="128dp"
@ -111,9 +104,12 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/play"
android:paddingHorizontal="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/play"
android:textColor="?colorOnPrimary"
android:backgroundTint="?colorPrimary"
app:icon="@drawable/ic_play"
app:iconTint="?colorOnPrimary"/>

View file

@ -5,14 +5,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|top"
android:padding="10dp"
android:background="@drawable/alert_dialog_background">
<View
android:layout_width="128dp"
android:layout_height="4dp"
android:background="?colorSurfaceVariant"
android:layout_margin="5dp"/>
android:padding="10dp">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="64dp"

View file

@ -3,20 +3,13 @@
android:id="@+id/theme_selector"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="@drawable/alert_dialog_background">
<View
android:layout_width="120dp"
android:layout_height="4dp"
android:background="?colorSurfaceVariant"
android:layout_margin="8dp"/>
android:layout_height="match_parent"
android:gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="400dp"
android:paddingHorizontal="20dp"/>
android:layout_height="match_parent"
android:paddingHorizontal="20dp" />
</LinearLayout>

View file

@ -4,6 +4,8 @@
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:padding="4dp">
<LinearLayout
android:layout_width="wrap_content"

View file

@ -5,7 +5,8 @@
android:layout_width="128dp"
android:layout_height="35dp"
android:paddingHorizontal="6dp"
android:textColor="?colorOnPrimary"
android:textColor="?colorOnSurfaceVariant"
android:background="?colorSurfaceVariant"
android:textSize="14sp"
android:gravity="start|center">
</TextView>

View file

@ -7,13 +7,13 @@
android:paddingVertical="10dp"
android:paddingHorizontal="20dp"
android:foreground="@drawable/rounded_selectable_item_background"
android:gravity="center">
android:gravity="top|center">
<com.google.android.material.card.MaterialCardView
android:id="@+id/preview"
android:layout_width="match_parent"
app:strokeColor="?colorSurfaceVariant"
android:layout_height="150dp">
android:layout_height="125dp">
</com.google.android.material.card.MaterialCardView>
@ -23,6 +23,7 @@
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"
android:gravity="center"
android:layout_margin="10dp"
android:text="@string/app_name"/>

View file

@ -75,4 +75,14 @@
<string name="pref_games_folders">Pastas de jogos</string>
<string name="import_folder">Adicionar pasta</string>
<string name="games_count_f">%d Jogos</string>
<string name="directory">Diretorio</string>
<string name="remove">Remover</string>
<string name="play">Jogar</string>
<string name="region">Região</string>
<string name="region_north_armerican">Estados Unidos</string>
<string name="region_japan">Japão</string>
<string name="region_europe">Europa</string>
<string name="region_australia">Australia</string>
<string name="region_korean">Coréia</string>
<string name="region_taiwan">Taiwan</string>
</resources>

View file

@ -83,4 +83,10 @@
<string name="remove">Remove</string>
<string name="play">Play</string>
<string name="region">Region</string>
<string name="region_north_armerican">North American</string>
<string name="region_japan">Japan</string>
<string name="region_europe">Europe</string>
<string name="region_australia">Australia</string>
<string name="region_korean">Korean</string>
<string name="region_taiwan">Taiwan</string>
</resources>