Aperture: Implement exposure level control
Change-Id: I9f2e5139bfbd47aaf3c94b573232e027ab9921ca
diff --git a/app/src/main/java/org/lineageos/aperture/CameraActivity.kt b/app/src/main/java/org/lineageos/aperture/CameraActivity.kt
index a7923f0..9ef0e36 100644
--- a/app/src/main/java/org/lineageos/aperture/CameraActivity.kt
+++ b/app/src/main/java/org/lineageos/aperture/CameraActivity.kt
@@ -71,6 +71,7 @@
import org.lineageos.aperture.ui.CountDownView
import org.lineageos.aperture.ui.GridView
import org.lineageos.aperture.ui.LevelerView
+import org.lineageos.aperture.ui.VerticalSlider
import org.lineageos.aperture.utils.Camera
import org.lineageos.aperture.utils.CameraFacing
import org.lineageos.aperture.utils.CameraMode
@@ -91,6 +92,7 @@
private val cameraModeHighlight by lazy { findViewById<MaterialButton>(R.id.cameraModeHighlight) }
private val countDownView by lazy { findViewById<CountDownView>(R.id.countDownView) }
private val effectButton by lazy { findViewById<ImageButton>(R.id.effectButton) }
+ private val exposureLevel by lazy { findViewById<VerticalSlider>(R.id.exposureLevel) }
private val flashButton by lazy { findViewById<ImageButton>(R.id.flashButton) }
private val flipCameraButton by lazy { findViewById<ImageButton>(R.id.flipCameraButton) }
private val galleryButton by lazy { findViewById<ImageView>(R.id.galleryButton) }
@@ -174,6 +176,9 @@
MSG_HIDE_FOCUS_RING -> {
viewFinderFocus.visibility = View.GONE
}
+ MSG_HIDE_EXPOSURE_SLIDER -> {
+ exposureLevel.visibility = View.GONE
+ }
}
}
}
@@ -364,6 +369,7 @@
return@setOnTouchListener false
}
viewFinder.setOnClickListener { view ->
+ exposureLevel.isVisible = true
viewFinderTouchEvent?.let {
viewFinderFocus.x = it.x - (viewFinderFocus.width / 2)
viewFinderFocus.y = it.y - (viewFinderFocus.height / 2)
@@ -371,6 +377,8 @@
viewFinderFocus.x = (view.width - viewFinderFocus.width) / 2f
viewFinderFocus.y = (view.height - viewFinderFocus.height) / 2f
}
+ handler.removeMessages(MSG_HIDE_EXPOSURE_SLIDER)
+ handler.sendMessageDelayed(handler.obtainMessage(MSG_HIDE_EXPOSURE_SLIDER), 2000)
}
// Observe preview stream state
@@ -407,6 +415,19 @@
"%.1fx".format(cameraController.zoomState.value?.zoomRatio)
}
+ // Set expose level callback & text formatter
+ exposureLevel.onProgressChangedByUser = {
+ cameraController.cameraControl?.setExposureCompensationIndex(
+ Int.mapToRange(camera.exposureCompensationRange, it)
+ )
+
+ handler.removeMessages(MSG_HIDE_EXPOSURE_SLIDER)
+ handler.sendMessageDelayed(handler.obtainMessage(MSG_HIDE_EXPOSURE_SLIDER), 2000)
+ }
+ exposureLevel.textFormatter = {
+ Int.mapToRange(camera.exposureCompensationRange, it).toString()
+ }
+
// Set primary bar button callbacks
qrModeButton.setOnClickListener { changeCameraMode(CameraMode.QR) }
photoModeButton.setOnClickListener { changeCameraMode(CameraMode.PHOTO) }
@@ -814,6 +835,11 @@
setFlashMode(sharedPreferences.photoFlashMode)
setMicrophoneMode(sharedPreferences.lastMicMode)
+ // Reset exposure level
+ exposureLevel.progress = 0.5f
+ exposureLevel.steps =
+ camera.exposureCompensationRange.upper - camera.exposureCompensationRange.lower
+
// Update icons from last state
updateCameraModeButtons()
updateTimerModeIcon()
@@ -1373,5 +1399,6 @@
private const val MSG_HIDE_ZOOM_SLIDER = 0
private const val MSG_HIDE_FOCUS_RING = 1
+ private const val MSG_HIDE_EXPOSURE_SLIDER = 2
}
}
diff --git a/app/src/main/java/org/lineageos/aperture/IntExt.kt b/app/src/main/java/org/lineageos/aperture/IntExt.kt
index ba3187d..639341a 100644
--- a/app/src/main/java/org/lineageos/aperture/IntExt.kt
+++ b/app/src/main/java/org/lineageos/aperture/IntExt.kt
@@ -7,6 +7,7 @@
package org.lineageos.aperture
import android.content.res.Resources.getSystem
+import android.util.Range
import kotlin.math.roundToInt
val Int.px
@@ -14,3 +15,7 @@
val Int.dp
get() = (this / getSystem().displayMetrics.density).roundToInt()
+
+internal fun Int.Companion.mapToRange(range: Range<Int>, percentage: Float): Int {
+ return (((range.upper - range.lower) * percentage) + range.lower).roundToInt()
+}
diff --git a/app/src/main/java/org/lineageos/aperture/utils/Camera.kt b/app/src/main/java/org/lineageos/aperture/utils/Camera.kt
index be68bf4..9b7dffa 100644
--- a/app/src/main/java/org/lineageos/aperture/utils/Camera.kt
+++ b/app/src/main/java/org/lineageos/aperture/utils/Camera.kt
@@ -28,6 +28,7 @@
else -> CameraFacing.UNKNOWN
}
+ val exposureCompensationRange = cameraInfo.exposureState.exposureCompensationRange
val hasFlashUnit = cameraInfo.hasFlashUnit()
val supportedVideoQualities: MutableList<Quality> =
diff --git a/app/src/main/res/layout/activity_camera.xml b/app/src/main/res/layout/activity_camera.xml
index 7152ec7..cc99305 100644
--- a/app/src/main/res/layout/activity_camera.xml
+++ b/app/src/main/res/layout/activity_camera.xml
@@ -218,6 +218,20 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
+ <org.lineageos.aperture.ui.VerticalSlider
+ android:id="@+id/exposureLevel"
+ android:layout_width="32dp"
+ android:layout_height="250dp"
+ android:layout_marginEnd="8dp"
+ android:visibility="gone"
+ app:layout_constraintBottom_toBottomOf="@+id/viewFinder"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/viewFinder"
+ app:thumbColor="@color/white"
+ app:thumbTextColor="@color/black"
+ app:thumbTextSize="10dp"
+ app:trackColor="#7FCCCCCC" />
+
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/primaryBarLayout"
android:layout_width="0dp"