From e6a588a218dcc29dfa548f91ddb86f6024f617ff Mon Sep 17 00:00:00 2001 From: darthpaul Date: Mon, 22 Aug 2022 14:27:07 +0100 Subject: [PATCH] simpler UI for flash mode / media size --- .../camera/activities/MainActivity.kt | 141 +++++++++++++++++- .../camera/extensions/Int.kt | 20 ++- .../camera/helpers/ImageQualityManager.kt | 2 +- .../camera/implementations/CameraXPreview.kt | 60 +++++--- .../implementations/CameraXPreviewListener.kt | 15 +- .../camera/interfaces/MyPreview.kt | 4 +- .../simplemobiletools/camera/models/MySize.kt | 24 +++ .../camera/models/ResolutionOption.kt | 9 ++ .../camera/models/VideoQuality.kt | 24 ++- .../main/res/color/camera_option_color.xml | 6 + app/src/main/res/color/tab_color.xml | 5 + .../main/res/drawable/gradient_background.xml | 7 - .../drawable/gradient_background_flipped.xml | 7 - .../res/drawable/ic_flash_auto_vector.xml | 2 +- .../main/res/drawable/ic_flash_off_vector.xml | 2 +- .../main/res/drawable/ic_flash_on_vector.xml | 2 +- app/src/main/res/drawable/ic_photo_16x9.xml | 31 ++++ app/src/main/res/drawable/ic_photo_1x1.xml | 26 ++++ app/src/main/res/drawable/ic_photo_4x3.xml | 26 ++++ app/src/main/res/drawable/ic_photo_full.xml | 9 ++ app/src/main/res/drawable/ic_video_fhd.xml | 19 +++ app/src/main/res/drawable/ic_video_hd.xml | 17 +++ app/src/main/res/drawable/ic_video_sd.xml | 17 +++ app/src/main/res/drawable/ic_video_uhd.xml | 20 +++ app/src/main/res/drawable/tab_indicator.xml | 17 ++- .../res/drawable/tab_indicator_selected.xml | 14 -- .../res/drawable/tab_indicator_unselected.xml | 4 - app/src/main/res/layout/activity_main.xml | 49 ++++-- app/src/main/res/layout/layout_button.xml | 8 + app/src/main/res/layout/layout_flash.xml | 36 +++++ app/src/main/res/layout/layout_media_size.xml | 8 + app/src/main/res/values/dimens.xml | 2 + app/src/main/res/values/ids.xml | 11 ++ app/src/main/res/values/styles.xml | 14 ++ 34 files changed, 574 insertions(+), 84 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/camera/models/ResolutionOption.kt create mode 100644 app/src/main/res/color/camera_option_color.xml create mode 100644 app/src/main/res/color/tab_color.xml delete mode 100644 app/src/main/res/drawable/gradient_background.xml delete mode 100644 app/src/main/res/drawable/gradient_background_flipped.xml create mode 100644 app/src/main/res/drawable/ic_photo_16x9.xml create mode 100644 app/src/main/res/drawable/ic_photo_1x1.xml create mode 100644 app/src/main/res/drawable/ic_photo_4x3.xml create mode 100644 app/src/main/res/drawable/ic_photo_full.xml create mode 100644 app/src/main/res/drawable/ic_video_fhd.xml create mode 100644 app/src/main/res/drawable/ic_video_hd.xml create mode 100644 app/src/main/res/drawable/ic_video_sd.xml create mode 100644 app/src/main/res/drawable/ic_video_uhd.xml delete mode 100644 app/src/main/res/drawable/tab_indicator_selected.xml delete mode 100644 app/src/main/res/drawable/tab_indicator_unselected.xml create mode 100644 app/src/main/res/layout/layout_button.xml create mode 100644 app/src/main/res/layout/layout_flash.xml create mode 100644 app/src/main/res/layout/layout_media_size.xml create mode 100644 app/src/main/res/values/ids.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt index ac24fcce..66922bc7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt @@ -10,30 +10,41 @@ import android.os.Handler import android.os.Looper import android.provider.MediaStore import android.view.* +import android.widget.LinearLayout +import androidx.appcompat.content.res.AppCompatResources import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.WindowCompat import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions +import com.google.android.material.button.MaterialButton +import com.google.android.material.button.MaterialButtonToggleGroup import com.google.android.material.tabs.TabLayout import com.simplemobiletools.camera.BuildConfig import com.simplemobiletools.camera.R import com.simplemobiletools.camera.extensions.config +import com.simplemobiletools.camera.extensions.idToAppFlashMode +import com.simplemobiletools.camera.extensions.toFlashModeId import com.simplemobiletools.camera.helpers.* import com.simplemobiletools.camera.implementations.CameraXInitializer import com.simplemobiletools.camera.implementations.CameraXPreviewListener import com.simplemobiletools.camera.implementations.MyCameraImpl import com.simplemobiletools.camera.interfaces.MyPreview +import com.simplemobiletools.camera.models.ResolutionOption import com.simplemobiletools.camera.views.FocusCircleView import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.Release import java.util.concurrent.TimeUnit import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.android.synthetic.main.layout_flash.flash_auto +import kotlinx.android.synthetic.main.layout_flash.flash_toggle_group +import kotlinx.android.synthetic.main.layout_media_size.media_size_toggle_group class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, CameraXPreviewListener { companion object { - private const val CAPTURE_ANIMATION_DURATION = 100L + private const val CAPTURE_ANIMATION_DURATION = 500L private const val PHOTO_MODE_INDEX = 1 private const val VIDEO_MODE_INDEX = 0 } @@ -43,9 +54,9 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera private lateinit var mFocusCircleView: FocusCircleView private lateinit var mFadeHandler: Handler private lateinit var mCameraImpl: MyCameraImpl - private var mPreview: MyPreview? = null private var mPreviewUri: Uri? = null + private var buttonCheckedListener: MaterialButtonToggleGroup.OnButtonCheckedListener? = null private var mIsInPhotoMode = true private var mIsCameraAvailable = false private var mIsHardwareShutterHandled = false @@ -63,6 +74,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera super.onCreate(savedInstanceState) appLaunched(BuildConfig.APPLICATION_ID) requestWindowFeature(Window.FEATURE_NO_TITLE) + WindowCompat.setDecorFitsSystemWindows(window, false) initVariables() tryInitCamera() @@ -155,6 +167,12 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera mPreview = null } + override fun onBackPressed() { + if (!closeOptions()) { + super.onBackPressed() + } + } + private fun initVariables() { mIsInPhotoMode = if (isVideoCaptureIntent()) { false @@ -263,14 +281,28 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera 0, ) - val goneMargin = (navigationBarHeight + resources.getDimension(R.dimen.big_margin)).toInt() + (flash_toggle_group.layoutParams as ConstraintLayout.LayoutParams).setMargins( + 0, + statusBarHeight, + 0, + 0, + ) + + (media_size_toggle_group.layoutParams as ConstraintLayout.LayoutParams).setMargins( + 0, + statusBarHeight, + 0, + 0, + ) + + val goneMargin = (navigationBarHeight + resources.getDimension(R.dimen.bigger_margin)).toInt() (shutter.layoutParams as ConstraintLayout.LayoutParams).goneBottomMargin = goneMargin (video_rec_curr_timer.layoutParams as ConstraintLayout.LayoutParams).setMargins( 0, 0, 0, - (navigationBarHeight + resources.getDimension(R.dimen.big_margin)).toInt() + (navigationBarHeight + resources.getDimension(R.dimen.bigger_margin)).toInt() ) checkVideoCaptureIntent() @@ -314,7 +346,15 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera toggle_flash.setOnClickListener { toggleFlash() } shutter.setOnClickListener { shutterPressed() } settings.setOnClickListener { launchSettings() } - change_resolution.setOnClickListener { mPreview?.showChangeResolutionDialog() } + change_resolution.setOnClickListener { mPreview?.showChangeResolution() } + flash_toggle_group.check(config.flashlightState.toFlashModeId()) + flash_toggle_group.addOnButtonCheckedListener { _, checkedId, isChecked -> + if (isChecked) { + val flashMode = checkedId.idToAppFlashMode() + closeOptions() + mPreview?.setFlashlightState(flashMode) + } + } } private fun toggleCamera() { @@ -332,7 +372,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera private fun toggleFlash() { if (checkCameraAvailable()) { - mPreview?.toggleFlashlight() + showFlashOptions(mIsInPhotoMode) } } @@ -642,6 +682,95 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera } } + override fun onTouchPreview() { + closeOptions() + } + + private fun closeOptions(): Boolean { + if (media_size_toggle_group.isVisible()) { + media_size_toggle_group.beGone() + top_group.beVisible() + return true + } + + if (flash_toggle_group.isVisible()) { + flash_toggle_group.beGone() + top_group.beVisible() + return true + } + return false + } + + override fun displaySelectedResolution(resolutionOption: ResolutionOption) { + val imageRes = resolutionOption.imageDrawableResId + change_resolution.setImageResource(imageRes) + } + + override fun showImageSizes( + selectedResolution: ResolutionOption, + resolutions: List, + isPhotoCapture: Boolean, + isFrontCamera: Boolean, + onSelect: (changed: Boolean) -> Unit + ) { + + media_size_toggle_group.removeAllViews() + media_size_toggle_group.clearChecked() + + resolutions.map(::createButton).forEach { button -> + media_size_toggle_group.addView(button) + } + + buttonCheckedListener?.let { media_size_toggle_group.removeOnButtonCheckedListener(it) } + buttonCheckedListener = MaterialButtonToggleGroup.OnButtonCheckedListener { _, checkedId, isChecked -> + if (isChecked) { + val index = resolutions.indexOfFirst { it.buttonViewId == checkedId } + if (isPhotoCapture) { + if (isFrontCamera) { + config.frontPhotoResIndex = index + } else { + config.backPhotoResIndex = index + } + } else { + if (isFrontCamera) { + config.frontVideoResIndex = index + } else { + config.backVideoResIndex = index + } + } + closeOptions() + onSelect.invoke(selectedResolution.buttonViewId != checkedId) + } + } + buttonCheckedListener?.let { + media_size_toggle_group.check(selectedResolution.buttonViewId) + media_size_toggle_group.addOnButtonCheckedListener(it) + } + showResolutionOptions() + } + + private fun createButton(resolutionOption: ResolutionOption): MaterialButton { + val params = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT).apply { + weight = 1f + } + return (layoutInflater.inflate(R.layout.layout_button, null) as MaterialButton).apply { + layoutParams = params + icon = AppCompatResources.getDrawable(context, resolutionOption.imageDrawableResId) + id = resolutionOption.buttonViewId + } + } + + private fun showResolutionOptions() { + top_group.beInvisible() + media_size_toggle_group.beVisible() + } + + override fun showFlashOptions(photoCapture: Boolean) { + flash_auto.beVisibleIf(photoCapture) + top_group.beInvisible() + flash_toggle_group.beVisible() + } + fun setRecordingState(isRecording: Boolean) { runOnUiThread { if (isRecording) { diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Int.kt b/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Int.kt index 4cf4caf7..04794b43 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Int.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Int.kt @@ -2,10 +2,10 @@ package com.simplemobiletools.camera.extensions import androidx.camera.core.CameraSelector import androidx.camera.core.ImageCapture +import com.simplemobiletools.camera.R import com.simplemobiletools.camera.helpers.FLASH_AUTO import com.simplemobiletools.camera.helpers.FLASH_OFF import com.simplemobiletools.camera.helpers.FLASH_ON -import java.lang.IllegalArgumentException fun Int.toCameraXFlashMode(): Int { return when (this) { @@ -25,6 +25,24 @@ fun Int.toAppFlashMode(): Int { } } +fun Int.toFlashModeId(): Int { + return when (this) { + FLASH_ON -> R.id.flash_on + FLASH_OFF -> R.id.flash_on + FLASH_AUTO -> R.id.flash_auto + else -> throw IllegalArgumentException("Unknown mode: $this") + } +} + +fun Int.idToAppFlashMode(): Int { + return when (this) { + R.id.flash_on -> FLASH_ON + R.id.flash_off -> FLASH_OFF + R.id.flash_auto -> FLASH_AUTO + else -> throw IllegalArgumentException("Unknown mode: $this") + } +} + fun Int.toCameraSelector(): CameraSelector { return if (this == CameraSelector.LENS_FACING_FRONT) { CameraSelector.DEFAULT_FRONT_CAMERA diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/helpers/ImageQualityManager.kt b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/ImageQualityManager.kt index 741be610..5e5d1c9a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/helpers/ImageQualityManager.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/ImageQualityManager.kt @@ -53,7 +53,7 @@ class ImageQualityManager( fun getUserSelectedResolution(cameraSelector: CameraSelector): MySize { val resolutions = getSupportedResolutions(cameraSelector) var index = if (cameraSelector == CameraSelector.DEFAULT_FRONT_CAMERA) config.frontPhotoResIndex else config.backPhotoResIndex - index = index.coerceAtMost(resolutions.lastIndex) + index = index.coerceAtMost(resolutions.lastIndex).coerceAtLeast(0) return resolutions[index] } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt index 1260e0d0..20c4b83f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt @@ -29,6 +29,7 @@ import com.simplemobiletools.camera.helpers.* import com.simplemobiletools.camera.interfaces.MyPreview import com.simplemobiletools.camera.models.MediaOutput import com.simplemobiletools.camera.models.MySize +import com.simplemobiletools.camera.models.ResolutionOption import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.helpers.ensureBackgroundThread import kotlin.math.abs @@ -128,9 +129,13 @@ class CameraXPreview( val cameraProvider = cameraProvider ?: throw IllegalStateException("Camera initialization failed.") val resolution = if (isPhotoCapture) { - imageQualityManager.getUserSelectedResolution(cameraSelector) + imageQualityManager.getUserSelectedResolution(cameraSelector).also { + displaySelectedResolution(it.toResolutionOption()) + } } else { - val selectedQuality = videoQualityManager.getUserSelectedQuality(cameraSelector) + val selectedQuality = videoQualityManager.getUserSelectedQuality(cameraSelector).also { + displaySelectedResolution(it.toResolutionOption()) + } MySize(selectedQuality.width, selectedQuality.height) } @@ -174,6 +179,10 @@ class CameraXPreview( setupZoomAndFocus() } + private fun displaySelectedResolution(resolutionOption: ResolutionOption) { + listener.displaySelectedResolution(resolutionOption) + } + private fun getRotatedResolution(resolution: MySize, rotationDegrees: Int): Size { return if (rotationDegrees == Surface.ROTATION_0 || rotationDegrees == Surface.ROTATION_180) { Size(resolution.height, resolution.width) @@ -261,6 +270,11 @@ class CameraXPreview( private fun setupZoomAndFocus() { val scaleGesture = camera?.let { ScaleGestureDetector(activity, PinchToZoomOnScaleGestureListener(it.cameraInfo, it.cameraControl)) } val gestureDetector = GestureDetector(activity, object : SimpleOnGestureListener() { + override fun onDown(e: MotionEvent?): Boolean { + listener.onTouchPreview() + return super.onDown(e) + } + override fun onSingleTapConfirmed(event: MotionEvent): Boolean { return camera?.cameraInfo?.let { val display = displayManager.getDisplay(Display.DEFAULT_DISPLAY) @@ -326,6 +340,28 @@ class CameraXPreview( } } + override fun showChangeResolution() { + val imageSizes = imageQualityManager.getSupportedResolutions(cameraSelector) + val videoSizes = videoQualityManager.getSupportedQualities(cameraSelector) + val selectedVideoSize = videoQualityManager.getUserSelectedQuality(cameraSelector) + val selectedImageSize = imageQualityManager.getUserSelectedResolution(cameraSelector) + + val selectedResolution = if (isPhotoCapture) selectedImageSize.toResolutionOption() else selectedVideoSize.toResolutionOption() + val resolutions = if (isPhotoCapture) imageSizes.map { it.toResolutionOption() } else videoSizes.map { it.toResolutionOption() } + + listener.showImageSizes( + selectedResolution = selectedResolution, + resolutions = resolutions, + isPhotoCapture = isPhotoCapture, + isFrontCamera = isFrontCameraInUse() + ) { changed -> + if (changed) { + currentRecording?.stop() + } + startCamera() + } + } + override fun toggleFrontBackCamera() { val newCameraSelector = if (isFrontCameraInUse()) { CameraSelector.DEFAULT_BACK_CAMERA @@ -337,22 +373,10 @@ class CameraXPreview( startCamera(switching = true) } - override fun toggleFlashlight() { - val newFlashMode = if (isPhotoCapture) { - when (flashMode) { - FLASH_MODE_OFF -> FLASH_MODE_ON - FLASH_MODE_ON -> FLASH_MODE_AUTO - FLASH_MODE_AUTO -> FLASH_MODE_OFF - else -> throw IllegalArgumentException("Unknown mode: $flashMode") - } - } else { - when (flashMode) { - FLASH_MODE_OFF -> FLASH_MODE_ON - FLASH_MODE_ON -> FLASH_MODE_OFF - else -> throw IllegalArgumentException("Unknown mode: $flashMode") - }.also { - camera?.cameraControl?.enableTorch(it == FLASH_MODE_ON) - } + override fun setFlashlightState(state: Int) { + val newFlashMode = state.toCameraXFlashMode() + if (!isPhotoCapture) { + camera?.cameraControl?.enableTorch(newFlashMode == FLASH_MODE_ON) } flashMode = newFlashMode imageCapture?.flashMode = newFlashMode diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt index 85657e43..69d8cc3e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt @@ -2,13 +2,14 @@ package com.simplemobiletools.camera.implementations import android.graphics.Bitmap import android.net.Uri +import com.simplemobiletools.camera.models.ResolutionOption interface CameraXPreviewListener { fun setCameraAvailable(available: Boolean) - fun setHasFrontAndBackCamera(hasFrontAndBack:Boolean) + fun setHasFrontAndBackCamera(hasFrontAndBack: Boolean) fun setFlashAvailable(available: Boolean) fun onChangeCamera(frontCamera: Boolean) - fun toggleBottomButtons(hide:Boolean) + fun toggleBottomButtons(hide: Boolean) fun onMediaSaved(uri: Uri) fun onImageCaptured(bitmap: Bitmap) fun onChangeFlashMode(flashMode: Int) @@ -18,4 +19,14 @@ interface CameraXPreviewListener { fun onFocusCamera(xPos: Float, yPos: Float) fun onSwipeLeft() fun onSwipeRight() + fun onTouchPreview() + fun displaySelectedResolution(resolutionOption: ResolutionOption) + fun showImageSizes( + selectedResolution: ResolutionOption, + resolutions: List, + isPhotoCapture: Boolean, + isFrontCamera: Boolean, + onSelect: (changed:Boolean) -> Unit, + ) + fun showFlashOptions(photoCapture: Boolean) } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt b/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt index 81125acb..cc670165 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt @@ -20,7 +20,7 @@ interface MyPreview { fun toggleFrontBackCamera() - fun toggleFlashlight() + fun toggleFlashlight() = Unit fun tryTakePicture() @@ -31,4 +31,6 @@ interface MyPreview { fun initVideoMode() fun checkFlashlight() = Unit + + fun showChangeResolution() = Unit } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt b/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt index 3ad93eac..158c91d0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt @@ -2,6 +2,8 @@ package com.simplemobiletools.camera.models import android.content.Context import android.util.Size +import androidx.annotation.DrawableRes +import androidx.annotation.IdRes import com.simplemobiletools.camera.R data class MySize(val width: Int, val height: Int, val isFullScreen: Boolean = false) { @@ -57,5 +59,27 @@ data class MySize(val width: Int, val height: Int, val isFullScreen: Boolean = f else -> context.resources.getString(R.string.other) } + @DrawableRes + fun getImageResId(): Int = when { + isFullScreen -> R.drawable.ic_photo_full + isSixteenToNine() -> R.drawable.ic_photo_16x9 + isFourToThree() -> R.drawable.ic_photo_4x3 + isSquare() -> R.drawable.ic_photo_1x1 + else -> throw UnsupportedOperationException("This size $this is not supported") + } + + @IdRes + fun getButtonId(): Int = when { + isFullScreen -> R.id.photo_full + isSixteenToNine() -> R.id.photo_16x9 + isFourToThree() -> R.id.photo_4x3 + isSquare() -> R.id.photo_1x1 + else -> throw UnsupportedOperationException("This size $this is not supported") + } + + fun toResolutionOption(): ResolutionOption { + return ResolutionOption(buttonViewId = getButtonId(), imageDrawableResId = getImageResId()) + } + fun toSize() = Size(width, height) } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/models/ResolutionOption.kt b/app/src/main/kotlin/com/simplemobiletools/camera/models/ResolutionOption.kt new file mode 100644 index 00000000..39b9eac6 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/camera/models/ResolutionOption.kt @@ -0,0 +1,9 @@ +package com.simplemobiletools.camera.models + +import androidx.annotation.DrawableRes +import androidx.annotation.IdRes + +data class ResolutionOption( + @IdRes val buttonViewId: Int, + @DrawableRes val imageDrawableResId: Int, +) diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/models/VideoQuality.kt b/app/src/main/kotlin/com/simplemobiletools/camera/models/VideoQuality.kt index ec2a536b..adcfefbd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/models/VideoQuality.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/models/VideoQuality.kt @@ -1,6 +1,8 @@ package com.simplemobiletools.camera.models import android.content.Context +import androidx.annotation.DrawableRes +import androidx.annotation.IdRes import com.simplemobiletools.camera.R enum class VideoQuality(val width: Int, val height: Int) { @@ -11,7 +13,7 @@ enum class VideoQuality(val width: Int, val height: Int) { val pixels: Int = width * height - val megaPixels: String = String.format("%.1f", (width * height.toFloat()) / VideoQuality.ONE_MEGA_PIXEL) + val megaPixels: String = String.format("%.1f", (width * height.toFloat()) / VideoQuality.ONE_MEGA_PIXEL) val ratio = width / height.toFloat() @@ -52,6 +54,26 @@ enum class VideoQuality(val width: Int, val height: Int) { else -> context.resources.getString(R.string.other) } + @DrawableRes + fun getImageResId(): Int = when (this) { + UHD -> R.drawable.ic_video_uhd + FHD -> R.drawable.ic_video_fhd + HD -> R.drawable.ic_video_hd + SD -> R.drawable.ic_video_sd + } + + @IdRes + fun getButtonId(): Int = when (this) { + UHD -> R.id.video_uhd + FHD -> R.id.video_fhd + HD -> R.id.video_hd + SD -> R.id.video_sd + } + + fun toResolutionOption(): ResolutionOption { + return ResolutionOption(buttonViewId = getButtonId(), imageDrawableResId = getImageResId()) + } + companion object { private const val ONE_MEGA_PIXEL = 1000000 } diff --git a/app/src/main/res/color/camera_option_color.xml b/app/src/main/res/color/camera_option_color.xml new file mode 100644 index 00000000..d4349ec0 --- /dev/null +++ b/app/src/main/res/color/camera_option_color.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/color/tab_color.xml b/app/src/main/res/color/tab_color.xml new file mode 100644 index 00000000..02947e5a --- /dev/null +++ b/app/src/main/res/color/tab_color.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/gradient_background.xml b/app/src/main/res/drawable/gradient_background.xml deleted file mode 100644 index 68f8cc81..00000000 --- a/app/src/main/res/drawable/gradient_background.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/gradient_background_flipped.xml b/app/src/main/res/drawable/gradient_background_flipped.xml deleted file mode 100644 index e8481212..00000000 --- a/app/src/main/res/drawable/gradient_background_flipped.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_flash_auto_vector.xml b/app/src/main/res/drawable/ic_flash_auto_vector.xml index 308f724c..bdd3aab7 100644 --- a/app/src/main/res/drawable/ic_flash_auto_vector.xml +++ b/app/src/main/res/drawable/ic_flash_auto_vector.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/ic_flash_off_vector.xml b/app/src/main/res/drawable/ic_flash_off_vector.xml index 9d4b374c..1e019ab3 100644 --- a/app/src/main/res/drawable/ic_flash_off_vector.xml +++ b/app/src/main/res/drawable/ic_flash_off_vector.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/ic_flash_on_vector.xml b/app/src/main/res/drawable/ic_flash_on_vector.xml index 57cd3a63..6947cbab 100644 --- a/app/src/main/res/drawable/ic_flash_on_vector.xml +++ b/app/src/main/res/drawable/ic_flash_on_vector.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/ic_photo_16x9.xml b/app/src/main/res/drawable/ic_photo_16x9.xml new file mode 100644 index 00000000..bc210589 --- /dev/null +++ b/app/src/main/res/drawable/ic_photo_16x9.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_photo_1x1.xml b/app/src/main/res/drawable/ic_photo_1x1.xml new file mode 100644 index 00000000..3d9a453f --- /dev/null +++ b/app/src/main/res/drawable/ic_photo_1x1.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_photo_4x3.xml b/app/src/main/res/drawable/ic_photo_4x3.xml new file mode 100644 index 00000000..2907e907 --- /dev/null +++ b/app/src/main/res/drawable/ic_photo_4x3.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_photo_full.xml b/app/src/main/res/drawable/ic_photo_full.xml new file mode 100644 index 00000000..48697239 --- /dev/null +++ b/app/src/main/res/drawable/ic_photo_full.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_video_fhd.xml b/app/src/main/res/drawable/ic_video_fhd.xml new file mode 100644 index 00000000..16b240a5 --- /dev/null +++ b/app/src/main/res/drawable/ic_video_fhd.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_video_hd.xml b/app/src/main/res/drawable/ic_video_hd.xml new file mode 100644 index 00000000..efc8d803 --- /dev/null +++ b/app/src/main/res/drawable/ic_video_hd.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_video_sd.xml b/app/src/main/res/drawable/ic_video_sd.xml new file mode 100644 index 00000000..1db2f721 --- /dev/null +++ b/app/src/main/res/drawable/ic_video_sd.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_video_uhd.xml b/app/src/main/res/drawable/ic_video_uhd.xml new file mode 100644 index 00000000..3aa0d9d4 --- /dev/null +++ b/app/src/main/res/drawable/ic_video_uhd.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/app/src/main/res/drawable/tab_indicator.xml b/app/src/main/res/drawable/tab_indicator.xml index 925ef230..afaa1853 100644 --- a/app/src/main/res/drawable/tab_indicator.xml +++ b/app/src/main/res/drawable/tab_indicator.xml @@ -1,5 +1,14 @@ - - - - + + + + + + + + + diff --git a/app/src/main/res/drawable/tab_indicator_selected.xml b/app/src/main/res/drawable/tab_indicator_selected.xml deleted file mode 100644 index e9b77dcf..00000000 --- a/app/src/main/res/drawable/tab_indicator_selected.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - diff --git a/app/src/main/res/drawable/tab_indicator_unselected.xml b/app/src/main/res/drawable/tab_indicator_unselected.xml deleted file mode 100644 index 76589c0c..00000000 --- a/app/src/main/res/drawable/tab_indicator_unselected.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 3ab53b46..53ab12f8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,7 +6,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/black" - android:fitsSystemWindows="true"> + android:fitsSystemWindows="false"> - + app:layout_constraintTop_toTopOf="parent" + tools:visibility="visible" /> + + + + + app:layout_constraintTop_toTopOf="@id/toggle_flash" + tools:src="@drawable/ic_photo_4x3" /> + + diff --git a/app/src/main/res/layout/layout_flash.xml b/app/src/main/res/layout/layout_flash.xml new file mode 100644 index 00000000..fd3bdfba --- /dev/null +++ b/app/src/main/res/layout/layout_flash.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_media_size.xml b/app/src/main/res/layout/layout_media_size.xml new file mode 100644 index 00000000..c7562f84 --- /dev/null +++ b/app/src/main/res/layout/layout_media_size.xml @@ -0,0 +1,8 @@ + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 5ff71dc3..5331afbe 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,5 +1,7 @@ 56dp + 48dp + 24dp 10dp diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml new file mode 100644 index 00000000..020243de --- /dev/null +++ b/app/src/main/res/values/ids.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 1ba2a099..4b6004f7 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -4,10 +4,24 @@ + +