Replace Deprecated Android Kotlin Extensions and Others

This commit is contained in:
Florian Märkl 2021-01-15 14:36:29 +01:00
commit 402782b4af
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
17 changed files with 215 additions and 184 deletions

View file

@ -1,6 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
def rootCMakeLists = "../../CMakeLists.txt"
@ -38,6 +38,9 @@ android {
}
}
}
buildFeatures {
viewBinding true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
@ -61,6 +64,7 @@ android {
}
}
Properties properties = new Properties()
def propertiesFile = file("../local.properties")
if (propertiesFile.exists()) {
@ -86,11 +90,6 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
}
}
androidExtensions {
// for @Parcelize
experimental = true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View file

@ -3,8 +3,7 @@ package com.metallic.chiaki.lib
import android.os.Parcelable
import android.util.Log
import android.view.Surface
import kotlinx.android.parcel.IgnoredOnParcel
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import java.lang.Exception
import java.net.InetSocketAddress
import kotlin.math.abs

View file

@ -3,6 +3,7 @@
package com.metallic.chiaki.main
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
@ -16,8 +17,8 @@ import com.metallic.chiaki.common.DiscoveredDisplayHost
import com.metallic.chiaki.common.DisplayHost
import com.metallic.chiaki.common.ManualDisplayHost
import com.metallic.chiaki.common.ext.inflate
import com.metallic.chiaki.databinding.ItemDisplayHostBinding
import com.metallic.chiaki.lib.DiscoveryHost
import kotlinx.android.synthetic.main.item_display_host.view.*
class DisplayHostDiffCallback(val old: List<DisplayHost>, val new: List<DisplayHost>): DiffUtil.Callback()
{
@ -42,10 +43,10 @@ class DisplayHostRecyclerViewAdapter(
diff.dispatchUpdatesTo(this)
}
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
class ViewHolder(val binding: ItemDisplayHostBinding): RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
= ViewHolder(parent.inflate(R.layout.item_display_host))
= ViewHolder(ItemDisplayHostBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun getItemCount() = hosts.count()
@ -53,7 +54,7 @@ class DisplayHostRecyclerViewAdapter(
{
val context = holder.itemView.context
val host = hosts[position]
holder.itemView.also {
holder.binding.also {
it.nameTextView.text = host.name
it.hostTextView.text = context.getString(R.string.display_host_host, host.host)
val id = host.id
@ -87,7 +88,7 @@ class DisplayHostRecyclerViewAdapter(
else -> R.drawable.ic_console
}
)
it.setOnClickListener { clickCallback(host) }
it.root.setOnClickListener { clickCallback(host) }
val canWakeup = host.registeredHost != null
val canEditDelete = host is ManualDisplayHost

View file

@ -17,52 +17,54 @@ import com.metallic.chiaki.R
import com.metallic.chiaki.common.*
import com.metallic.chiaki.common.ext.putRevealExtra
import com.metallic.chiaki.common.ext.viewModelFactory
import com.metallic.chiaki.databinding.ActivityMainBinding
import com.metallic.chiaki.lib.ConnectInfo
import com.metallic.chiaki.lib.DiscoveryHost
import com.metallic.chiaki.manualconsole.EditManualConsoleActivity
import com.metallic.chiaki.regist.RegistActivity
import com.metallic.chiaki.settings.SettingsActivity
import com.metallic.chiaki.stream.StreamActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity()
{
private lateinit var viewModel: MainViewModel
private lateinit var binding: ActivityMainBinding
private var discoveryMenuItem: MenuItem? = null
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
title = ""
setSupportActionBar(toolbar)
setSupportActionBar(binding.toolbar)
floatingActionButton.setOnClickListener {
expandFloatingActionButton(!floatingActionButton.isExpanded)
binding.floatingActionButton.setOnClickListener {
expandFloatingActionButton(!binding.floatingActionButton.isExpanded)
}
floatingActionButtonDialBackground.setOnClickListener {
binding.floatingActionButtonDialBackground.setOnClickListener {
expandFloatingActionButton(false)
}
addManualButton.setOnClickListener { addManualConsole() }
addManualLabelButton.setOnClickListener { addManualConsole() }
binding.addManualButton.setOnClickListener { addManualConsole() }
binding.addManualLabelButton.setOnClickListener { addManualConsole() }
registerButton.setOnClickListener { showRegistration() }
registerLabelButton.setOnClickListener { showRegistration() }
binding.registerButton.setOnClickListener { showRegistration() }
binding.registerLabelButton.setOnClickListener { showRegistration() }
viewModel = ViewModelProvider(this, viewModelFactory { MainViewModel(getDatabase(this), Preferences(this)) })
.get(MainViewModel::class.java)
val recyclerViewAdapter = DisplayHostRecyclerViewAdapter(this::hostTriggered, this::wakeupHost, this::editHost, this::deleteHost)
hostsRecyclerView.adapter = recyclerViewAdapter
hostsRecyclerView.layoutManager = LinearLayoutManager(this)
binding.hostsRecyclerView.adapter = recyclerViewAdapter
binding.hostsRecyclerView.layoutManager = LinearLayoutManager(this)
viewModel.displayHosts.observe(this, Observer {
val top = hostsRecyclerView.computeVerticalScrollOffset() == 0
val top = binding.hostsRecyclerView.computeVerticalScrollOffset() == 0
recyclerViewAdapter.hosts = it
if(top)
hostsRecyclerView.scrollToPosition(0)
binding.hostsRecyclerView.scrollToPosition(0)
updateEmptyInfo()
})
@ -76,19 +78,19 @@ class MainActivity : AppCompatActivity()
{
if(viewModel.displayHosts.value?.isEmpty() ?: true)
{
emptyInfoLayout.visibility = View.VISIBLE
binding.emptyInfoLayout.visibility = View.VISIBLE
val discoveryActive = viewModel.discoveryActive.value ?: false
emptyInfoImageView.setImageResource(if(discoveryActive) R.drawable.ic_discover_on else R.drawable.ic_discover_off)
emptyInfoTextView.setText(if(discoveryActive) R.string.display_hosts_empty_discovery_on_info else R.string.display_hosts_empty_discovery_off_info)
binding.emptyInfoImageView.setImageResource(if(discoveryActive) R.drawable.ic_discover_on else R.drawable.ic_discover_off)
binding.emptyInfoTextView.setText(if(discoveryActive) R.string.display_hosts_empty_discovery_on_info else R.string.display_hosts_empty_discovery_off_info)
}
else
emptyInfoLayout.visibility = View.GONE
binding.emptyInfoLayout.visibility = View.GONE
}
private fun expandFloatingActionButton(expand: Boolean)
{
floatingActionButton.isExpanded = expand
floatingActionButton.isActivated = floatingActionButton.isExpanded
binding.floatingActionButton.isExpanded = expand
binding.floatingActionButton.isActivated = binding.floatingActionButton.isExpanded
}
override fun onStart()
@ -105,7 +107,7 @@ class MainActivity : AppCompatActivity()
override fun onBackPressed()
{
if(floatingActionButton.isExpanded)
if(binding.floatingActionButton.isExpanded)
{
expandFloatingActionButton(false)
return
@ -151,7 +153,7 @@ class MainActivity : AppCompatActivity()
private fun addManualConsole()
{
Intent(this, EditManualConsoleActivity::class.java).also {
it.putRevealExtra(addManualButton, rootLayout)
it.putRevealExtra(binding.addManualButton, binding.rootLayout)
startActivity(it, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
}
}
@ -159,7 +161,7 @@ class MainActivity : AppCompatActivity()
private fun showRegistration()
{
Intent(this, RegistActivity::class.java).also {
it.putRevealExtra(registerButton, rootLayout)
it.putRevealExtra(binding.registerButton, binding.rootLayout)
startActivity(it, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
}
}

View file

@ -16,10 +16,10 @@ import com.metallic.chiaki.common.RegisteredHost
import com.metallic.chiaki.common.ext.RevealActivity
import com.metallic.chiaki.common.ext.viewModelFactory
import com.metallic.chiaki.common.getDatabase
import com.metallic.chiaki.databinding.ActivityEditManualBinding
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import kotlinx.android.synthetic.main.activity_edit_manual.*
class EditManualConsoleActivity: AppCompatActivity(), RevealActivity
{
@ -28,18 +28,20 @@ class EditManualConsoleActivity: AppCompatActivity(), RevealActivity
const val EXTRA_MANUAL_HOST_ID = "manual_host_id"
}
override val revealIntent: Intent get() = intent
override val revealRootLayout: View get() = rootLayout
override val revealWindow: Window get() = window
private lateinit var viewModel: EditManualConsoleViewModel
private lateinit var binding: ActivityEditManualBinding
override val revealIntent: Intent get() = intent
override val revealRootLayout: View get() = binding.rootLayout
override val revealWindow: Window get() = window
private val disposable = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit_manual)
binding = ActivityEditManualBinding.inflate(layoutInflater)
setContentView(binding.root)
handleReveal()
viewModel = ViewModelProvider(this, viewModelFactory {
@ -52,17 +54,17 @@ class EditManualConsoleActivity: AppCompatActivity(), RevealActivity
.get(EditManualConsoleViewModel::class.java)
viewModel.existingHost?.observe(this, Observer {
hostEditText.setText(it.host)
binding.hostEditText.setText(it.host)
})
viewModel.selectedRegisteredHost.observe(this, Observer {
registeredHostTextView.setText(titleForRegisteredHost(it))
binding.registeredHostTextView.setText(titleForRegisteredHost(it))
})
viewModel.registeredHosts.observe(this, Observer { hosts ->
registeredHostTextView.setAdapter(ArrayAdapter<String>(this, R.layout.dropdown_menu_popup_item,
binding.registeredHostTextView.setAdapter(ArrayAdapter<String>(this, R.layout.dropdown_menu_popup_item,
hosts.map { titleForRegisteredHost(it) }))
registeredHostTextView.onItemClickListener = object: AdapterView.OnItemClickListener {
binding.registeredHostTextView.onItemClickListener = object: AdapterView.OnItemClickListener {
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long)
{
if(position >= hosts.size)
@ -73,8 +75,7 @@ class EditManualConsoleActivity: AppCompatActivity(), RevealActivity
}
})
saveButton.setOnClickListener { saveHost() }
binding.saveButton.setOnClickListener { saveHost() }
}
private fun titleForRegisteredHost(registeredHost: RegisteredHost?) =
@ -85,14 +86,14 @@ class EditManualConsoleActivity: AppCompatActivity(), RevealActivity
private fun saveHost()
{
val host = hostEditText.text.toString().trim()
val host = binding.hostEditText.text.toString().trim()
if(host.isEmpty())
{
hostEditText.error = getString(R.string.entered_host_invalid)
binding.hostEditText.error = getString(R.string.entered_host_invalid)
return
}
saveButton.isEnabled = false
binding.saveButton.isEnabled = false
viewModel.saveHost(host)
.observeOn(AndroidSchedulers.mainThread())
.subscribe {

View file

@ -12,9 +12,9 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.metallic.chiaki.R
import com.metallic.chiaki.common.ext.RevealActivity
import com.metallic.chiaki.databinding.ActivityRegistBinding
import com.metallic.chiaki.lib.RegistInfo
import com.metallic.chiaki.lib.Target
import kotlinx.android.synthetic.main.activity_regist.*
import java.lang.IllegalArgumentException
class RegistActivity: AppCompatActivity(), RevealActivity
@ -30,33 +30,35 @@ class RegistActivity: AppCompatActivity(), RevealActivity
private const val REQUEST_REGIST = 1
}
private lateinit var viewModel: RegistViewModel
private lateinit var binding: ActivityRegistBinding
override val revealWindow: Window get() = window
override val revealIntent: Intent get() = intent
override val revealRootLayout: View get() = rootLayout
private lateinit var viewModel: RegistViewModel
override val revealRootLayout: View get() = binding.rootLayout
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
binding = ActivityRegistBinding.inflate(layoutInflater)
setContentView(R.layout.activity_regist)
handleReveal()
viewModel = ViewModelProvider(this).get(RegistViewModel::class.java)
hostEditText.setText(intent.getStringExtra(EXTRA_HOST) ?: "255.255.255.255")
broadcastCheckBox.isChecked = intent.getBooleanExtra(EXTRA_BROADCAST, true)
binding.hostEditText.setText(intent.getStringExtra(EXTRA_HOST) ?: "255.255.255.255")
binding.broadcastCheckBox.isChecked = intent.getBooleanExtra(EXTRA_BROADCAST, true)
registButton.setOnClickListener { doRegist() }
binding.registButton.setOnClickListener { doRegist() }
ps4VersionRadioGroup.check(when(viewModel.ps4Version.value ?: RegistViewModel.ConsoleVersion.PS5) {
binding.ps4VersionRadioGroup.check(when(viewModel.ps4Version.value ?: RegistViewModel.ConsoleVersion.PS5) {
RegistViewModel.ConsoleVersion.PS5 -> R.id.ps5RadioButton
RegistViewModel.ConsoleVersion.PS4_GE_8 -> R.id.ps4VersionGE8RadioButton
RegistViewModel.ConsoleVersion.PS4_GE_7 -> R.id.ps4VersionGE7RadioButton
RegistViewModel.ConsoleVersion.PS4_LT_7 -> R.id.ps4VersionLT7RadioButton
})
ps4VersionRadioGroup.setOnCheckedChangeListener { _, checkedId ->
binding.ps4VersionRadioGroup.setOnCheckedChangeListener { _, checkedId ->
viewModel.ps4Version.value = when(checkedId)
{
R.id.ps5RadioButton -> RegistViewModel.ConsoleVersion.PS5
@ -68,14 +70,14 @@ class RegistActivity: AppCompatActivity(), RevealActivity
}
viewModel.ps4Version.observe(this, Observer {
psnAccountIdHelpGroup.visibility = if(it == RegistViewModel.ConsoleVersion.PS4_LT_7) View.GONE else View.VISIBLE
psnIdTextInputLayout.hint = getString(when(it!!)
binding.psnAccountIdHelpGroup.visibility = if(it == RegistViewModel.ConsoleVersion.PS4_LT_7) View.GONE else View.VISIBLE
binding.psnIdTextInputLayout.hint = getString(when(it!!)
{
RegistViewModel.ConsoleVersion.PS4_LT_7 -> R.string.hint_regist_psn_online_id
else -> R.string.hint_regist_psn_account_id
})
pinHelpBeforeTextView.setText(if(it.isPS5) R.string.regist_pin_instructions_ps5_before else R.string.regist_pin_instructions_ps4_before)
pinHelpNavigationTextView.setText(if(it.isPS5) R.string.regist_pin_instructions_ps5_navigation else R.string.regist_pin_instructions_ps4_navigation)
binding.pinHelpBeforeTextView.setText(if(it.isPS5) R.string.regist_pin_instructions_ps5_before else R.string.regist_pin_instructions_ps4_before)
binding.pinHelpNavigationTextView.setText(if(it.isPS5) R.string.regist_pin_instructions_ps5_navigation else R.string.regist_pin_instructions_ps4_navigation)
})
}
@ -83,11 +85,11 @@ class RegistActivity: AppCompatActivity(), RevealActivity
{
val ps4Version = viewModel.ps4Version.value ?: RegistViewModel.ConsoleVersion.PS5
val host = hostEditText.text.toString().trim()
val host = binding.hostEditText.text.toString().trim()
val hostValid = host.isNotEmpty()
val broadcast = broadcastCheckBox.isChecked
val broadcast = binding.broadcastCheckBox.isChecked
val psnId = psnIdEditText.text.toString().trim()
val psnId = binding.psnIdEditText.text.toString().trim()
val psnOnlineId: String? = if(ps4Version == RegistViewModel.ConsoleVersion.PS4_LT_7) psnId else null
val psnAccountId: ByteArray? =
if(ps4Version != RegistViewModel.ConsoleVersion.PS4_LT_7)
@ -101,11 +103,11 @@ class RegistActivity: AppCompatActivity(), RevealActivity
}
val pin = pinEditText.text.toString()
val pin = binding.pinEditText.text.toString()
val pinValid = pin.length == PIN_LENGTH
hostEditText.error = if(!hostValid) getString(R.string.entered_host_invalid) else null
psnIdEditText.error =
binding.hostEditText.error = if(!hostValid) getString(R.string.entered_host_invalid) else null
binding.psnIdEditText.error =
if(!psnIdValid)
getString(when(ps4Version)
{
@ -114,7 +116,7 @@ class RegistActivity: AppCompatActivity(), RevealActivity
})
else
null
pinEditText.error = if(!pinValid) getString(R.string.regist_pin_invalid, PIN_LENGTH) else null
binding.pinEditText.error = if(!pinValid) getString(R.string.regist_pin_invalid, PIN_LENGTH) else null
if(!hostValid || !psnIdValid || !pinValid)
return

View file

@ -16,8 +16,8 @@ import com.metallic.chiaki.R
import com.metallic.chiaki.common.MacAddress
import com.metallic.chiaki.common.ext.viewModelFactory
import com.metallic.chiaki.common.getDatabase
import com.metallic.chiaki.databinding.ActivityRegistExecuteBinding
import com.metallic.chiaki.lib.RegistInfo
import kotlinx.android.synthetic.main.activity_regist_execute.*
import kotlin.math.max
class RegistExecuteActivity: AppCompatActivity()
@ -31,55 +31,57 @@ class RegistExecuteActivity: AppCompatActivity()
}
private lateinit var viewModel: RegistExecuteViewModel
private lateinit var binding: ActivityRegistExecuteBinding
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_regist_execute)
binding = ActivityRegistExecuteBinding.inflate(layoutInflater)
setContentView(binding.root)
viewModel = ViewModelProvider(this, viewModelFactory { RegistExecuteViewModel(getDatabase(this)) })
.get(RegistExecuteViewModel::class.java)
logTextView.setHorizontallyScrolling(true)
logTextView.movementMethod = ScrollingMovementMethod()
binding.logTextView.setHorizontallyScrolling(true)
binding.logTextView.movementMethod = ScrollingMovementMethod()
viewModel.logText.observe(this, Observer {
val textLayout = logTextView.layout ?: return@Observer
val textLayout = binding.logTextView.layout ?: return@Observer
val lineCount = textLayout.lineCount
if(lineCount < 1)
return@Observer
logTextView.text = it
val scrollY = textLayout.getLineBottom(lineCount - 1) - logTextView.height + logTextView.paddingTop + logTextView.paddingBottom
logTextView.scrollTo(0, max(scrollY, 0))
binding.logTextView.text = it
val scrollY = textLayout.getLineBottom(lineCount - 1) - binding.logTextView.height + binding.logTextView.paddingTop + binding.logTextView.paddingBottom
binding.logTextView.scrollTo(0, max(scrollY, 0))
})
viewModel.state.observe(this, Observer {
progressBar.visibility = if(it == RegistExecuteViewModel.State.RUNNING) View.VISIBLE else View.GONE
binding.progressBar.visibility = if(it == RegistExecuteViewModel.State.RUNNING) View.VISIBLE else View.GONE
when(it)
{
RegistExecuteViewModel.State.FAILED ->
{
infoTextView.visibility = View.VISIBLE
infoTextView.setText(R.string.regist_info_failed)
binding.infoTextView.visibility = View.VISIBLE
binding.infoTextView.setText(R.string.regist_info_failed)
setResult(RESULT_FAILED)
}
RegistExecuteViewModel.State.SUCCESSFUL, RegistExecuteViewModel.State.SUCCESSFUL_DUPLICATE ->
{
infoTextView.visibility = View.VISIBLE
infoTextView.setText(R.string.regist_info_success)
binding.infoTextView.visibility = View.VISIBLE
binding.infoTextView.setText(R.string.regist_info_success)
setResult(RESULT_OK)
if(it == RegistExecuteViewModel.State.SUCCESSFUL_DUPLICATE)
showDuplicateDialog()
}
RegistExecuteViewModel.State.STOPPED ->
{
infoTextView.visibility = View.GONE
binding.infoTextView.visibility = View.GONE
setResult(Activity.RESULT_CANCELED)
}
else -> infoTextView.visibility = View.GONE
else -> binding.infoTextView.visibility = View.GONE
}
})
shareLogButton.setOnClickListener {
binding.shareLogButton.setOnClickListener {
val log = viewModel.logText.value ?: ""
Intent(Intent.ACTION_SEND).also {
it.type = "text/plain"

View file

@ -19,6 +19,7 @@ class StreamInput(val context: Context, val preferences: Preferences)
val controllerState = sensorControllerState or keyControllerState or motionControllerState
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
@Suppress("DEPRECATION")
when(windowManager.defaultDisplay.rotation)
{
Surface.ROTATION_90 -> {
@ -175,7 +176,7 @@ class StreamInput(val context: Context, val preferences: Preferences)
{
if(event.source and InputDevice.SOURCE_CLASS_JOYSTICK != InputDevice.SOURCE_CLASS_JOYSTICK)
return false
fun Float.signedAxis() = (this * Short.MAX_VALUE).toShort()
fun Float.signedAxis() = (this * Short.MAX_VALUE).toInt().toShort()
fun Float.unsignedAxis() = (this * UByte.MAX_VALUE.toFloat()).toUInt().toUByte()
motionControllerState.leftX = event.getAxisValue(MotionEvent.AXIS_X).signedAxis()
motionControllerState.leftY = event.getAxisValue(MotionEvent.AXIS_Y).signedAxis()

View file

@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.metallic.chiaki.R
import kotlinx.android.synthetic.main.activity_settings.*
import com.metallic.chiaki.databinding.ActivitySettingsBinding
interface TitleFragment
{
@ -18,20 +18,23 @@ interface TitleFragment
class SettingsActivity: AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback
{
private lateinit var binding: ActivitySettingsBinding
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
binding = ActivitySettingsBinding.inflate(layoutInflater)
setContentView(binding.root)
title = ""
setSupportActionBar(toolbar)
setSupportActionBar(binding.toolbar)
val rootFragment = SettingsFragment()
replaceFragment(rootFragment, false)
supportFragmentManager.addOnBackStackChangedListener {
val titleFragment = supportFragmentManager.findFragmentById(R.id.settingsFragment) as? TitleFragment ?: return@addOnBackStackChangedListener
titleTextView.text = titleFragment.getTitle(resources)
binding.titleTextView.text = titleFragment.getTitle(resources)
}
titleTextView.text = rootFragment.getTitle(resources)
binding.titleTextView.text = rootFragment.getTitle(resources)
}
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference) = when(pref.fragment)

View file

@ -16,7 +16,6 @@ import com.metallic.chiaki.common.exportAndShareAllSettings
import com.metallic.chiaki.common.ext.viewModelFactory
import com.metallic.chiaki.common.getDatabase
import com.metallic.chiaki.common.importSettingsFromUri
import com.metallic.chiaki.lib.Codec
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo

View file

@ -2,13 +2,13 @@
package com.metallic.chiaki.settings
import android.view.View
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.metallic.chiaki.R
import com.metallic.chiaki.common.LogFile
import com.metallic.chiaki.common.ext.inflate
import kotlinx.android.synthetic.main.item_log_file.view.*
import com.metallic.chiaki.databinding.ItemLogFileBinding
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
@ -20,7 +20,7 @@ class SettingsLogsAdapter: RecyclerView.Adapter<SettingsLogsAdapter.ViewHolder>(
private val dateFormat: DateFormat = DateFormat.getDateInstance(DateFormat.SHORT)
private val timeFormat = SimpleDateFormat("HH:mm:ss:SSS", Locale.getDefault())
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
class ViewHolder(val binding: ItemLogFileBinding): RecyclerView.ViewHolder(binding.root)
var logFiles: List<LogFile> = listOf()
set(value)
@ -29,16 +29,16 @@ class SettingsLogsAdapter: RecyclerView.Adapter<SettingsLogsAdapter.ViewHolder>(
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(parent.inflate(R.layout.item_log_file))
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ViewHolder(ItemLogFileBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun getItemCount() = logFiles.size
override fun onBindViewHolder(holder: ViewHolder, position: Int)
{
val view = holder.itemView
val logFile = logFiles[position]
view.nameTextView.text = "${dateFormat.format(logFile.date)} ${timeFormat.format(logFile.date)}"
view.summaryTextView.text = logFile.filename
view.shareButton.setOnClickListener { shareCallback?.let { it(logFile) } }
holder.binding.nameTextView.text = "${dateFormat.format(logFile.date)} ${timeFormat.format(logFile.date)}"
holder.binding.summaryTextView.text = logFile.filename
holder.binding.shareButton.setOnClickListener { shareCallback?.let { it(logFile) } }
}
}

View file

@ -21,29 +21,35 @@ import com.metallic.chiaki.common.LogFile
import com.metallic.chiaki.common.LogManager
import com.metallic.chiaki.common.ext.viewModelFactory
import com.metallic.chiaki.common.fileProviderAuthority
import kotlinx.android.synthetic.main.fragment_settings_logs.*
import com.metallic.chiaki.databinding.FragmentSettingsLogsBinding
class SettingsLogsFragment: AppCompatDialogFragment(), TitleFragment
{
private lateinit var viewModel: SettingsLogsViewModel
private var _binding: FragmentSettingsLogsBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
inflater.inflate(R.layout.fragment_settings_logs, container, false)
FragmentSettingsLogsBinding.inflate(inflater, container, false).let {
_binding = it
it.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
val context = context!!
val context = requireContext()
viewModel = ViewModelProvider(this, viewModelFactory { SettingsLogsViewModel(LogManager(context)) })
.get(SettingsLogsViewModel::class.java)
val adapter = SettingsLogsAdapter()
logsRecyclerView.layoutManager = LinearLayoutManager(context)
logsRecyclerView.adapter = adapter
binding.logsRecyclerView.layoutManager = LinearLayoutManager(context)
binding.logsRecyclerView.adapter = adapter
adapter.shareCallback = this::shareLogFile
viewModel.sessionLogs.observe(viewLifecycleOwner, Observer {
adapter.logFiles = it
emptyInfoGroup.visibility = if(it.isEmpty()) View.VISIBLE else View.GONE
binding.emptyInfoGroup.visibility = if(it.isEmpty()) View.VISIBLE else View.GONE
})
val itemTouchSwipeCallback = object : ItemTouchSwipeCallback(context)
@ -55,7 +61,7 @@ class SettingsLogsFragment: AppCompatDialogFragment(), TitleFragment
viewModel.deleteLog(file)
}
}
ItemTouchHelper(itemTouchSwipeCallback).attachToRecyclerView(logsRecyclerView)
ItemTouchHelper(itemTouchSwipeCallback).attachToRecyclerView(binding.logsRecyclerView)
}
override fun getTitle(resources: Resources): String = resources.getString(R.string.preferences_logs_title)

View file

@ -2,17 +2,15 @@
package com.metallic.chiaki.settings
import android.view.View
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.metallic.chiaki.R
import com.metallic.chiaki.common.RegisteredHost
import com.metallic.chiaki.common.ext.inflate
import kotlinx.android.synthetic.main.item_registered_host.view.*
import com.metallic.chiaki.databinding.ItemRegisteredHostBinding
class SettingsRegisteredHostsAdapter: RecyclerView.Adapter<SettingsRegisteredHostsAdapter.ViewHolder>()
{
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
class ViewHolder(val binding: ItemRegisteredHostBinding): RecyclerView.ViewHolder(binding.root)
var hosts: List<RegisteredHost> = listOf()
set(value)
@ -21,15 +19,15 @@ class SettingsRegisteredHostsAdapter: RecyclerView.Adapter<SettingsRegisteredHos
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(parent.inflate(R.layout.item_registered_host))
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
= ViewHolder(ItemRegisteredHostBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun getItemCount() = hosts.size
override fun onBindViewHolder(holder: ViewHolder, position: Int)
{
val view = holder.itemView
val host = hosts[position]
view.nameTextView.text = "${host.serverNickname} (${if(host.target.isPS5) "PS5" else "PS4"})"
view.summaryTextView.text = host.serverMac.toString()
holder.binding.nameTextView.text = "${host.serverNickname} (${if(host.target.isPS5) "PS5" else "PS4"})"
holder.binding.summaryTextView.text = host.serverMac.toString()
}
}

View file

@ -20,25 +20,32 @@ import com.metallic.chiaki.R
import com.metallic.chiaki.common.ext.putRevealExtra
import com.metallic.chiaki.common.ext.viewModelFactory
import com.metallic.chiaki.common.getDatabase
import com.metallic.chiaki.databinding.FragmentSettingsRegisteredHostsBinding
import com.metallic.chiaki.regist.RegistActivity
import kotlinx.android.synthetic.main.fragment_settings_registered_hosts.*
class SettingsRegisteredHostsFragment: AppCompatDialogFragment(), TitleFragment
{
private lateinit var viewModel: SettingsRegisteredHostsViewModel
private var _binding: FragmentSettingsRegisteredHostsBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
inflater.inflate(R.layout.fragment_settings_registered_hosts, container, false)
FragmentSettingsRegisteredHostsBinding.inflate(inflater, container, false).let {
_binding = it
it.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
viewModel = ViewModelProvider(this, viewModelFactory { SettingsRegisteredHostsViewModel(getDatabase(context!!)) })
val context = requireContext()
viewModel = ViewModelProvider(this, viewModelFactory { SettingsRegisteredHostsViewModel(getDatabase(context)) })
.get(SettingsRegisteredHostsViewModel::class.java)
val adapter = SettingsRegisteredHostsAdapter()
hostsRecyclerView.layoutManager = LinearLayoutManager(context)
hostsRecyclerView.adapter = adapter
val itemTouchSwipeCallback = object : ItemTouchSwipeCallback(context!!)
binding.hostsRecyclerView.layoutManager = LinearLayoutManager(context)
binding.hostsRecyclerView.adapter = adapter
val itemTouchSwipeCallback = object : ItemTouchSwipeCallback(context)
{
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int)
{
@ -56,15 +63,15 @@ class SettingsRegisteredHostsFragment: AppCompatDialogFragment(), TitleFragment
.show()
}
}
ItemTouchHelper(itemTouchSwipeCallback).attachToRecyclerView(hostsRecyclerView)
ItemTouchHelper(itemTouchSwipeCallback).attachToRecyclerView(binding.hostsRecyclerView)
viewModel.registeredHosts.observe(this, Observer {
adapter.hosts = it
emptyInfoGroup.visibility = if(it.isEmpty()) View.VISIBLE else View.GONE
binding.emptyInfoGroup.visibility = if(it.isEmpty()) View.VISIBLE else View.GONE
})
floatingActionButton.setOnClickListener {
binding.floatingActionButton.setOnClickListener {
Intent(context, RegistActivity::class.java).also {
it.putRevealExtra(floatingActionButton, rootLayout)
it.putRevealExtra(binding.floatingActionButton, binding.rootLayout)
startActivity(it, ActivityOptions.makeSceneTransitionAnimation(activity).toBundle())
}
}

View file

@ -7,12 +7,9 @@ import android.animation.AnimatorListenerAdapter
import android.app.AlertDialog
import android.graphics.Matrix
import android.os.*
import android.transition.TransitionManager
import android.view.*
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
@ -21,12 +18,12 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.metallic.chiaki.R
import com.metallic.chiaki.common.Preferences
import com.metallic.chiaki.common.ext.viewModelFactory
import com.metallic.chiaki.databinding.ActivityStreamBinding
import com.metallic.chiaki.lib.ConnectInfo
import com.metallic.chiaki.lib.ConnectVideoProfile
import com.metallic.chiaki.session.*
import com.metallic.chiaki.touchcontrols.TouchpadOnlyFragment
import com.metallic.chiaki.touchcontrols.TouchControlsFragment
import kotlinx.android.synthetic.main.activity_stream.*
import com.metallic.chiaki.touchcontrols.TouchpadOnlyFragment
import kotlin.math.min
private sealed class DialogContents
@ -43,6 +40,8 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
}
private lateinit var viewModel: StreamViewModel
private lateinit var binding: ActivityStreamBinding
private val uiVisibilityHandler = Handler()
override fun onCreate(savedInstanceState: Bundle?)
@ -62,38 +61,39 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
viewModel.input.observe(this)
setContentView(R.layout.activity_stream)
binding = ActivityStreamBinding.inflate(layoutInflater)
setContentView(binding.root)
window.decorView.setOnSystemUiVisibilityChangeListener(this)
viewModel.onScreenControlsEnabled.observe(this, Observer {
if(onScreenControlsSwitch.isChecked != it)
onScreenControlsSwitch.isChecked = it
if(onScreenControlsSwitch.isChecked)
touchpadOnlySwitch.isChecked = false
if(binding.onScreenControlsSwitch.isChecked != it)
binding.onScreenControlsSwitch.isChecked = it
if(binding.onScreenControlsSwitch.isChecked)
binding.touchpadOnlySwitch.isChecked = false
})
onScreenControlsSwitch.setOnCheckedChangeListener { _, isChecked ->
binding.onScreenControlsSwitch.setOnCheckedChangeListener { _, isChecked ->
viewModel.setOnScreenControlsEnabled(isChecked)
showOverlay()
}
viewModel.touchpadOnlyEnabled.observe(this, Observer {
if(touchpadOnlySwitch.isChecked != it)
touchpadOnlySwitch.isChecked = it
if(touchpadOnlySwitch.isChecked)
onScreenControlsSwitch.isChecked = false
if(binding.touchpadOnlySwitch.isChecked != it)
binding.touchpadOnlySwitch.isChecked = it
if(binding.touchpadOnlySwitch.isChecked)
binding.onScreenControlsSwitch.isChecked = false
})
touchpadOnlySwitch.setOnCheckedChangeListener { _, isChecked ->
binding.touchpadOnlySwitch.setOnCheckedChangeListener { _, isChecked ->
viewModel.setTouchpadOnlyEnabled(isChecked)
showOverlay()
}
displayModeToggle.addOnButtonCheckedListener { _, _, _ ->
binding.displayModeToggle.addOnButtonCheckedListener { _, _, _ ->
adjustStreamViewAspect()
showOverlay()
}
//viewModel.session.attachToTextureView(textureView)
viewModel.session.attachToSurfaceView(surfaceView)
viewModel.session.attachToSurfaceView(binding.surfaceView)
viewModel.session.state.observe(this, Observer { this.stateChanged(it) })
adjustStreamViewAspect()
@ -159,14 +159,14 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
private fun showOverlay()
{
overlay.isVisible = true
overlay.animate()
binding.overlay.isVisible = true
binding.overlay.animate()
.alpha(1.0f)
.setListener(object: AnimatorListenerAdapter()
{
override fun onAnimationEnd(animation: Animator?)
{
overlay.alpha = 1.0f
binding.overlay.alpha = 1.0f
}
})
uiVisibilityHandler.removeCallbacks(hideSystemUIRunnable)
@ -175,13 +175,13 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
private fun hideOverlay()
{
overlay.animate()
binding.overlay.animate()
.alpha(0.0f)
.setListener(object: AnimatorListenerAdapter()
{
override fun onAnimationEnd(animation: Animator?)
{
overlay.isGone = true
binding.overlay.isGone = true
}
})
}
@ -214,7 +214,7 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
private fun stateChanged(state: StreamState)
{
progressBar.visibility = if(state == StreamStateConnecting) View.VISIBLE else View.GONE
binding.progressBar.visibility = if(state == StreamStateConnecting) View.VISIBLE else View.GONE
when(state)
{
@ -302,7 +302,7 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
private fun adjustTextureViewAspect(textureView: TextureView)
{
val trans = TextureViewTransform(viewModel.session.connectInfo.videoProfile, textureView)
val resolution = trans.resolutionFor(TransformMode.fromButton(displayModeToggle.checkedButtonId))
val resolution = trans.resolutionFor(TransformMode.fromButton(binding.displayModeToggle.checkedButtonId))
Matrix().also {
textureView.getTransform(it)
it.setScale(resolution.width / trans.viewWidth, resolution.height / trans.viewHeight)
@ -314,8 +314,8 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
private fun adjustSurfaceViewAspect()
{
val videoProfile = viewModel.session.connectInfo.videoProfile
aspectRatioLayout.aspectRatio = videoProfile.width.toFloat() / videoProfile.height.toFloat()
aspectRatioLayout.mode = TransformMode.fromButton(displayModeToggle.checkedButtonId)
binding.aspectRatioLayout.aspectRatio = videoProfile.width.toFloat() / videoProfile.height.toFloat()
binding.aspectRatioLayout.mode = TransformMode.fromButton(binding.displayModeToggle.checkedButtonId)
}
private fun adjustStreamViewAspect() = adjustSurfaceViewAspect()

View file

@ -3,16 +3,14 @@
package com.metallic.chiaki.touchcontrols
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import com.metallic.chiaki.R
import com.metallic.chiaki.databinding.FragmentControlsBinding
import com.metallic.chiaki.lib.ControllerState
import kotlinx.android.synthetic.main.fragment_controls.*
class TouchControlsFragment : Fragment()
{
@ -28,44 +26,50 @@ class TouchControlsFragment : Fragment()
var controllerStateCallback: ((ControllerState) -> Unit)? = null
var onScreenControlsEnabled: LiveData<Boolean>? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View
= inflater.inflate(R.layout.fragment_controls, container, false)
private var _binding: FragmentControlsBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
FragmentControlsBinding.inflate(inflater, container, false).let {
_binding = it
it.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
super.onViewCreated(view, savedInstanceState)
dpadView.stateChangeCallback = this::dpadStateChanged
crossButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_CROSS)
moonButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_MOON)
pyramidButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_PYRAMID)
boxButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_BOX)
l1ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_L1)
r1ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_R1)
l3ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_L3)
r3ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_R3)
optionsButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_OPTIONS)
shareButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_SHARE)
psButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_PS)
touchpadButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_TOUCHPAD)
binding.dpadView.stateChangeCallback = this::dpadStateChanged
binding.crossButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_CROSS)
binding.moonButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_MOON)
binding.pyramidButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_PYRAMID)
binding.boxButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_BOX)
binding.l1ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_L1)
binding.r1ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_R1)
binding.l3ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_L3)
binding.r3ButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_R3)
binding.optionsButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_OPTIONS)
binding.shareButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_SHARE)
binding.psButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_PS)
binding.touchpadButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_TOUCHPAD)
l2ButtonView.buttonPressedCallback = { controllerState = controllerState.copy().apply { l2State = if(it) 255U else 0U } }
r2ButtonView.buttonPressedCallback = { controllerState = controllerState.copy().apply { r2State = if(it) 255U else 0U } }
binding.l2ButtonView.buttonPressedCallback = { controllerState = controllerState.copy().apply { l2State = if(it) 255U else 0U } }
binding.r2ButtonView.buttonPressedCallback = { controllerState = controllerState.copy().apply { r2State = if(it) 255U else 0U } }
val quantizeStick = { f: Float ->
(Short.MAX_VALUE * f).toShort()
(Short.MAX_VALUE * f).toInt().toShort()
}
leftAnalogStickView.stateChangedCallback = { controllerState = controllerState.copy().apply {
binding.leftAnalogStickView.stateChangedCallback = { controllerState = controllerState.copy().apply {
leftX = quantizeStick(it.x)
leftY = quantizeStick(it.y)
}}
rightAnalogStickView.stateChangedCallback = { controllerState = controllerState.copy().apply {
binding.rightAnalogStickView.stateChangedCallback = { controllerState = controllerState.copy().apply {
rightX = quantizeStick(it.x)
rightY = quantizeStick(it.y)
}}
onScreenControlsEnabled?.observe(this, Observer {
onScreenControlsEnabled?.observe(viewLifecycleOwner, Observer {
view.visibility = if(it) View.VISIBLE else View.GONE
})
}

View file

@ -10,8 +10,9 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import com.metallic.chiaki.R
import com.metallic.chiaki.databinding.FragmentControlsBinding
import com.metallic.chiaki.databinding.FragmentTouchpadOnlyBinding
import com.metallic.chiaki.lib.ControllerState
import kotlinx.android.synthetic.main.fragment_controls.*
class TouchpadOnlyFragment : Fragment()
{
@ -27,16 +28,22 @@ class TouchpadOnlyFragment : Fragment()
var controllerStateCallback: ((ControllerState) -> Unit)? = null
var touchpadOnlyEnabled: LiveData<Boolean>? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View
= inflater.inflate(R.layout.fragment_touchpad_only, container, false)
private var _binding: FragmentTouchpadOnlyBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
FragmentTouchpadOnlyBinding.inflate(inflater, container, false).let {
_binding = it
it.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
super.onViewCreated(view, savedInstanceState)
touchpadButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_TOUCHPAD)
binding.touchpadButtonView.buttonPressedCallback = buttonStateChanged(ControllerState.BUTTON_TOUCHPAD)
touchpadOnlyEnabled?.observe(this, Observer {
touchpadOnlyEnabled?.observe(viewLifecycleOwner, Observer {
view.visibility = if(it) View.VISIBLE else View.GONE
})
}