android: Use view binding
This commit is contained in:
		| @@ -8,11 +8,9 @@ import android.content.DialogInterface | ||||
| import android.content.Intent | ||||
| import android.graphics.Rect | ||||
| import android.os.Bundle | ||||
| import android.view.LayoutInflater | ||||
| import android.view.MotionEvent | ||||
| import android.view.View | ||||
| import android.view.WindowManager | ||||
| import android.widget.TextView | ||||
| import androidx.activity.OnBackPressedCallback | ||||
| import androidx.annotation.IntDef | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| @@ -21,10 +19,10 @@ import androidx.fragment.app.FragmentActivity | ||||
| import androidx.fragment.app.FragmentManager | ||||
| import androidx.preference.PreferenceManager | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||
| import com.google.android.material.slider.Slider | ||||
| import com.google.android.material.slider.Slider.OnChangeListener | ||||
| import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.DialogSliderBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Settings | ||||
| import org.yuzu.yuzu_emu.fragments.EmulationFragment | ||||
| import org.yuzu.yuzu_emu.fragments.MenuFragment | ||||
| @@ -139,27 +137,22 @@ open class EmulationActivity : AppCompatActivity() { | ||||
|     } | ||||
|  | ||||
|     private fun adjustScale() { | ||||
|         val inflater = LayoutInflater.from(this) | ||||
|         val view = inflater.inflate(R.layout.dialog_slider, null) | ||||
|         val slider = view.findViewById<Slider>(R.id.slider) | ||||
|         val textValue = view.findViewById<TextView>(R.id.text_value) | ||||
|         val units = view.findViewById<TextView>(R.id.text_units) | ||||
|  | ||||
|         slider.valueTo = 150F | ||||
|         slider.value = PreferenceManager.getDefaultSharedPreferences(applicationContext) | ||||
|         val sliderBinding = DialogSliderBinding.inflate(layoutInflater) | ||||
|         sliderBinding.slider.valueTo = 150F | ||||
|         sliderBinding.slider.value = PreferenceManager.getDefaultSharedPreferences(applicationContext) | ||||
|             .getInt(Settings.PREF_CONTROL_SCALE, 50).toFloat() | ||||
|         slider.addOnChangeListener(OnChangeListener { _, value, _ -> | ||||
|             textValue.text = value.toString() | ||||
|         sliderBinding.slider.addOnChangeListener(OnChangeListener { _, value, _ -> | ||||
|             sliderBinding.textValue.text = value.toString() | ||||
|             setControlScale(value.toInt()) | ||||
|         }) | ||||
|         textValue.text = slider.value.toString() | ||||
|         units.text = "%" | ||||
|         sliderBinding.textValue.text = sliderBinding.slider.value.toString() | ||||
|         sliderBinding.textUnits.text = "%" | ||||
|         MaterialAlertDialogBuilder(this) | ||||
|             .setTitle(R.string.emulation_control_scale) | ||||
|             .setView(view) | ||||
|             .setView(sliderBinding.root) | ||||
|             .setNegativeButton(android.R.string.cancel, null) | ||||
|             .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int -> | ||||
|                 setControlScale(slider.value.toInt()) | ||||
|                 setControlScale(sliderBinding.slider.value.toInt()) | ||||
|             } | ||||
|             .setNeutralButton(R.string.slider_default) { _: DialogInterface?, _: Int -> | ||||
|                 setControlScale(50) | ||||
|   | ||||
| @@ -24,6 +24,8 @@ import kotlinx.coroutines.withContext | ||||
| import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.activities.EmulationActivity.Companion.launch | ||||
| import org.yuzu.yuzu_emu.databinding.CardGameBinding | ||||
| import org.yuzu.yuzu_emu.model.Game | ||||
| import org.yuzu.yuzu_emu.model.GameDatabase | ||||
| import org.yuzu.yuzu_emu.utils.Log | ||||
| import org.yuzu.yuzu_emu.viewholders.GameViewHolder | ||||
| @@ -51,25 +53,24 @@ class GameAdapter(private val activity: AppCompatActivity) : RecyclerView.Adapte | ||||
|  | ||||
|     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameViewHolder { | ||||
|         // Create a new view. | ||||
|         val gameCard = LayoutInflater.from(parent.context) | ||||
|             .inflate(R.layout.card_game, parent, false) | ||||
|         gameCard.setOnClickListener(this) | ||||
|         val binding = CardGameBinding.inflate(LayoutInflater.from(parent.context)) | ||||
|         binding.root.setOnClickListener(this) | ||||
|  | ||||
|         // Use that view to create a ViewHolder. | ||||
|         return GameViewHolder(gameCard) | ||||
|         return GameViewHolder(binding) | ||||
|     } | ||||
|  | ||||
|     override fun onBindViewHolder(holder: GameViewHolder, position: Int) { | ||||
|         if (isDatasetValid) { | ||||
|             if (cursor!!.moveToPosition(position)) { | ||||
|                 holder.imageIcon.scaleType = ImageView.ScaleType.CENTER_CROP | ||||
|                 holder.binding.imageGameScreen.scaleType = ImageView.ScaleType.CENTER_CROP | ||||
|                 activity.lifecycleScope.launch { | ||||
|                     withContext(Dispatchers.IO) { | ||||
|                         val uri = | ||||
|                             Uri.parse(cursor!!.getString(GameDatabase.GAME_COLUMN_PATH)).toString() | ||||
|                         val bitmap = decodeGameIcon(uri) | ||||
|                         withContext(Dispatchers.Main) { | ||||
|                             holder.imageIcon.load(bitmap) { | ||||
|                             holder.binding.imageGameScreen.load(bitmap) { | ||||
|                                 error(R.drawable.no_icon) | ||||
|                                 crossfade(true) | ||||
|                             } | ||||
| @@ -77,20 +78,23 @@ class GameAdapter(private val activity: AppCompatActivity) : RecyclerView.Adapte | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 holder.textGameTitle.text = | ||||
|                 holder.binding.textGameTitle.text = | ||||
|                     cursor!!.getString(GameDatabase.GAME_COLUMN_TITLE) | ||||
|                         .replace("[\\t\\n\\r]+".toRegex(), " ") | ||||
|                 holder.textGameCaption.text = cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION) | ||||
|                 holder.binding.textGameCaption.text = cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION) | ||||
|  | ||||
|                 // TODO These shouldn't be necessary once the move to a DB-based model is complete. | ||||
|                 holder.gameId = cursor!!.getString(GameDatabase.GAME_COLUMN_GAME_ID) | ||||
|                 holder.path = cursor!!.getString(GameDatabase.GAME_COLUMN_PATH) | ||||
|                 holder.title = cursor!!.getString(GameDatabase.GAME_COLUMN_TITLE) | ||||
|                 holder.description = cursor!!.getString(GameDatabase.GAME_COLUMN_DESCRIPTION) | ||||
|                 holder.regions = cursor!!.getString(GameDatabase.GAME_COLUMN_REGIONS) | ||||
|                 holder.company = cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION) | ||||
|                 val game = Game( | ||||
|                     cursor!!.getString(GameDatabase.GAME_COLUMN_TITLE), | ||||
|                     cursor!!.getString(GameDatabase.GAME_COLUMN_DESCRIPTION), | ||||
|                     cursor!!.getString(GameDatabase.GAME_COLUMN_REGIONS), | ||||
|                     cursor!!.getString(GameDatabase.GAME_COLUMN_PATH), | ||||
|                     cursor!!.getString(GameDatabase.GAME_COLUMN_GAME_ID), | ||||
|                     cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION) | ||||
|                 ) | ||||
|                 holder.game = game | ||||
|                 val backgroundColorId = | ||||
|                     if (isValidGame(holder.path!!)) R.attr.colorSurface else R.attr.colorErrorContainer | ||||
|                     if (isValidGame(holder.game.path)) R.attr.colorSurface else R.attr.colorErrorContainer | ||||
|                 val itemView = holder.itemView | ||||
|                 itemView.setBackgroundColor( | ||||
|                     MaterialColors.getColor( | ||||
| @@ -177,7 +181,7 @@ class GameAdapter(private val activity: AppCompatActivity) : RecyclerView.Adapte | ||||
|      */ | ||||
|     override fun onClick(view: View) { | ||||
|         val holder = view.tag as GameViewHolder | ||||
|         launch((view.context as FragmentActivity), holder.path, holder.title) | ||||
|         launch((view.context as FragmentActivity), holder.game.path, holder.game.title) | ||||
|     } | ||||
|  | ||||
|     private fun isValidGame(path: String): Boolean { | ||||
|   | ||||
| @@ -9,7 +9,6 @@ import android.content.IntentFilter | ||||
| import android.os.Bundle | ||||
| import android.view.Menu | ||||
| import android.view.View | ||||
| import android.widget.FrameLayout | ||||
| import android.widget.Toast | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| @@ -18,11 +17,11 @@ import androidx.core.view.WindowCompat | ||||
| import androidx.core.view.WindowInsetsCompat | ||||
| import androidx.core.view.updatePadding | ||||
| import androidx.localbroadcastmanager.content.LocalBroadcastManager | ||||
| import com.google.android.material.appbar.AppBarLayout | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||
| import com.google.android.material.progressindicator.LinearProgressIndicator | ||||
| import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding | ||||
| import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Settings | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsFragment.Companion.newInstance | ||||
| import org.yuzu.yuzu_emu.utils.* | ||||
| @@ -31,11 +30,15 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { | ||||
|     private val presenter = SettingsActivityPresenter(this) | ||||
|     private var dialog: AlertDialog? = null | ||||
|  | ||||
|     private lateinit var binding: ActivitySettingsBinding | ||||
|  | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         ThemeHelper.setTheme(this) | ||||
|  | ||||
|         super.onCreate(savedInstanceState) | ||||
|         setContentView(R.layout.activity_settings) | ||||
|  | ||||
|         binding = ActivitySettingsBinding.inflate(layoutInflater) | ||||
|         setContentView(binding.root) | ||||
|  | ||||
|         WindowCompat.setDecorFitsSystemWindows(window, false) | ||||
|  | ||||
| @@ -45,7 +48,7 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { | ||||
|         presenter.onCreate(savedInstanceState, menuTag!!, gameID!!) | ||||
|  | ||||
|         // Show "Back" button in the action bar for navigation | ||||
|         setSupportActionBar(findViewById(R.id.toolbar_settings)) | ||||
|         setSupportActionBar(binding.toolbarSettings) | ||||
|         supportActionBar!!.setDisplayHomeAsUpEnabled(true) | ||||
|  | ||||
|         setInsets() | ||||
| @@ -138,13 +141,12 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { | ||||
|  | ||||
|     override fun showLoading() { | ||||
|         if (dialog == null) { | ||||
|             val root = layoutInflater.inflate(R.layout.dialog_progress_bar, null) | ||||
|             val progressBar = root.findViewById<LinearProgressIndicator>(R.id.progress_bar) | ||||
|             progressBar.isIndeterminate = true | ||||
|             val loadingBinding = DialogProgressBarBinding.inflate(layoutInflater) | ||||
|             loadingBinding.progressBar.isIndeterminate = true | ||||
|  | ||||
|             dialog = MaterialAlertDialogBuilder(this) | ||||
|                 .setTitle(R.string.load_settings) | ||||
|                 .setView(root) | ||||
|                 .setView(loadingBinding.root) | ||||
|                 .setCancelable(false) | ||||
|                 .create() | ||||
|         } | ||||
| @@ -195,12 +197,10 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { | ||||
|         get() = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as SettingsFragment? | ||||
|  | ||||
|     private fun setInsets() { | ||||
|         val appBar = findViewById<AppBarLayout>(R.id.appbar_settings) | ||||
|         val frame = findViewById<FrameLayout>(R.id.frame_content) | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(frame) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(binding.frameContent) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) | ||||
|             view.updatePadding(left = insets.left, right = insets.right) | ||||
|             InsetsHelper.insetAppBar(insets, appBar) | ||||
|             InsetsHelper.insetAppBar(insets, binding.appbarSettings) | ||||
|             windowInsets | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -9,7 +9,6 @@ import android.icu.util.Calendar | ||||
| import android.icu.util.TimeZone | ||||
| import android.text.format.DateFormat | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.TextView | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| @@ -20,6 +19,10 @@ import com.google.android.material.slider.Slider | ||||
| import com.google.android.material.timepicker.MaterialTimePicker | ||||
| import com.google.android.material.timepicker.TimeFormat | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.DialogSliderBinding | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingsHeaderBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.FloatSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.* | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.viewholder.* | ||||
| @@ -43,37 +46,29 @@ class SettingsAdapter( | ||||
|     } | ||||
|  | ||||
|     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SettingViewHolder { | ||||
|         val view: View | ||||
|         val inflater = LayoutInflater.from(parent.context) | ||||
|         return when (viewType) { | ||||
|             SettingsItem.TYPE_HEADER -> { | ||||
|                 view = inflater.inflate(R.layout.list_item_settings_header, parent, false) | ||||
|                 HeaderViewHolder(view, this) | ||||
|                 HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this) | ||||
|             } | ||||
|             SettingsItem.TYPE_CHECKBOX -> { | ||||
|                 view = inflater.inflate(R.layout.list_item_setting_switch, parent, false) | ||||
|                 SwitchSettingViewHolder(view, this) | ||||
|             SettingsItem.TYPE_SWITCH -> { | ||||
|                 SwitchSettingViewHolder(ListItemSettingSwitchBinding.inflate(inflater), this) | ||||
|             } | ||||
|             SettingsItem.TYPE_SINGLE_CHOICE, SettingsItem.TYPE_STRING_SINGLE_CHOICE -> { | ||||
|                 view = inflater.inflate(R.layout.list_item_setting, parent, false) | ||||
|                 SingleChoiceViewHolder(view, this) | ||||
|                 SingleChoiceViewHolder(ListItemSettingBinding.inflate(inflater), this) | ||||
|             } | ||||
|             SettingsItem.TYPE_SLIDER -> { | ||||
|                 view = inflater.inflate(R.layout.list_item_setting, parent, false) | ||||
|                 SliderViewHolder(view, this) | ||||
|                 SliderViewHolder(ListItemSettingBinding.inflate(inflater), this) | ||||
|             } | ||||
|             SettingsItem.TYPE_SUBMENU -> { | ||||
|                 view = inflater.inflate(R.layout.list_item_setting, parent, false) | ||||
|                 SubmenuViewHolder(view, this) | ||||
|                 SubmenuViewHolder(ListItemSettingBinding.inflate(inflater), this) | ||||
|             } | ||||
|             SettingsItem.TYPE_DATETIME_SETTING -> { | ||||
|                 view = inflater.inflate(R.layout.list_item_setting, parent, false) | ||||
|                 DateTimeViewHolder(view, this) | ||||
|                 DateTimeViewHolder(ListItemSettingBinding.inflate(inflater), this) | ||||
|             } | ||||
|             else -> { | ||||
|                 // TODO: Create an error view since we can't return null now | ||||
|                 view = inflater.inflate(R.layout.list_item_settings_header, parent, false) | ||||
|                 HeaderViewHolder(view, this) | ||||
|                 HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -191,15 +186,13 @@ class SettingsAdapter( | ||||
|         sliderProgress = item.selectedValue | ||||
|  | ||||
|         val inflater = LayoutInflater.from(context) | ||||
|         val sliderLayout = inflater.inflate(R.layout.dialog_slider, null) | ||||
|         val sliderView = sliderLayout.findViewById<Slider>(R.id.slider) | ||||
|         val sliderBinding = DialogSliderBinding.inflate(inflater) | ||||
|  | ||||
|         textSliderValue = sliderLayout.findViewById(R.id.text_value) | ||||
|         textSliderValue = sliderBinding.textValue | ||||
|         textSliderValue!!.text = sliderProgress.toString() | ||||
|         val units = sliderLayout.findViewById<TextView>(R.id.text_units) | ||||
|         units.text = item.units | ||||
|         sliderBinding.textUnits.text = item.units | ||||
|  | ||||
|         sliderView.apply { | ||||
|         sliderBinding.slider.apply { | ||||
|             valueFrom = item.min.toFloat() | ||||
|             valueTo = item.max.toFloat() | ||||
|             value = sliderProgress.toFloat() | ||||
| @@ -211,11 +204,11 @@ class SettingsAdapter( | ||||
|  | ||||
|         dialog = MaterialAlertDialogBuilder(context) | ||||
|             .setTitle(item.nameId) | ||||
|             .setView(sliderLayout) | ||||
|             .setView(sliderBinding.root) | ||||
|             .setPositiveButton(android.R.string.ok, this) | ||||
|             .setNegativeButton(android.R.string.cancel, defaultCancelListener) | ||||
|             .setNeutralButton(R.string.slider_default) { dialog: DialogInterface, which: Int -> | ||||
|                 sliderView.value = item.defaultValue.toFloat() | ||||
|                 sliderBinding.slider.value = item.defaultValue.toFloat() | ||||
|                 onClick(dialog, which) | ||||
|             } | ||||
|             .show() | ||||
|   | ||||
| @@ -14,9 +14,8 @@ import androidx.core.view.updatePadding | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.fragment.app.FragmentActivity | ||||
| import androidx.recyclerview.widget.LinearLayoutManager | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.google.android.material.divider.MaterialDividerItemDecoration | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Setting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Settings | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||||
| @@ -26,9 +25,10 @@ class SettingsFragment : Fragment(), SettingsFragmentView { | ||||
|  | ||||
|     private val presenter = SettingsFragmentPresenter(this) | ||||
|     private var activityView: SettingsActivityView? = null | ||||
|     private var adapter: SettingsAdapter? = null | ||||
|     private var settingsAdapter: SettingsAdapter? = null | ||||
|  | ||||
|     private lateinit var recyclerView: RecyclerView | ||||
|     private var _binding: FragmentSettingsBinding? = null | ||||
|     private val binding get() = _binding!! | ||||
|  | ||||
|     override fun onAttach(context: Context) { | ||||
|         super.onAttach(context) | ||||
| @@ -41,7 +41,6 @@ class SettingsFragment : Fragment(), SettingsFragmentView { | ||||
|         super.onCreate(savedInstanceState) | ||||
|         val menuTag = requireArguments().getString(ARGUMENT_MENU_TAG) | ||||
|         val gameId = requireArguments().getString(ARGUMENT_GAME_ID) | ||||
|         adapter = SettingsAdapter(this, requireActivity()) | ||||
|         presenter.onCreate(menuTag!!, gameId!!) | ||||
|     } | ||||
|  | ||||
| @@ -49,18 +48,20 @@ class SettingsFragment : Fragment(), SettingsFragmentView { | ||||
|         inflater: LayoutInflater, | ||||
|         container: ViewGroup?, | ||||
|         savedInstanceState: Bundle? | ||||
|     ): View? { | ||||
|         return inflater.inflate(R.layout.fragment_settings, container, false) | ||||
|     ): View { | ||||
|         _binding = FragmentSettingsBinding.inflate(layoutInflater) | ||||
|         return binding.root | ||||
|     } | ||||
|  | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         val manager = LinearLayoutManager(activity) | ||||
|         recyclerView = view.findViewById(R.id.list_settings) | ||||
|         recyclerView.adapter = adapter | ||||
|         recyclerView.layoutManager = manager | ||||
|         settingsAdapter = SettingsAdapter(this, requireActivity()) | ||||
|         val dividerDecoration = MaterialDividerItemDecoration(requireContext(), LinearLayoutManager.VERTICAL) | ||||
|         dividerDecoration.isLastItemDecorated = false | ||||
|         recyclerView.addItemDecoration(dividerDecoration) | ||||
|         binding.listSettings.apply { | ||||
|             adapter = settingsAdapter | ||||
|             layoutManager = LinearLayoutManager(activity) | ||||
|             addItemDecoration(dividerDecoration) | ||||
|         } | ||||
|         val activity = activity as SettingsActivityView? | ||||
|         presenter.onViewCreated(activity!!.settings) | ||||
|  | ||||
| @@ -70,8 +71,8 @@ class SettingsFragment : Fragment(), SettingsFragmentView { | ||||
|     override fun onDetach() { | ||||
|         super.onDetach() | ||||
|         activityView = null | ||||
|         if (adapter != null) { | ||||
|             adapter!!.closeDialog() | ||||
|         if (settingsAdapter != null) { | ||||
|             settingsAdapter!!.closeDialog() | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -86,7 +87,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView { | ||||
|     } | ||||
|  | ||||
|     override fun showSettingsList(settingsList: ArrayList<SettingsItem>) { | ||||
|         adapter!!.setSettings(settingsList) | ||||
|         settingsAdapter!!.setSettings(settingsList) | ||||
|     } | ||||
|  | ||||
|     override fun loadDefaultSettings() { | ||||
| @@ -114,7 +115,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView { | ||||
|     } | ||||
|  | ||||
|     private fun setInsets() { | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(recyclerView) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(binding.listSettings) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) | ||||
|             view.updatePadding(bottom = insets.bottom) | ||||
|             windowInsets | ||||
|   | ||||
| @@ -4,31 +4,23 @@ | ||||
| package org.yuzu.yuzu_emu.features.settings.ui.viewholder | ||||
|  | ||||
| import android.view.View | ||||
| import android.widget.TextView | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | ||||
|  | ||||
| class DateTimeViewHolder(itemView: View, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(itemView, adapter) { | ||||
| class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(binding.root, adapter) { | ||||
|     private lateinit var item: DateTimeSetting | ||||
|     private lateinit var textSettingName: TextView | ||||
|     private lateinit var textSettingDescription: TextView | ||||
|  | ||||
|     override fun findViews(root: View) { | ||||
|         textSettingName = root.findViewById(R.id.text_setting_name) | ||||
|         textSettingDescription = root.findViewById(R.id.text_setting_description) | ||||
|     } | ||||
|  | ||||
|     override fun bind(item: SettingsItem) { | ||||
|         this.item = item as DateTimeSetting | ||||
|         textSettingName.setText(item.nameId) | ||||
|         binding.textSettingName.setText(item.nameId) | ||||
|         if (item.descriptionId!! > 0) { | ||||
|             textSettingDescription.setText(item.descriptionId) | ||||
|             textSettingDescription.visibility = View.VISIBLE | ||||
|             binding.textSettingDescription.setText(item.descriptionId) | ||||
|             binding.textSettingDescription.visibility = View.VISIBLE | ||||
|         } else { | ||||
|             textSettingDescription.visibility = View.GONE | ||||
|             binding.textSettingDescription.visibility = View.GONE | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -4,25 +4,19 @@ | ||||
| package org.yuzu.yuzu_emu.features.settings.ui.viewholder | ||||
|  | ||||
| import android.view.View | ||||
| import android.widget.TextView | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingsHeaderBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | ||||
|  | ||||
| class HeaderViewHolder(itemView: View, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(itemView, adapter) { | ||||
|     private lateinit var headerName: TextView | ||||
| class HeaderViewHolder(val binding: ListItemSettingsHeaderBinding, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(binding.root, adapter) { | ||||
|  | ||||
|     init { | ||||
|         itemView.setOnClickListener(null) | ||||
|     } | ||||
|  | ||||
|     override fun findViews(root: View) { | ||||
|         headerName = root.findViewById(R.id.text_header_name) | ||||
|     } | ||||
|  | ||||
|     override fun bind(item: SettingsItem) { | ||||
|         headerName.setText(item.nameId) | ||||
|         binding.textHeaderName.setText(item.nameId) | ||||
|     } | ||||
|  | ||||
|     override fun onClick(clicked: View) { | ||||
|   | ||||
| @@ -13,16 +13,8 @@ abstract class SettingViewHolder(itemView: View, protected val adapter: Settings | ||||
|  | ||||
|     init { | ||||
|         itemView.setOnClickListener(this) | ||||
|         findViews(itemView) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets handles to all this ViewHolder's child views using their XML-defined identifiers. | ||||
|      * | ||||
|      * @param root The newly inflated top-level view. | ||||
|      */ | ||||
|     protected abstract fun findViews(root: View) | ||||
|  | ||||
|     /** | ||||
|      * Called by the adapter to set this ViewHolder's child views to display the list item | ||||
|      * it must now represent. | ||||
|   | ||||
| @@ -4,40 +4,32 @@ | ||||
| package org.yuzu.yuzu_emu.features.settings.ui.viewholder | ||||
|  | ||||
| import android.view.View | ||||
| import android.widget.TextView | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | ||||
|  | ||||
| class SingleChoiceViewHolder(itemView: View, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(itemView, adapter) { | ||||
| class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(binding.root, adapter) { | ||||
|     private lateinit var item: SettingsItem | ||||
|     private lateinit var textSettingName: TextView | ||||
|     private lateinit var textSettingDescription: TextView | ||||
|  | ||||
|     override fun findViews(root: View) { | ||||
|         textSettingName = root.findViewById(R.id.text_setting_name) | ||||
|         textSettingDescription = root.findViewById(R.id.text_setting_description) | ||||
|     } | ||||
|  | ||||
|     override fun bind(item: SettingsItem) { | ||||
|         this.item = item | ||||
|         textSettingName.setText(item.nameId) | ||||
|         textSettingDescription.visibility = View.VISIBLE | ||||
|         binding.textSettingName.setText(item.nameId) | ||||
|         binding.textSettingDescription.visibility = View.VISIBLE | ||||
|         if (item.descriptionId!! > 0) { | ||||
|             textSettingDescription.setText(item.descriptionId) | ||||
|             binding.textSettingDescription.setText(item.descriptionId) | ||||
|         } else if (item is SingleChoiceSetting) { | ||||
|             val resMgr = textSettingDescription.context.resources | ||||
|             val resMgr = binding.textSettingDescription.context.resources | ||||
|             val values = resMgr.getIntArray(item.valuesId) | ||||
|             for (i in values.indices) { | ||||
|                 if (values[i] == item.selectedValue) { | ||||
|                     textSettingDescription.text = resMgr.getStringArray(item.choicesId)[i] | ||||
|                     binding.textSettingDescription.text = resMgr.getStringArray(item.choicesId)[i] | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             textSettingDescription.visibility = View.GONE | ||||
|             binding.textSettingDescription.visibility = View.GONE | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -4,30 +4,23 @@ | ||||
| package org.yuzu.yuzu_emu.features.settings.ui.viewholder | ||||
|  | ||||
| import android.view.View | ||||
| import android.widget.TextView | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | ||||
|  | ||||
| class SliderViewHolder(itemView: View, adapter: SettingsAdapter) : SettingViewHolder(itemView, adapter) { | ||||
| class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(binding.root, adapter) { | ||||
|     private lateinit var item: SliderSetting | ||||
|     private lateinit var textSettingName: TextView | ||||
|     private lateinit var textSettingDescription: TextView | ||||
|  | ||||
|     override fun findViews(root: View) { | ||||
|         textSettingName = root.findViewById(R.id.text_setting_name) | ||||
|         textSettingDescription = root.findViewById(R.id.text_setting_description) | ||||
|     } | ||||
|  | ||||
|     override fun bind(item: SettingsItem) { | ||||
|         this.item = item as SliderSetting | ||||
|         textSettingName.setText(item.nameId) | ||||
|         binding.textSettingName.setText(item.nameId) | ||||
|         if (item.descriptionId!! > 0) { | ||||
|             textSettingDescription.setText(item.descriptionId) | ||||
|             textSettingDescription.visibility = View.VISIBLE | ||||
|             binding.textSettingDescription.setText(item.descriptionId) | ||||
|             binding.textSettingDescription.visibility = View.VISIBLE | ||||
|         } else { | ||||
|             textSettingDescription.visibility = View.GONE | ||||
|             binding.textSettingDescription.visibility = View.GONE | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -4,31 +4,23 @@ | ||||
| package org.yuzu.yuzu_emu.features.settings.ui.viewholder | ||||
|  | ||||
| import android.view.View | ||||
| import android.widget.TextView | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | ||||
|  | ||||
| class SubmenuViewHolder(itemView: View, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(itemView, adapter) { | ||||
| class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(binding.root, adapter) { | ||||
|     private lateinit var item: SubmenuSetting | ||||
|     private lateinit var textSettingName: TextView | ||||
|     private lateinit var textSettingDescription: TextView | ||||
|  | ||||
|     override fun findViews(root: View) { | ||||
|         textSettingName = root.findViewById(R.id.text_setting_name) | ||||
|         textSettingDescription = root.findViewById(R.id.text_setting_description) | ||||
|     } | ||||
|  | ||||
|     override fun bind(item: SettingsItem) { | ||||
|         this.item = item as SubmenuSetting | ||||
|         textSettingName.setText(item.nameId) | ||||
|         binding.textSettingName.setText(item.nameId) | ||||
|         if (item.descriptionId!! > 0) { | ||||
|             textSettingDescription.setText(item.descriptionId) | ||||
|             textSettingDescription.visibility = View.VISIBLE | ||||
|             binding.textSettingDescription.setText(item.descriptionId) | ||||
|             binding.textSettingDescription.visibility = View.VISIBLE | ||||
|         } else { | ||||
|             textSettingDescription.visibility = View.GONE | ||||
|             binding.textSettingDescription.visibility = View.GONE | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -5,43 +5,31 @@ package org.yuzu.yuzu_emu.features.settings.ui.viewholder | ||||
|  | ||||
| import android.view.View | ||||
| import android.widget.CompoundButton | ||||
| import android.widget.TextView | ||||
| import com.google.android.material.materialswitch.MaterialSwitch | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SwitchSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | ||||
|  | ||||
| class SwitchSettingViewHolder(itemView: View, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(itemView, adapter) { | ||||
|     private lateinit var item: SwitchSetting | ||||
|     private lateinit var textSettingName: TextView | ||||
|     private lateinit var textSettingDescription: TextView | ||||
|     private lateinit var switch: MaterialSwitch | ||||
|  | ||||
|     override fun findViews(root: View) { | ||||
|         textSettingName = root.findViewById(R.id.text_setting_name) | ||||
|         textSettingDescription = root.findViewById(R.id.text_setting_description) | ||||
|         switch = root.findViewById(R.id.switch_widget) | ||||
|     } | ||||
| class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter: SettingsAdapter) : | ||||
|     SettingViewHolder(binding.root, adapter) { | ||||
|  | ||||
|     override fun bind(item: SettingsItem) { | ||||
|         this.item = item as SwitchSetting | ||||
|         textSettingName.setText(item.nameId) | ||||
|         val setting = item as SwitchSetting | ||||
|         binding.textSettingName.setText(item.nameId) | ||||
|         if (item.descriptionId!! > 0) { | ||||
|             textSettingDescription.setText(item.descriptionId) | ||||
|             textSettingDescription.visibility = View.VISIBLE | ||||
|             binding.textSettingDescription.setText(item.descriptionId) | ||||
|             binding.textSettingDescription.visibility = View.VISIBLE | ||||
|         } else { | ||||
|             textSettingDescription.text = "" | ||||
|             textSettingDescription.visibility = View.GONE | ||||
|             binding.textSettingDescription.text = "" | ||||
|             binding.textSettingDescription.visibility = View.GONE | ||||
|         } | ||||
|         switch.isChecked = this.item.isChecked | ||||
|         switch.setOnCheckedChangeListener { _: CompoundButton, _: Boolean -> | ||||
|             adapter.onBooleanClick(item, bindingAdapterPosition, switch.isChecked) | ||||
|         binding.switchWidget.isChecked = setting.isChecked | ||||
|         binding.switchWidget.setOnCheckedChangeListener { _: CompoundButton, _: Boolean -> | ||||
|             adapter.onBooleanClick(item, bindingAdapterPosition, binding.switchWidget.isChecked) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun onClick(clicked: View) { | ||||
|         switch.toggle() | ||||
|         binding.switchWidget.toggle() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -10,8 +10,6 @@ import android.graphics.Color | ||||
| import android.os.Bundle | ||||
| import android.os.Handler | ||||
| import android.view.* | ||||
| import android.widget.Button | ||||
| import android.widget.TextView | ||||
| import android.widget.Toast | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.localbroadcastmanager.content.LocalBroadcastManager | ||||
| @@ -20,8 +18,8 @@ import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.YuzuApplication | ||||
| import org.yuzu.yuzu_emu.activities.EmulationActivity | ||||
| import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Settings | ||||
| import org.yuzu.yuzu_emu.overlay.InputOverlay | ||||
| import org.yuzu.yuzu_emu.utils.DirectoryInitialization | ||||
| import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState | ||||
| import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver | ||||
| @@ -29,13 +27,14 @@ import org.yuzu.yuzu_emu.utils.Log | ||||
|  | ||||
| class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.FrameCallback { | ||||
|     private lateinit var preferences: SharedPreferences | ||||
|     private var inputOverlay: InputOverlay? = null | ||||
|     private lateinit var emulationState: EmulationState | ||||
|     private var directoryStateReceiver: DirectoryStateReceiver? = null | ||||
|     private var emulationActivity: EmulationActivity? = null | ||||
|     private lateinit var perfStats: TextView | ||||
|     private var perfStatsUpdater: (() -> Unit)? = null | ||||
|  | ||||
|     private var _binding: FragmentEmulationBinding? = null | ||||
|     private val binding get() = _binding!! | ||||
|  | ||||
|     override fun onAttach(context: Context) { | ||||
|         super.onAttach(context) | ||||
|         if (context is EmulationActivity) { | ||||
| @@ -66,22 +65,19 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram | ||||
|         inflater: LayoutInflater, | ||||
|         container: ViewGroup?, | ||||
|         savedInstanceState: Bundle? | ||||
|     ): View? { | ||||
|         val contents = inflater.inflate(R.layout.fragment_emulation, container, false) | ||||
|         val surfaceView = contents.findViewById<SurfaceView>(R.id.surface_emulation) | ||||
|         surfaceView.holder.addCallback(this) | ||||
|         inputOverlay = contents.findViewById(R.id.surface_input_overlay) | ||||
|         perfStats = contents.findViewById(R.id.show_fps_text) | ||||
|         perfStats.setTextColor(Color.YELLOW) | ||||
|         val doneButton = contents.findViewById<Button>(R.id.done_control_config) | ||||
|         doneButton?.setOnClickListener { stopConfiguringControls() } | ||||
|     ): View { | ||||
|         _binding = FragmentEmulationBinding.inflate(layoutInflater) | ||||
|         return binding.root | ||||
|     } | ||||
|  | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         binding.surfaceEmulation.holder.addCallback(this) | ||||
|         binding.showFpsText.setTextColor(Color.YELLOW) | ||||
|         binding.doneControlConfig.setOnClickListener { stopConfiguringControls() } | ||||
|  | ||||
|         // Setup overlay. | ||||
|         resetInputOverlay() | ||||
|         updateShowFpsOverlay() | ||||
|  | ||||
|         // The new Surface created here will get passed to the native code via onSurfaceChanged. | ||||
|         return contents | ||||
|     } | ||||
|  | ||||
|     override fun onResume() { | ||||
| @@ -108,6 +104,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram | ||||
|         super.onPause() | ||||
|     } | ||||
|  | ||||
|     override fun onDestroyView() { | ||||
|         super.onDestroyView() | ||||
|         _binding = null | ||||
|     } | ||||
|  | ||||
|     override fun onDetach() { | ||||
|         NativeLibrary.clearEmulationActivity() | ||||
|         super.onDetach() | ||||
| @@ -144,7 +145,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram | ||||
|     } | ||||
|  | ||||
|     fun refreshInputOverlay() { | ||||
|         inputOverlay!!.refreshControls() | ||||
|         binding.surfaceInputOverlay.refreshControls() | ||||
|     } | ||||
|  | ||||
|     fun resetInputOverlay() { | ||||
| @@ -152,7 +153,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram | ||||
|         preferences.edit() | ||||
|             .putInt(Settings.PREF_CONTROL_SCALE, 50) | ||||
|             .apply() | ||||
|         inputOverlay!!.resetButtonPlacement() | ||||
|         binding.surfaceInputOverlay.resetButtonPlacement() | ||||
|     } | ||||
|  | ||||
|     private fun updateShowFpsOverlay() { | ||||
| @@ -165,17 +166,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram | ||||
|             perfStatsUpdater = { | ||||
|                 val perfStats = NativeLibrary.GetPerfStats() | ||||
|                 if (perfStats[FPS] > 0) { | ||||
|                     this.perfStats.text = String.format("FPS: %.1f", perfStats[FPS]) | ||||
|                     binding.showFpsText.text = String.format("FPS: %.1f", perfStats[FPS]) | ||||
|                 } | ||||
|                 perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 100) | ||||
|             } | ||||
|             perfStatsUpdateHandler.post(perfStatsUpdater!!) | ||||
|             perfStats.visibility = View.VISIBLE | ||||
|             binding.showFpsText.visibility = View.VISIBLE | ||||
|         } else { | ||||
|             if (perfStatsUpdater != null) { | ||||
|                 perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!) | ||||
|             } | ||||
|             perfStats.visibility = View.GONE | ||||
|             binding.showFpsText.visibility = View.GONE | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -203,18 +204,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram | ||||
|     } | ||||
|  | ||||
|     fun startConfiguringControls() { | ||||
|         requireView().findViewById<View>(R.id.done_control_config).visibility = | ||||
|             View.VISIBLE | ||||
|         inputOverlay!!.setIsInEditMode(true) | ||||
|         binding.doneControlConfig.visibility = View.VISIBLE | ||||
|         binding.surfaceInputOverlay.setIsInEditMode(true) | ||||
|     } | ||||
|  | ||||
|     fun stopConfiguringControls() { | ||||
|         requireView().findViewById<View>(R.id.done_control_config).visibility = View.GONE | ||||
|         inputOverlay!!.setIsInEditMode(false) | ||||
|         binding.doneControlConfig.visibility = View.GONE | ||||
|         binding.surfaceInputOverlay.setIsInEditMode(false) | ||||
|     } | ||||
|  | ||||
|     val isConfiguringControls: Boolean | ||||
|         get() = inputOverlay!!.isInEditMode | ||||
|         get() = binding.surfaceInputOverlay.isInEditMode | ||||
|  | ||||
|     private class EmulationState(private val mGamePath: String?) { | ||||
|         private var state: State | ||||
|   | ||||
| @@ -10,30 +10,29 @@ import android.os.Bundle | ||||
| import android.view.Menu | ||||
| import android.view.MenuItem | ||||
| import android.view.View | ||||
| import android.widget.FrameLayout | ||||
| import android.widget.Toast | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| import androidx.appcompat.widget.Toolbar | ||||
| import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen | ||||
| import androidx.core.view.ViewCompat | ||||
| import androidx.core.view.WindowCompat | ||||
| import androidx.core.view.WindowInsetsCompat | ||||
| import androidx.core.view.updatePadding | ||||
| import com.google.android.material.appbar.AppBarLayout | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||
| import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.activities.EmulationActivity | ||||
| import org.yuzu.yuzu_emu.databinding.ActivityMainBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity | ||||
| import org.yuzu.yuzu_emu.model.GameProvider | ||||
| import org.yuzu.yuzu_emu.ui.platform.PlatformGamesFragment | ||||
| import org.yuzu.yuzu_emu.utils.* | ||||
|  | ||||
| class MainActivity : AppCompatActivity(), MainView { | ||||
|     private lateinit var toolbar: Toolbar | ||||
|     private var platformGamesFragment: PlatformGamesFragment? = null | ||||
|     private val presenter = MainPresenter(this) | ||||
|  | ||||
|     private lateinit var binding: ActivityMainBinding | ||||
|  | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         val splashScreen = installSplashScreen() | ||||
|         splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady() } | ||||
| @@ -41,12 +40,13 @@ class MainActivity : AppCompatActivity(), MainView { | ||||
|         ThemeHelper.setTheme(this) | ||||
|  | ||||
|         super.onCreate(savedInstanceState) | ||||
|         setContentView(R.layout.activity_main) | ||||
|  | ||||
|         binding = ActivityMainBinding.inflate(layoutInflater) | ||||
|         setContentView(binding.root) | ||||
|  | ||||
|         WindowCompat.setDecorFitsSystemWindows(window, false) | ||||
|  | ||||
|         findViews() | ||||
|         setSupportActionBar(toolbar) | ||||
|         setSupportActionBar(binding.toolbarMain) | ||||
|         presenter.onCreate() | ||||
|         if (savedInstanceState == null) { | ||||
|             StartupHandler.handleInit(this) | ||||
| @@ -81,11 +81,6 @@ class MainActivity : AppCompatActivity(), MainView { | ||||
|         presenter.addDirIfNeeded(AddDirectoryHelper(this)) | ||||
|     } | ||||
|  | ||||
|     // TODO: Replace with view binding | ||||
|     private fun findViews() { | ||||
|         toolbar = findViewById(R.id.toolbar_main) | ||||
|     } | ||||
|  | ||||
|     override fun onCreateOptionsMenu(menu: Menu): Boolean { | ||||
|         menuInflater.inflate(R.menu.menu_game_grid, menu) | ||||
|         return true | ||||
| @@ -95,7 +90,7 @@ class MainActivity : AppCompatActivity(), MainView { | ||||
|      * MainView | ||||
|      */ | ||||
|     override fun setVersionString(version: String) { | ||||
|         toolbar.subtitle = version | ||||
|         binding.toolbarMain.subtitle = version | ||||
|     } | ||||
|  | ||||
|     override fun refresh() { | ||||
| @@ -247,12 +242,10 @@ class MainActivity : AppCompatActivity(), MainView { | ||||
|     } | ||||
|  | ||||
|     private fun setInsets() { | ||||
|         val appBar = findViewById<AppBarLayout>(R.id.appbar_main) | ||||
|         val frame = findViewById<FrameLayout>(R.id.games_platform_frame) | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(frame) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(binding.gamesPlatformFrame) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) | ||||
|             view.updatePadding(left = insets.left, right = insets.right) | ||||
|             InsetsHelper.insetAppBar(insets, appBar) | ||||
|             InsetsHelper.insetAppBar(insets, binding.appbarMain) | ||||
|             windowInsets | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -9,35 +9,33 @@ import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.view.ViewTreeObserver.OnGlobalLayoutListener | ||||
| import android.widget.TextView | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| import androidx.core.view.ViewCompat | ||||
| import androidx.core.view.WindowInsetsCompat | ||||
| import androidx.core.view.updatePadding | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.recyclerview.widget.GridLayoutManager | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import androidx.swiperefreshlayout.widget.SwipeRefreshLayout | ||||
| import com.google.android.material.color.MaterialColors | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.YuzuApplication | ||||
| import org.yuzu.yuzu_emu.adapters.GameAdapter | ||||
| import org.yuzu.yuzu_emu.databinding.FragmentGridBinding | ||||
|  | ||||
| class PlatformGamesFragment : Fragment(), PlatformGamesView { | ||||
|     private val presenter = PlatformGamesPresenter(this) | ||||
|     private var adapter: GameAdapter? = null | ||||
|     private lateinit var recyclerView: RecyclerView | ||||
|     private lateinit var textView: TextView | ||||
|  | ||||
|     private var _binding: FragmentGridBinding? = null | ||||
|     private val binding get() = _binding!! | ||||
|  | ||||
|     override fun onCreateView( | ||||
|         inflater: LayoutInflater, | ||||
|         container: ViewGroup?, | ||||
|         savedInstanceState: Bundle? | ||||
|     ): View? { | ||||
|         val rootView = inflater.inflate(R.layout.fragment_grid, container, false) | ||||
|         findViews(rootView) | ||||
|     ): View { | ||||
|         presenter.onCreateView() | ||||
|         return rootView | ||||
|         _binding = FragmentGridBinding.inflate(inflater) | ||||
|         return binding.root | ||||
|     } | ||||
|  | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
| @@ -58,30 +56,34 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView { | ||||
|                         } | ||||
|                         view.viewTreeObserver.removeOnGlobalLayoutListener(this) | ||||
|                         val layoutManager = GridLayoutManager(activity, columns) | ||||
|                         recyclerView.layoutManager = layoutManager | ||||
|                         recyclerView.adapter = adapter | ||||
|                         binding.gridGames.layoutManager = layoutManager | ||||
|                         binding.gridGames.adapter = adapter | ||||
|                     } | ||||
|                 }) | ||||
|         } | ||||
|  | ||||
|         // Add swipe down to refresh gesture | ||||
|         val pullToRefresh = view.findViewById<SwipeRefreshLayout>(R.id.swipe_refresh) | ||||
|         pullToRefresh.setOnRefreshListener { | ||||
|         binding.swipeRefresh.setOnRefreshListener { | ||||
|             refresh() | ||||
|             pullToRefresh.isRefreshing = false | ||||
|             binding.swipeRefresh.isRefreshing = false | ||||
|         } | ||||
|  | ||||
|         // Set theme color to the refresh animation's background | ||||
|         pullToRefresh.setProgressBackgroundColorSchemeColor( | ||||
|             MaterialColors.getColor(pullToRefresh, R.attr.colorPrimary) | ||||
|         binding.swipeRefresh.setProgressBackgroundColorSchemeColor( | ||||
|             MaterialColors.getColor(binding.swipeRefresh, R.attr.colorPrimary) | ||||
|         ) | ||||
|         pullToRefresh.setColorSchemeColors( | ||||
|             MaterialColors.getColor(pullToRefresh, R.attr.colorOnPrimary) | ||||
|         binding.swipeRefresh.setColorSchemeColors( | ||||
|             MaterialColors.getColor(binding.swipeRefresh, R.attr.colorOnPrimary) | ||||
|         ) | ||||
|  | ||||
|         setInsets() | ||||
|     } | ||||
|  | ||||
|     override fun onDestroyView() { | ||||
|         super.onDestroyView() | ||||
|         _binding = null | ||||
|     } | ||||
|  | ||||
|     override fun refresh() { | ||||
|         val databaseHelper = YuzuApplication.databaseHelper | ||||
|         databaseHelper!!.scanLibrary(databaseHelper.writableDatabase) | ||||
| @@ -97,17 +99,12 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView { | ||||
|     } | ||||
|  | ||||
|     private fun updateTextView() { | ||||
|         textView.visibility = | ||||
|         binding.gamelistEmptyText.visibility = | ||||
|             if (adapter!!.itemCount == 0) View.VISIBLE else View.GONE | ||||
|     } | ||||
|  | ||||
|     private fun findViews(root: View) { | ||||
|         recyclerView = root.findViewById(R.id.grid_games) | ||||
|         textView = root.findViewById(R.id.gamelist_empty_text) | ||||
|     } | ||||
|  | ||||
|     private fun setInsets() { | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(recyclerView) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(binding.gridGames) { view: View, windowInsets: WindowInsetsCompat -> | ||||
|             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) | ||||
|             view.updatePadding(bottom = insets.bottom) | ||||
|             windowInsets | ||||
|   | ||||
| @@ -3,33 +3,14 @@ | ||||
|  | ||||
| package org.yuzu.yuzu_emu.viewholders | ||||
|  | ||||
| import android.view.View | ||||
| import android.widget.ImageView | ||||
| import android.widget.TextView | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.databinding.CardGameBinding | ||||
| import org.yuzu.yuzu_emu.model.Game | ||||
|  | ||||
| /** | ||||
|  * A simple class that stores references to views so that the GameAdapter doesn't need to | ||||
|  * keep calling findViewById(), which is expensive. | ||||
|  */ | ||||
| class GameViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | ||||
|     var imageIcon: ImageView | ||||
|     var textGameTitle: TextView | ||||
|     var textGameCaption: TextView | ||||
|     var gameId: String? = null | ||||
|  | ||||
|     // TODO Not need any of this stuff. Currently only the properties dialog needs it. | ||||
|     var path: String? = null | ||||
|     var title: String? = null | ||||
|     var description: String? = null | ||||
|     var regions: String? = null | ||||
|     var company: String? = null | ||||
| class GameViewHolder(val binding: CardGameBinding) : RecyclerView.ViewHolder(binding.root) { | ||||
|     lateinit var game: Game | ||||
|  | ||||
|     init { | ||||
|         itemView.tag = this | ||||
|         imageIcon = itemView.findViewById(R.id.image_game_screen) | ||||
|         textGameTitle = itemView.findViewById(R.id.text_game_title) | ||||
|         textGameCaption = itemView.findViewById(R.id.text_game_caption) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user