From 4b171378553d7a2a2fcda2d51a52ad891baf20af Mon Sep 17 00:00:00 2001 From: FearlessSpiff Date: Sun, 26 Jan 2020 11:33:57 +0100 Subject: [PATCH] Add Stream Display Options: Normal, Zoom and Stretch (#146) --- .../metallic/chiaki/stream/StreamActivity.kt | 93 +++++++++++++++---- .../stream_material_button_icon_tint.xml | 5 + .../main/res/drawable/ic_display_normal.xml | 9 ++ .../main/res/drawable/ic_display_stretch.xml | 9 ++ .../src/main/res/drawable/ic_display_zoom.xml | 13 +++ .../src/main/res/layout/activity_stream.xml | 41 +++++++- 6 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 android/app/src/main/res/color/stream_material_button_icon_tint.xml create mode 100644 android/app/src/main/res/drawable/ic_display_normal.xml create mode 100644 android/app/src/main/res/drawable/ic_display_stretch.xml create mode 100644 android/app/src/main/res/drawable/ic_display_zoom.xml diff --git a/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt index eee3908..40be5f9 100644 --- a/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt +++ b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt @@ -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) diff --git a/android/app/src/main/res/color/stream_material_button_icon_tint.xml b/android/app/src/main/res/color/stream_material_button_icon_tint.xml new file mode 100644 index 0000000..fbfbf5c --- /dev/null +++ b/android/app/src/main/res/color/stream_material_button_icon_tint.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/ic_display_normal.xml b/android/app/src/main/res/drawable/ic_display_normal.xml new file mode 100644 index 0000000..4ffbf8f --- /dev/null +++ b/android/app/src/main/res/drawable/ic_display_normal.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/ic_display_stretch.xml b/android/app/src/main/res/drawable/ic_display_stretch.xml new file mode 100644 index 0000000..605cf01 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_display_stretch.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/ic_display_zoom.xml b/android/app/src/main/res/drawable/ic_display_zoom.xml new file mode 100644 index 0000000..c260698 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_display_zoom.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/activity_stream.xml b/android/app/src/main/res/layout/activity_stream.xml index 770c42c..c320d3f 100644 --- a/android/app/src/main/res/layout/activity_stream.xml +++ b/android/app/src/main/res/layout/activity_stream.xml @@ -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"> - + + + + + + + + + \ No newline at end of file