Add Stream Display Options: Normal, Zoom and Stretch (#146)

This commit is contained in:
FearlessSpiff 2020-01-26 11:33:57 +01:00 committed by Florian Märkl
commit 4b17137855
6 changed files with 147 additions and 23 deletions

View file

@ -25,6 +25,7 @@ import android.os.Bundle
import android.os.Handler
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.TextureView
import android.view.View
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
@ -38,6 +39,7 @@ import com.metallic.chiaki.common.LogManager
import com.metallic.chiaki.common.Preferences
import com.metallic.chiaki.common.ext.viewModelFactory
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
@ -99,6 +101,17 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
showOverlay()
}
displayModeToggle.addOnButtonCheckedListener {group, checkedId, _ ->
// following 'if' is a workaround until selectionRequired for MaterialButtonToggleGroup
// comes out of alpha.
// See https://stackoverflow.com/questions/56164004/required-single-selection-on-materialbuttontogglegroup
if (displayModeToggle.checkedButtonId == -1)
displayModeToggle.check(checkedId)
adjustTextureViewAspect()
showOverlay()
}
viewModel.session.attachToTextureView(textureView)
viewModel.session.state.observe(this, Observer { this.stateChanged(it) })
textureView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
@ -294,33 +307,73 @@ class StreamActivity : AppCompatActivity(), View.OnSystemUiVisibilityChangeListe
private fun adjustTextureViewAspect()
{
val contentWidth = viewModel.session.connectInfo.videoProfile.width.toFloat()
val contentHeight = viewModel.session.connectInfo.videoProfile.height.toFloat()
val viewWidth = textureView.width.toFloat()
val viewHeight = textureView.height.toFloat()
val contentAspect = contentHeight / contentWidth
val width: Float
val height: Float
if(viewHeight > viewWidth * contentAspect)
{
width = viewWidth
height = viewWidth * contentAspect
}
else
{
width = viewHeight / contentAspect
height = viewHeight
}
val displayInfo = DisplayInfo(viewModel.session.connectInfo.videoProfile, textureView)
val resolution = displayInfo.computeResolutionFor(displayModeToggle.checkedButtonId)
Matrix().also {
textureView.getTransform(it)
it.setScale(width / viewWidth, height / viewHeight)
it.postTranslate((viewWidth - width) * 0.5f, (viewHeight - height) * 0.5f)
it.setScale(resolution.width / displayInfo.viewWidth, resolution.height / displayInfo.viewHeight)
it.postTranslate((displayInfo.viewWidth - resolution.width) * 0.5f, (displayInfo.viewHeight - resolution.height) * 0.5f)
textureView.setTransform(it)
}
}
override fun dispatchKeyEvent(event: KeyEvent) = viewModel.input.dispatchKeyEvent(event) || super.dispatchKeyEvent(event)
override fun onGenericMotionEvent(event: MotionEvent) = viewModel.input.onGenericMotionEvent(event) || super.onGenericMotionEvent(event)
}
class DisplayInfo constructor(val videoProfile: ConnectVideoProfile, val textureView: TextureView)
{
val contentWidth : Float get() = videoProfile.width.toFloat()
val contentHeight : Float get() = videoProfile.height.toFloat()
val viewWidth : Float get() = textureView.width.toFloat()
val viewHeight : Float get() = textureView.height.toFloat()
val contentAspect : Float get() = contentHeight / contentWidth
fun computeResolutionFor(displayModeButtonId: Int) : Resolution
{
when (displayModeButtonId)
{
R.id.display_mode_stretch_button -> return computeStrechedResolution()
R.id.display_mode_zoom_button -> return computeZoomedResolution()
else -> return computeNormalResolution()
}
}
private fun computeStrechedResolution(): Resolution
{
return Resolution(viewWidth, viewHeight)
}
private fun computeZoomedResolution(): Resolution
{
if (viewHeight > viewWidth * contentAspect)
{
val zoomFactor = viewHeight / contentHeight
return Resolution(contentWidth * zoomFactor, viewHeight)
}
else
{
val zoomFactor = viewWidth / contentWidth
return Resolution(viewWidth, contentHeight * zoomFactor)
}
}
private fun computeNormalResolution(): Resolution
{
if (viewHeight > viewWidth * contentAspect)
{
return Resolution(viewWidth, viewWidth * contentAspect)
}
else
{
return Resolution(viewHeight / contentAspect, viewHeight)
}
}
}
data class Resolution(val width: Float, val height: Float)

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorAccent" android:state_checked="true"/>
<item android:color="@android:color/white"/>
</selector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp"
android:height="24dp">
<path
android:pathData="M19 5H5c-1.1 0 -2 0.9 -2 2v10c0 1.1 0.9 2 2 2h14c1.1 0 2 -0.9 2 -2V7c0 -1.1 -0.9 -2 -2 -2zm0 12H5V7h14v10z"
android:fillColor="#000000" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp"
android:height="24dp">
<path
android:pathData="M7 14H5v5h5v-2H7v-3zm-2 -4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"
android:fillColor="#000000" />
</vector>

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp"
android:height="24dp">
<group>
<clip-path
android:pathData="M0 0h24v24H0z" />
<path
android:pathData="M15 3l2.3 2.3 -2.89 2.87 1.42 1.42L18.7 6.7 21 9V3zM3 9l2.3 -2.3 2.87 2.89 1.42 -1.42L6.7 5.3 9 3H3zm6 12l-2.3 -2.3 2.89 -2.87 -1.42 -1.42L5.3 17.3 3 15v6zm12 -6l-2.3 2.3 -2.87 -2.89 -1.42 1.42 2.89 2.87L15 21h6z"
android:fillColor="#000000" />
</group>
</vector>

View file

@ -34,8 +34,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
tools:paddingRight="12dp"
tools:paddingTop="25dp"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
@ -69,8 +67,45 @@
app:layout_constraintStart_toStartOf="parent"
app:switchPadding="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/displayModeToggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:singleSelection="true"
app:checkedButton="@id/display_mode_normal_button">
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:id="@+id/display_mode_normal_button"
android:layout_width="60dp"
android:layout_height="wrap_content"
app:icon="@drawable/ic_display_normal"
app:iconTint="@color/stream_material_button_icon_tint"
app:strokeColor="@color/stream_text"/>
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:id="@+id/display_mode_zoom_button"
android:layout_width="60dp"
android:layout_height="wrap_content"
app:icon="@drawable/ic_display_zoom"
app:iconTint="@color/stream_material_button_icon_tint"
app:strokeColor="@color/stream_text"/>
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:id="@+id/display_mode_stretch_button"
android:layout_width="60dp"
android:layout_height="wrap_content"
app:icon="@drawable/ic_display_stretch"
app:iconTint="@color/stream_material_button_icon_tint"
app:strokeColor="@color/stream_text"/>
</com.google.android.material.button.MaterialButtonToggleGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>