Merge pull request #11163 from t895/convert-layout

Android: Replace spinners with dropdown menus
This commit is contained in:
JosJuice 2022-10-23 20:00:18 +02:00 committed by GitHub
commit 7743afddac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 279 additions and 255 deletions

View File

@ -4,7 +4,6 @@ package org.dolphinemu.dolphinemu.features.riivolution.ui;
import android.content.Context; import android.content.Context;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -49,18 +48,8 @@ public class RiivolutionAdapter extends RecyclerView.Adapter<RiivolutionViewHold
public RiivolutionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) public RiivolutionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{ {
LayoutInflater inflater = LayoutInflater.from(parent.getContext()); LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new RiivolutionViewHolder(
switch (viewType) inflater.inflate(R.layout.list_item_riivolution, parent, false));
{
case RiivolutionViewHolder.TYPE_HEADER:
View headerView = inflater.inflate(R.layout.list_item_riivolution_header, parent, false);
return new RiivolutionViewHolder(headerView);
case RiivolutionViewHolder.TYPE_OPTION:
View optionView = inflater.inflate(R.layout.list_item_riivolution_option, parent, false);
return new RiivolutionViewHolder(optionView);
default:
throw new UnsupportedOperationException();
}
} }
@Override @Override
@ -74,11 +63,4 @@ public class RiivolutionAdapter extends RecyclerView.Adapter<RiivolutionViewHold
{ {
return mItems.size(); return mItems.size();
} }
@Override
public int getItemViewType(int position)
{
return mItems.get(position).mOptionIndex != -1 ?
RiivolutionViewHolder.TYPE_OPTION : RiivolutionViewHolder.TYPE_HEADER;
}
} }

View File

@ -6,24 +6,23 @@ import android.content.Context;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.google.android.material.textfield.TextInputLayout;
import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches; import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches;
public class RiivolutionViewHolder extends RecyclerView.ViewHolder public class RiivolutionViewHolder extends RecyclerView.ViewHolder
implements AdapterView.OnItemSelectedListener implements AdapterView.OnItemClickListener
{ {
public static final int TYPE_HEADER = 0;
public static final int TYPE_OPTION = 1;
private final TextView mTextView; private final TextView mTextView;
private final Spinner mSpinner; private final TextInputLayout mChoiceLayout;
private final MaterialAutoCompleteTextView mChoiceDropdown;
private RiivolutionPatches mPatches; private RiivolutionPatches mPatches;
private RiivolutionItem mItem; private RiivolutionItem mItem;
@ -32,18 +31,34 @@ public class RiivolutionViewHolder extends RecyclerView.ViewHolder
super(itemView); super(itemView);
mTextView = itemView.findViewById(R.id.text_name); mTextView = itemView.findViewById(R.id.text_name);
mSpinner = itemView.findViewById(R.id.spinner_choice); mChoiceLayout = itemView.findViewById(R.id.layout_choice);
mChoiceDropdown = itemView.findViewById(R.id.dropdown_choice);
} }
public void bind(Context context, RiivolutionPatches patches, RiivolutionItem item) public void bind(Context context, RiivolutionPatches patches, RiivolutionItem item)
{ {
// TODO: Remove workaround for text filtering issue in material components when fixed
// https://github.com/material-components/material-components-android/issues/1464
mChoiceDropdown.setSaveEnabled(false);
String text; String text;
if (item.mOptionIndex != -1) if (item.mOptionIndex != -1)
{
mTextView.setVisibility(View.GONE);
text = patches.getOptionName(item.mDiscIndex, item.mSectionIndex, item.mOptionIndex); text = patches.getOptionName(item.mDiscIndex, item.mSectionIndex, item.mOptionIndex);
mChoiceLayout.setHint(text);
}
else if (item.mSectionIndex != -1) else if (item.mSectionIndex != -1)
{
mTextView.setTextAppearance(context, R.style.TextAppearance_AppCompat_Medium);
mChoiceLayout.setVisibility(View.GONE);
text = patches.getSectionName(item.mDiscIndex, item.mSectionIndex); text = patches.getSectionName(item.mDiscIndex, item.mSectionIndex);
}
else else
{
mChoiceLayout.setVisibility(View.GONE);
text = patches.getDiscName(item.mDiscIndex); text = patches.getDiscName(item.mDiscIndex);
}
mTextView.setText(text); mTextView.setText(text);
if (item.mOptionIndex != -1) if (item.mOptionIndex != -1)
@ -52,10 +67,10 @@ public class RiivolutionViewHolder extends RecyclerView.ViewHolder
mItem = item; mItem = item;
ArrayAdapter<String> adapter = new ArrayAdapter<>(context, ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
R.layout.list_item_riivolution_header); R.layout.support_simple_spinner_dropdown_item);
int choiceCount = patches.getChoiceCount(mItem.mDiscIndex, mItem.mSectionIndex, int choiceCount =
mItem.mOptionIndex); patches.getChoiceCount(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex);
adapter.add(context.getString(R.string.riivolution_disabled)); adapter.add(context.getString(R.string.riivolution_disabled));
for (int i = 0; i < choiceCount; i++) for (int i = 0; i < choiceCount; i++)
{ {
@ -63,21 +78,17 @@ public class RiivolutionViewHolder extends RecyclerView.ViewHolder
i)); i));
} }
mSpinner.setAdapter(adapter); mChoiceDropdown.setAdapter(adapter);
mSpinner.setSelection(patches.getSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mChoiceDropdown.setText(adapter.getItem(
mItem.mOptionIndex)); patches.getSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex)),
mSpinner.setOnItemSelectedListener(this); false);
mChoiceDropdown.setOnItemClickListener(this);
} }
} }
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{ {
mPatches.setSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex, position); mPatches.setSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex, position);
} }
@Override
public void onNothingSelected(AdapterView<?> parent)
{
}
} }

View File

@ -14,7 +14,6 @@ import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.Spinner;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
@ -23,6 +22,8 @@ import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator; import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.google.android.material.textfield.TextInputLayout;
import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.R;
@ -35,25 +36,19 @@ import java.util.ArrayList;
public class ConvertFragment extends Fragment implements View.OnClickListener public class ConvertFragment extends Fragment implements View.OnClickListener
{ {
private static class SpinnerValue implements AdapterView.OnItemSelectedListener private static class DropdownValue implements AdapterView.OnItemClickListener
{ {
private int mValuesId = -1; private int mValuesId = -1;
private int mCurrentPosition = -1; private int mCurrentPosition = 0;
private ArrayList<Runnable> mCallbacks = new ArrayList<>(); private ArrayList<Runnable> mCallbacks = new ArrayList<>();
@Override @Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{ {
if (mCurrentPosition != position) if (mCurrentPosition != position)
setPosition(position); setPosition(position);
} }
@Override
public void onNothingSelected(AdapterView<?> adapterView)
{
mCurrentPosition = -1;
}
int getPosition() int getPosition()
{ {
return mCurrentPosition; return mCurrentPosition;
@ -102,7 +97,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
private static final int REQUEST_CODE_SAVE_FILE = 0; private static final int REQUEST_CODE_SAVE_FILE = 0;
private static final int BLOB_TYPE_PLAIN = 0; private static final int BLOB_TYPE_ISO = 0;
private static final int BLOB_TYPE_GCZ = 3; private static final int BLOB_TYPE_GCZ = 3;
private static final int BLOB_TYPE_WIA = 7; private static final int BLOB_TYPE_WIA = 7;
private static final int BLOB_TYPE_RVZ = 8; private static final int BLOB_TYPE_RVZ = 8;
@ -114,10 +109,20 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
private static final int COMPRESSION_LZMA2 = 4; private static final int COMPRESSION_LZMA2 = 4;
private static final int COMPRESSION_ZSTD = 5; private static final int COMPRESSION_ZSTD = 5;
private SpinnerValue mFormat = new SpinnerValue(); private DropdownValue mFormat = new DropdownValue();
private SpinnerValue mBlockSize = new SpinnerValue(); private DropdownValue mBlockSize = new DropdownValue();
private SpinnerValue mCompression = new SpinnerValue(); private DropdownValue mCompression = new DropdownValue();
private SpinnerValue mCompressionLevel = new SpinnerValue(); private DropdownValue mCompressionLevel = new DropdownValue();
private TextInputLayout mFormatLayout;
private MaterialAutoCompleteTextView mFormatDropdown;
private TextInputLayout mBlockSizeLayout;
private MaterialAutoCompleteTextView mBlockSizeDropdown;
private TextInputLayout mCompressionLayout;
private MaterialAutoCompleteTextView mCompressionDropdown;
private TextInputLayout mCompressionLevelLayout;
private MaterialAutoCompleteTextView mCompressionLevelDropdown;
private CheckBox mRemoveJunkDataCheckbox;
private GameFile gameFile; private GameFile gameFile;
@ -142,7 +147,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) Bundle savedInstanceState)
{ {
return inflater.inflate(R.layout.fragment_convert, container, false); return inflater.inflate(R.layout.fragment_convert, container, false);
@ -151,6 +156,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
@Override @Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
{ {
findViews();
// TODO: Remove workaround for text filtering issue in material components when fixed
// https://github.com/material-components/material-components-android/issues/1464
mFormatDropdown.setSaveEnabled(false);
mBlockSizeDropdown.setSaveEnabled(false);
mCompressionDropdown.setSaveEnabled(false);
mCompressionLevelDropdown.setSaveEnabled(false);
populateFormats(); populateFormats();
populateBlockSize(); populateBlockSize();
populateCompression(); populateCompression();
@ -159,6 +173,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
mFormat.addCallback(this::populateBlockSize); mFormat.addCallback(this::populateBlockSize);
mFormat.addCallback(this::populateCompression); mFormat.addCallback(this::populateCompression);
mFormat.addCallback(this::populateCompressionLevel);
mCompression.addCallback(this::populateCompressionLevel); mCompression.addCallback(this::populateCompressionLevel);
mFormat.addCallback(this::populateRemoveJunkData); mFormat.addCallback(this::populateRemoveJunkData);
@ -166,19 +181,31 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
if (savedInstanceState != null) if (savedInstanceState != null)
{ {
setSpinnerSelection(R.id.spinner_format, mFormat, savedInstanceState.getInt(KEY_FORMAT)); setDropdownSelection(mFormatDropdown, mFormat, savedInstanceState.getInt(KEY_FORMAT));
setSpinnerSelection(R.id.spinner_block_size, mBlockSize, setDropdownSelection(mBlockSizeDropdown, mBlockSize,
savedInstanceState.getInt(KEY_BLOCK_SIZE)); savedInstanceState.getInt(KEY_BLOCK_SIZE));
setSpinnerSelection(R.id.spinner_compression, mCompression, setDropdownSelection(mCompressionDropdown, mCompression,
savedInstanceState.getInt(KEY_COMPRESSION)); savedInstanceState.getInt(KEY_COMPRESSION));
setSpinnerSelection(R.id.spinner_compression_level, mCompressionLevel, setDropdownSelection(mCompressionLevelDropdown, mCompressionLevel,
savedInstanceState.getInt(KEY_COMPRESSION_LEVEL)); savedInstanceState.getInt(KEY_COMPRESSION_LEVEL));
CheckBox removeJunkData = requireView().findViewById(R.id.checkbox_remove_junk_data); mRemoveJunkDataCheckbox.setChecked(savedInstanceState.getBoolean(KEY_REMOVE_JUNK_DATA));
removeJunkData.setChecked(savedInstanceState.getBoolean(KEY_REMOVE_JUNK_DATA));
} }
} }
private void findViews()
{
mFormatLayout = requireView().findViewById(R.id.format);
mFormatDropdown = requireView().findViewById(R.id.dropdown_format);
mBlockSizeLayout = requireView().findViewById(R.id.block_size);
mBlockSizeDropdown = requireView().findViewById(R.id.dropdown_block_size);
mCompressionLayout = requireView().findViewById(R.id.compression);
mCompressionDropdown = requireView().findViewById(R.id.dropdown_compression);
mCompressionLevelLayout = requireView().findViewById(R.id.compression_level);
mCompressionLevelDropdown = requireView().findViewById(R.id.dropdown_compression_level);
mRemoveJunkDataCheckbox = requireView().findViewById(R.id.checkbox_remove_junk_data);
}
@Override @Override
public void onSaveInstanceState(@NonNull Bundle outState) public void onSaveInstanceState(@NonNull Bundle outState)
{ {
@ -187,14 +214,17 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
outState.putInt(KEY_COMPRESSION, mCompression.getPosition()); outState.putInt(KEY_COMPRESSION, mCompression.getPosition());
outState.putInt(KEY_COMPRESSION_LEVEL, mCompressionLevel.getPosition()); outState.putInt(KEY_COMPRESSION_LEVEL, mCompressionLevel.getPosition());
CheckBox removeJunkData = requireView().findViewById(R.id.checkbox_remove_junk_data); outState.putBoolean(KEY_REMOVE_JUNK_DATA, mRemoveJunkDataCheckbox.isChecked());
outState.putBoolean(KEY_REMOVE_JUNK_DATA, removeJunkData.isChecked());
} }
private void setSpinnerSelection(int id, SpinnerValue valueWrapper, int i) private void setDropdownSelection(MaterialAutoCompleteTextView dropdown,
DropdownValue valueWrapper, int selection)
{ {
((Spinner) requireView().findViewById(id)).setSelection(i); if (dropdown.getAdapter() != null)
valueWrapper.setPosition(i); {
dropdown.setText(dropdown.getAdapter().getItem(selection).toString(), false);
}
valueWrapper.setPosition(selection);
} }
@Override @Override
@ -206,47 +236,41 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
joinThread(); joinThread();
} }
private Spinner populateSpinner(int spinnerId, int entriesId, int valuesId, private void populateDropdown(TextInputLayout layout, MaterialAutoCompleteTextView dropdown,
SpinnerValue valueWrapper) int entriesId, int valuesId, DropdownValue valueWrapper)
{ {
Spinner spinner = requireView().findViewById(spinnerId);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(requireContext(), ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(requireContext(),
entriesId, android.R.layout.simple_spinner_item); entriesId, R.layout.support_simple_spinner_dropdown_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); dropdown.setAdapter(adapter);
spinner.setAdapter(adapter);
spinner.setEnabled(spinner.getCount() > 1);
valueWrapper.populate(valuesId); valueWrapper.populate(valuesId);
valueWrapper.setPosition(spinner.getSelectedItemPosition()); dropdown.setOnItemClickListener(valueWrapper);
spinner.setOnItemSelectedListener(valueWrapper);
return spinner; layout.setEnabled(adapter.getCount() > 1);
} }
private Spinner clearSpinner(int spinnerId, SpinnerValue valueWrapper) private void clearDropdown(TextInputLayout layout, MaterialAutoCompleteTextView dropdown,
DropdownValue valueWrapper)
{ {
Spinner spinner = requireView().findViewById(spinnerId); dropdown.setAdapter(null);
layout.setEnabled(false);
spinner.setAdapter(null);
spinner.setEnabled(false);
valueWrapper.populate(-1); valueWrapper.populate(-1);
valueWrapper.setPosition(-1); valueWrapper.setPosition(0);
spinner.setOnItemSelectedListener(valueWrapper); dropdown.setText(null, false);
dropdown.setOnItemClickListener(valueWrapper);
return spinner;
} }
private void populateFormats() private void populateFormats()
{ {
Spinner spinner = populateSpinner(R.id.spinner_format, R.array.convertFormatEntries, populateDropdown(mFormatLayout, mFormatDropdown, R.array.convertFormatEntries,
R.array.convertFormatValues, mFormat); R.array.convertFormatValues, mFormat);
if (gameFile.getBlobType() == BLOB_TYPE_ISO)
if (gameFile.getBlobType() == BLOB_TYPE_PLAIN) {
spinner.setSelection(spinner.getCount() - 1); setDropdownSelection(mFormatDropdown, mFormat, mFormatDropdown.getAdapter().getCount() - 1);
}
mFormatDropdown.setText(mFormatDropdown.getAdapter().getItem(mFormat.getPosition()).toString(),
false);
} }
private void populateBlockSize() private void populateBlockSize()
@ -257,19 +281,25 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
// In the equivalent DolphinQt code, we have some logic for avoiding block sizes that can // In the equivalent DolphinQt code, we have some logic for avoiding block sizes that can
// trigger bugs in Dolphin versions older than 5.0-11893, but it was too annoying to port. // trigger bugs in Dolphin versions older than 5.0-11893, but it was too annoying to port.
// TODO: Port it? // TODO: Port it?
populateSpinner(R.id.spinner_block_size, R.array.convertBlockSizeGczEntries, populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeGczEntries,
R.array.convertBlockSizeGczValues, mBlockSize); R.array.convertBlockSizeGczValues, mBlockSize);
mBlockSize.setPosition(0);
mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(0).toString(), false);
break; break;
case BLOB_TYPE_WIA: case BLOB_TYPE_WIA:
populateSpinner(R.id.spinner_block_size, R.array.convertBlockSizeWiaEntries, populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeWiaEntries,
R.array.convertBlockSizeWiaValues, mBlockSize); R.array.convertBlockSizeWiaValues, mBlockSize);
mBlockSize.setPosition(0);
mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(0).toString(), false);
break; break;
case BLOB_TYPE_RVZ: case BLOB_TYPE_RVZ:
populateSpinner(R.id.spinner_block_size, R.array.convertBlockSizeRvzEntries, populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeRvzEntries,
R.array.convertBlockSizeRvzValues, mBlockSize).setSelection(2); R.array.convertBlockSizeRvzValues, mBlockSize);
mBlockSize.setPosition(2);
mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(2).toString(), false);
break; break;
default: default:
clearSpinner(R.id.spinner_block_size, mBlockSize); clearDropdown(mBlockSizeLayout, mBlockSizeDropdown, mBlockSize);
} }
} }
@ -278,19 +308,31 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
switch (mFormat.getValue(requireContext())) switch (mFormat.getValue(requireContext()))
{ {
case BLOB_TYPE_GCZ: case BLOB_TYPE_GCZ:
populateSpinner(R.id.spinner_compression, R.array.convertCompressionGczEntries, populateDropdown(mCompressionLayout, mCompressionDropdown,
R.array.convertCompressionGczValues, mCompression); R.array.convertCompressionGczEntries, R.array.convertCompressionGczValues,
mCompression);
mCompression.setPosition(0);
mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(0).toString(),
false);
break; break;
case BLOB_TYPE_WIA: case BLOB_TYPE_WIA:
populateSpinner(R.id.spinner_compression, R.array.convertCompressionWiaEntries, populateDropdown(mCompressionLayout, mCompressionDropdown,
R.array.convertCompressionWiaValues, mCompression); R.array.convertCompressionWiaEntries, R.array.convertCompressionWiaValues,
mCompression);
mCompression.setPosition(0);
mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(0).toString(),
false);
break; break;
case BLOB_TYPE_RVZ: case BLOB_TYPE_RVZ:
populateSpinner(R.id.spinner_compression, R.array.convertCompressionRvzEntries, populateDropdown(mCompressionLayout, mCompressionDropdown,
R.array.convertCompressionRvzValues, mCompression).setSelection(4); R.array.convertCompressionRvzEntries, R.array.convertCompressionRvzValues,
mCompression);
mCompression.setPosition(4);
mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(4).toString(),
false);
break; break;
default: default:
clearSpinner(R.id.spinner_compression, mCompression); clearDropdown(mCompressionLayout, mCompressionDropdown, mCompression);
} }
} }
@ -301,16 +343,24 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
case COMPRESSION_BZIP2: case COMPRESSION_BZIP2:
case COMPRESSION_LZMA: case COMPRESSION_LZMA:
case COMPRESSION_LZMA2: case COMPRESSION_LZMA2:
populateSpinner(R.id.spinner_compression_level, R.array.convertCompressionLevelEntries, populateDropdown(mCompressionLevelLayout, mCompressionLevelDropdown,
R.array.convertCompressionLevelValues, mCompressionLevel).setSelection(4); R.array.convertCompressionLevelEntries, R.array.convertCompressionLevelValues,
mCompressionLevel);
mCompressionLevel.setPosition(4);
mCompressionLevelDropdown.setText(
mCompressionLevelDropdown.getAdapter().getItem(4).toString(), false);
break; break;
case COMPRESSION_ZSTD: case COMPRESSION_ZSTD:
// TODO: Query DiscIO for the supported compression levels, like we do in DolphinQt? // TODO: Query DiscIO for the supported compression levels, like we do in DolphinQt?
populateSpinner(R.id.spinner_compression_level, R.array.convertCompressionLevelZstdEntries, populateDropdown(mCompressionLevelLayout, mCompressionLevelDropdown,
R.array.convertCompressionLevelZstdValues, mCompressionLevel).setSelection(4); R.array.convertCompressionLevelZstdEntries,
R.array.convertCompressionLevelZstdValues, mCompressionLevel);
mCompressionLevel.setPosition(4);
mCompressionLevelDropdown.setText(
mCompressionLevelDropdown.getAdapter().getItem(4).toString(), false);
break; break;
default: default:
clearSpinner(R.id.spinner_compression_level, mCompressionLevel); clearDropdown(mCompressionLevelLayout, mCompressionLevelDropdown, mCompressionLevel);
} }
} }
@ -319,22 +369,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
boolean scrubbingAllowed = mFormat.getValue(requireContext()) != BLOB_TYPE_RVZ && boolean scrubbingAllowed = mFormat.getValue(requireContext()) != BLOB_TYPE_RVZ &&
!gameFile.isDatelDisc(); !gameFile.isDatelDisc();
CheckBox removeJunkData = requireView().findViewById(R.id.checkbox_remove_junk_data); mRemoveJunkDataCheckbox.setEnabled(scrubbingAllowed);
removeJunkData.setEnabled(scrubbingAllowed);
if (!scrubbingAllowed) if (!scrubbingAllowed)
removeJunkData.setChecked(false); mRemoveJunkDataCheckbox.setChecked(false);
}
private boolean getRemoveJunkData()
{
CheckBox checkBoxScrub = requireView().findViewById(R.id.checkbox_remove_junk_data);
return checkBoxScrub.isChecked();
} }
@Override @Override
public void onClick(View view) public void onClick(View view)
{ {
boolean scrub = getRemoveJunkData(); boolean scrub = mRemoveJunkDataCheckbox.isChecked();
int format = mFormat.getValue(requireContext()); int format = mFormat.getValue(requireContext());
Runnable action = this::showSavePrompt; Runnable action = this::showSavePrompt;
@ -350,7 +393,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
action = addAreYouSureDialog(action, R.string.convert_warning_gcz); action = addAreYouSureDialog(action, R.string.convert_warning_gcz);
} }
if (scrub && format == BLOB_TYPE_PLAIN) if (scrub && format == BLOB_TYPE_ISO)
{ {
action = addAreYouSureDialog(action, R.string.convert_warning_iso); action = addAreYouSureDialog(action, R.string.convert_warning_iso);
} }
@ -381,7 +424,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
filename.setLength(dotIndex); filename.setLength(dotIndex);
switch (mFormat.getValue(requireContext())) switch (mFormat.getValue(requireContext()))
{ {
case BLOB_TYPE_PLAIN: case BLOB_TYPE_ISO:
filename.append(".iso"); filename.append(".iso");
break; break;
case BLOB_TYPE_GCZ: case BLOB_TYPE_GCZ:
@ -439,7 +482,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
boolean success = NativeLibrary.ConvertDiscImage(gameFile.getPath(), outPath, boolean success = NativeLibrary.ConvertDiscImage(gameFile.getPath(), outPath,
gameFile.getPlatform(), mFormat.getValue(context), mBlockSize.getValueOr(context, 0), gameFile.getPlatform(), mFormat.getValue(context), mBlockSize.getValueOr(context, 0),
mCompression.getValueOr(context, 0), mCompressionLevel.getValueOr(context, 0), mCompression.getValueOr(context, 0), mCompressionLevel.getValueOr(context, 0),
getRemoveJunkData(), (text, completion) -> mRemoveJunkDataCheckbox.isChecked(), (text, completion) ->
{ {
requireActivity().runOnUiThread(() -> requireActivity().runOnUiThread(() ->
{ {

View File

@ -1,123 +1,108 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView <com.google.android.material.textfield.TextInputLayout
android:id="@+id/label_format" style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="wrap_content" android:id="@+id/format"
android:layout_height="0dp" android:layout_width="match_parent"
android:text="@string/convert_format" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/spinner_format" android:hint="@string/convert_format"
app:layout_constraintBottom_toBottomOf="@id/spinner_format" app:layout_constraintTop_toTopOf="parent">
app:layout_constraintStart_toStartOf="parent" />
<TextView <com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/label_block_size" android:id="@+id/dropdown_format"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="wrap_content"
android:text="@string/convert_block_size" android:inputType="none" />
app:layout_constraintTop_toTopOf="@id/spinner_block_size"
app:layout_constraintBottom_toBottomOf="@id/spinner_block_size"
app:layout_constraintStart_toStartOf="parent" />
<TextView </com.google.android.material.textfield.TextInputLayout>
android:id="@+id/label_compression"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="@string/convert_compression"
app:layout_constraintTop_toTopOf="@id/spinner_compression"
app:layout_constraintBottom_toBottomOf="@id/spinner_compression"
app:layout_constraintStart_toStartOf="parent" />
<TextView <com.google.android.material.textfield.TextInputLayout
android:id="@+id/label_compression_level" style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="wrap_content" android:id="@+id/block_size"
android:layout_height="0dp" android:layout_width="match_parent"
android:text="@string/convert_compression_level" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/spinner_compression_level" android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="@id/spinner_compression_level" android:hint="@string/convert_block_size"
app:layout_constraintStart_toStartOf="parent" /> android:enabled="false"
app:layout_constraintTop_toBottomOf="@id/format">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_block_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:id="@+id/compression"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/convert_compression"
android:enabled="false"
app:layout_constraintTop_toBottomOf="@id/block_size">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_compression"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:id="@+id/compression_level"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/convert_compression_level"
android:enabled="false"
app:layout_constraintTop_toBottomOf="@id/compression">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_compression_level"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
<TextView <TextView
android:id="@+id/label_remove_junk_data" android:id="@+id/label_remove_junk_data"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="0dp"
android:gravity="center_vertical"
android:text="@string/convert_remove_junk_data" android:text="@string/convert_remove_junk_data"
android:layout_marginStart="@dimen/spacing_small"
app:layout_constraintTop_toTopOf="@id/checkbox_remove_junk_data" app:layout_constraintTop_toTopOf="@id/checkbox_remove_junk_data"
app:layout_constraintBottom_toBottomOf="@id/checkbox_remove_junk_data" app:layout_constraintBottom_toBottomOf="@id/checkbox_remove_junk_data"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/label_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="label_format,label_block_size,label_compression,label_compression_level" />
<Spinner
android:id="@+id/spinner_format"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:id="@+id/spinner_block_size"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_format" />
<Spinner
android:id="@+id/spinner_compression"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_block_size" />
<Spinner
android:id="@+id/spinner_compression_level"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_compression" />
<CheckBox <CheckBox
android:id="@+id/checkbox_remove_junk_data" android:id="@+id/checkbox_remove_junk_data"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@id/label_remove_junk_data"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_compression_level" /> app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintTop_toBottomOf="@id/compression_level" />
<Button <Button
android:id="@+id/button_convert" android:id="@+id/button_convert"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/convert_convert" android:text="@string/convert_convert"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/checkbox_remove_junk_data" /> app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/label_remove_junk_data" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/layout_choice"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginHorizontal="@dimen/spacing_large"
android:layout_marginStart="16dp"
android:layout_marginVertical="@dimen/spacing_medlarge"
android:layout_toStartOf="@+id/layout_choice"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
tools:text="Example Option" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/layout_choice"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="@dimen/spacing_medlarge"
android:layout_marginHorizontal="@dimen/spacing_large"
android:layout_marginTop="0dp">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_choice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text_name"
tools:text="Example Section"
android:paddingHorizontal="@dimen/spacing_large"
android:paddingVertical="@dimen/spacing_medlarge" />

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/text_name"
tools:text="Example Option"
android:layout_marginHorizontal="@dimen/spacing_large"
android:layout_marginVertical="@dimen/spacing_medlarge"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/spinner_choice"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/spinner_choice"
app:layout_constraintStart_toEndOf="@id/text_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>