1 package jp.sfjp.gokigen.a01c.thetacamerawrapper
3 import android.util.Log
4 import android.view.MotionEvent
5 import androidx.appcompat.app.AppCompatActivity
6 import androidx.preference.PreferenceDataStore
7 import jp.sfjp.gokigen.a01c.ICameraController
8 import jp.sfjp.gokigen.a01c.ICameraFeatureDispatcher
9 import jp.sfjp.gokigen.a01c.IShowInformation
10 import jp.sfjp.gokigen.a01c.R
11 import jp.sfjp.gokigen.a01c.liveview.ILiveImageStatusNotify
12 import jp.sfjp.gokigen.a01c.olycamerawrapper.property.IOlyCameraProperty
13 import jp.sfjp.gokigen.a01c.olycamerawrapper.takepicture.IBracketingShotStyle
14 import jp.sfjp.gokigen.a01c.thetacamerawrapper.operation.ThetaOptionUpdateControl
16 class ThetaFeatureDispatcher(private val context: AppCompatActivity, private val statusDrawer: IShowInformation, private val camera: ICameraController, private val preferences: PreferenceDataStore, private val liveImageView: ILiveImageStatusNotify, private val optionSet : ThetaOptionUpdateControl, private val statusHolder : IThetaStatusHolder, private val sessionIdProvider : IThetaSessionIdProvider): ICameraFeatureDispatcher
18 private var exposureCompensationIndex : Int = 6
19 private var exposureProgramIndex : Int = 1
20 private var thetaFilterModeIndex : Int = 0
21 private var thetaWhiteBalanceIndex : Int = 0
26 * @param objectId 操作したオブジェクト
28 * @param defaultAction 標準機能
30 override fun dispatchAction(objectId: Int, key: String, defaultAction: Int): Boolean
32 val featureNumber = preferences.getInt(key, defaultAction)
33 if (featureNumber <= ICameraFeatureDispatcher.FEATURE_ACTION_NONE)
39 // AREA1: Movie/Video切替
40 // AREA2: Exposure Program
42 // AREA4: Settings (未実装)
45 var duration = IShowInformation.VIBRATE_PATTERN_SIMPLE_SHORT
46 when (featureNumber) {
47 ICameraFeatureDispatcher.FEATURE_TOGGLE_SHOW_GRID -> // グリッド標示ON/OFF
48 changeShowGrid(objectId)
49 ICameraFeatureDispatcher.FEATURE_SHUTTER_SINGLESHOT -> // シャッター(一枚撮影)
51 ICameraFeatureDispatcher.FEATURE_SETTINGS -> {
52 showSettingsScreen() // 設定画面を開く
53 duration = IShowInformation.VIBRATE_PATTERN_NONE
55 ICameraFeatureDispatcher.FEATURE_CONTROL_MOVIE -> // 動画の撮影・撮影終了
57 ICameraFeatureDispatcher.FEATURE_CHANGE_TAKEMODE -> // 撮影モードの変更
59 ICameraFeatureDispatcher.FEATURE_CHANGE_TAKEMODE_REVERSE -> // 撮影モードの変更(逆順)
60 changeTakeModeReverse()
61 ICameraFeatureDispatcher.FEATURE_EXPOSURE_BIAS_DOWN -> // 露出補正を1段階下げる
62 changeExposureBiasValueDown()
63 ICameraFeatureDispatcher.FEATURE_EXPOSURE_BIAS_UP -> // 露出補正を1段階上げる
64 changeExposureBiasValueUp()
65 ICameraFeatureDispatcher.FEATURE_SHOW_FAVORITE_DIALOG -> // Exposure Program(SHOW_FAVORITE_DIALOG)
66 changeExposureProgram()
67 ICameraFeatureDispatcher.FEATURE_CHAGE_AE_LOCK_MODE -> // FILTER MODE (AE LOCKのON/OFF切り替え)
69 ICameraFeatureDispatcher.FEATURE_CHANGE_AE -> // FILTER MODE AE(測光方式)を選択
71 ICameraFeatureDispatcher.FEATURE_WB_DOWN -> // ホワイトバランスを選択
72 changeWhiteBalanceDown()
73 ICameraFeatureDispatcher.FEATURE_WB_UP -> // ホワイトバランスを選択
74 changeWhiteBalanceUp()
77 ICameraFeatureDispatcher.FEATURE_APERTURE_DOWN -> // 絞り値を1段階下げる
78 changeApertureValueDown()
79 ICameraFeatureDispatcher.FEATURE_APERTURE_UP -> // 絞り値を1段階上げる
80 changeApertureValueUp()
81 ICameraFeatureDispatcher.FEATURE_SHUTTER_SPEED_DOWN -> // シャッター速度を1段階下げる
82 changeShutterSpeedDown()
83 ICameraFeatureDispatcher.FEATURE_SHUTTER_SPEED_UP -> // シャッター速度を1段階上げる
84 changeShutterSpeedUp()
85 ICameraFeatureDispatcher.FEATURE_COLORTONE_DOWN -> // 仕上がり・ピクチャーモードを選択
87 ICameraFeatureDispatcher.FEATURE_COLORTONE_UP -> // 仕上がり・ピクチャーモードを選択
89 ICameraFeatureDispatcher.FEATURE_ART_FILTER_DOWN -> // アートフィルターを選択
91 ICameraFeatureDispatcher.FEATURE_ART_FILTER_UP -> // アートフィルターを選択
93 ICameraFeatureDispatcher.FEATURE_TOGGLE_SHOW_LEVEL_GAUGE -> // デジタル水準器の表示・非表示
94 changeShowLevelGauge()
95 ICameraFeatureDispatcher.FEATURE_AE_DOWN -> // AE(測光方式)を選択
97 ICameraFeatureDispatcher.FEATURE_AE_UP -> // AE(測光方式)を選択
99 ICameraFeatureDispatcher.FEATURE_ISO_DOWN -> // ISO感度を選択
100 changeIsoSensitivityDown()
101 ICameraFeatureDispatcher.FEATURE_ISO_UP -> // ISO感度を選択
102 changeIsoSensitivityUp()
103 ICameraFeatureDispatcher.FEATURE_QUALITY_MOVIE_DOWN -> // 動画撮影クオリティを選択
104 changeMovieQualityModeDown()
105 ICameraFeatureDispatcher.FEATURE_QUALITY_MOVIE_UP -> // 動画撮影クオリティを選択
106 changeMovieQualityModeUp()
107 ICameraFeatureDispatcher.FEATURE_SHORT_MOVIE_RECORD_TIME_DOWN -> // ショートムービー時の撮影時間を選択
108 changeShortMovieRecordLengthDown()
109 ICameraFeatureDispatcher.FEATURE_SHORT_MOVIE_RECORD_TIME_UP -> // ショートムービー時の撮影時間を選択
110 changeShortMovieRecordLengthUp()
111 ICameraFeatureDispatcher.FEATURE_EXPOSE_MOVIE_SELECT_DOWN -> // 動画の撮影モードを選択
112 changeMovieTakeModeDown()
113 ICameraFeatureDispatcher.FEATURE_EXPOSE_MOVIE_SELECT_UP -> // 動画の撮影モードを選択
114 changeMovieTakeModeUp()
115 ICameraFeatureDispatcher.FEATURE_CHANGE_AF_MF -> // AF/MFの切り替えを行う
117 ICameraFeatureDispatcher.FEATURE_CHANGE_AE -> // AE(測光方式)を選択
119 ICameraFeatureDispatcher.FEATURE_CHANGE_AE_REVERSE -> // AE(測光方式)を選択
121 ICameraFeatureDispatcher.FEATURE_SHOT_INTERVAL_3SEC -> // 3秒待ってから1枚撮影する
123 ICameraFeatureDispatcher.FEATURE_SHOT_INTERVAL_5SEC -> // 5秒待ってから1枚撮影する
125 ICameraFeatureDispatcher.FEATURE_SHOT_INTERVAL_10SEC -> // 10秒待ってから1枚撮影する
127 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_EXPOSURE -> // 露出ブラケット撮影を行う (5枚)
128 bracketingShot(IBracketingShotStyle.BRACKET_EXPREV, 5)
129 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_APERATURE -> // 絞りブラケット撮影を行う
130 bracketingShot(IBracketingShotStyle.BRACKET_APERTURE, 5)
131 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_SHUTTER -> // シャッターブラケット撮影を行う
132 bracketingShot(IBracketingShotStyle.BRACKET_SHUTTER, 5)
133 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_COLORTONE -> // カラートーンブラケット撮影を行う
134 bracketingShot(IBracketingShotStyle.BRACKET_COLOR_TONE, 11)
135 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_WB -> // ホワイトバランスブラケット撮影を行う
136 bracketingShot(IBracketingShotStyle.BRACKET_WB, 7)
137 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_ART_FILTER -> // アートフィルターブラケット撮影を行う
138 bracketingShot(IBracketingShotStyle.BRACKET_ART_FILTER, 5)
139 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_ISO -> // ブラケット撮影を行う
140 bracketingShot(IBracketingShotStyle.BRACKET_ISO, 3)
141 ICameraFeatureDispatcher.FEATURE_SHOW_FAVORITE_DIALOG -> // お気に入りのダイアログ表示を行う
143 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMIN -> // ズームイン(パワーズームレンズ装着時)
144 if (!driveZoomLens(1)) {
145 duration = IShowInformation.VIBRATE_PATTERN_NONE
147 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMOUT -> // ズームアウト(パワーズームレンズ装着時)
148 if (!driveZoomLens(-1)) {
149 duration = IShowInformation.VIBRATE_PATTERN_NONE
151 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMIN_2X -> // ズームイン(パワーズームレンズ装着時)
152 if (!driveZoomLens(2)) {
153 duration = IShowInformation.VIBRATE_PATTERN_NONE
155 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMOUT_2X -> // ズームアウト(パワーズームレンズ装着時)
156 if (!driveZoomLens(-2)) {
157 duration = IShowInformation.VIBRATE_PATTERN_NONE
159 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOM_RESET -> // デジタルズームのリセット
161 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOM_CHANGE -> // デジタルズームの設定 (繰り返し)
162 if (!driveDigitalZoom(0)) {
163 duration = IShowInformation.VIBRATE_PATTERN_NONE
165 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOMIN -> // デジタルズーム ズームイン
166 if (!driveDigitalZoom(1)) {
167 duration = IShowInformation.VIBRATE_PATTERN_NONE
169 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOMOUT -> // デジタルズーム ズームアウト
170 if (!driveDigitalZoom(-1)) {
171 duration = IShowInformation.VIBRATE_PATTERN_NONE
173 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X5 -> // ライブビュー拡大(5倍)
174 if (!changeLiveViewMagnify(5)) {
175 duration = IShowInformation.VIBRATE_PATTERN_NONE
177 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X7 -> // ライブビュー拡大(7倍)
178 if (!changeLiveViewMagnify(7)) {
179 duration = IShowInformation.VIBRATE_PATTERN_NONE
181 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X10 -> // ライブビュー拡大(10倍)
182 if (!changeLiveViewMagnify(10)) {
183 duration = IShowInformation.VIBRATE_PATTERN_NONE
185 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X14 -> // ライブビュー拡大(14倍)
186 if (!changeLiveViewMagnify(14)) {
187 duration = IShowInformation.VIBRATE_PATTERN_NONE
190 else -> // 上記以外...なにもしない
191 duration = IShowInformation.VIBRATE_PATTERN_NONE
195 statusDrawer.vibrate(duration)
199 override fun dispatchAreaAction(event: MotionEvent?, areaFeatureNumber: Int): Boolean
202 when (areaFeatureNumber)
204 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_DRIVE_AUTOFOCUS -> ret = camera.driveAutoFocus(event)
205 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_NOT_CONNECTED -> {
207 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_CHECK_CONTAINS_AUTOFOCUS_AREA -> // AUTOFOCUS エリアに含まれているかどうかチェックする
208 ret = camera.isContainsAutoFocusPoint(event)
209 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_NONE -> // 何もしない
220 override fun getTakeMode(): String
222 return (statusHolder.captureMode)
228 private fun changeTakeMode()
231 camera.updateTakeMode()
236 * (iAuto < P < A < S < M < ART < movie < iAuto < ...)
238 private fun changeTakeModeReverse()
245 * (現在は、連続撮影モードについてはまだ非対応)
247 private fun pushShutterButton()
257 private fun movieControl()
259 camera.movieControl()
266 private fun changeFilterMode()
270 thetaFilterModeIndex++
271 if (thetaFilterModeIndex > MAX_FILTER_SELECTION)
273 thetaFilterModeIndex = 0
275 val optionStr = context.resources.getStringArray(R.array.theta_filter_set_value)[thetaFilterModeIndex]
276 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
278 catch (e : Exception)
288 private fun changeExposureProgram()
292 exposureProgramIndex++
293 if (exposureProgramIndex > MAX_EXPOSURE_PROGRAM)
295 exposureProgramIndex = 0
297 val optionStr = context.resources.getStringArray(R.array.exposure_program_value)[exposureProgramIndex]
298 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
300 catch (e : Exception)
309 private fun toggleAfMf()
311 camera.toggleManualFocus()
315 * グリッド表示の ON/OFFを切り替える
318 private fun changeShowGrid(objectId: Int)
320 liveImageView.toggleShowGridFrame()
321 updateGridStatusButton(objectId)
325 * デジタル水準器の ON/OFFを切り替える
328 private fun changeShowLevelGauge()
330 liveImageView.toggleShowLevelGauge()
337 private fun changeAeLockMode()
339 camera.toggleAutoExposure()
343 * グリッドフレームの表示・非表示ボタンを更新する
346 private fun updateGridStatusButton(buttonId: Int)
349 btnResId = if (liveImageView.isShowGrid) {
350 // グリッドがON状態、グリッドをOFFにするボタンを出す
351 R.drawable.btn_ic_grid_off
353 // グリッドがOFF状態、グリッドをONにするボタンを出す
354 R.drawable.btn_ic_grid_on
356 statusDrawer.setButtonDrawable(buttonId, btnResId)
362 private fun changeExposureBiasValueDown()
366 if (exposureCompensationIndex > 0)
368 exposureCompensationIndex--
370 val optionStr = context.resources.getStringArray(R.array.exposure_compensation_value)[exposureCompensationIndex]
371 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
374 catch (e : Exception)
384 private fun changeExposureBiasValueUp()
388 if (exposureCompensationIndex < MAX_EXPOSURE_COMPENSATION)
390 exposureCompensationIndex++
392 val optionStr = context.resources.getStringArray(R.array.exposure_compensation_value)[exposureCompensationIndex]
393 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
396 catch (e : Exception)
405 private fun changeApertureValueDown()
407 val propertyProxy = camera.cameraPropertyProvider
408 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.APERTURE)
415 private fun changeApertureValueUp()
417 val propertyProxy = camera.cameraPropertyProvider
418 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.APERTURE)
424 private fun changeShutterSpeedDown()
426 val propertyProxy = camera.cameraPropertyProvider
427 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.SHUTTER_SPEED)
434 private fun changeShutterSpeedUp()
436 val propertyProxy = camera.cameraPropertyProvider
437 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.SHUTTER_SPEED)
441 * 仕上がり・ピクチャーモードを1段階下げる
443 private fun changeColorToneDown()
445 val propertyProxy = camera.cameraPropertyProvider
446 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.COLOR_TONE)
450 * 仕上がり・ピクチャーモードを1段階あげる
453 private fun changeColorToneUp()
455 val propertyProxy = camera.cameraPropertyProvider
456 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.COLOR_TONE)
463 private fun changeArtFilterDown()
465 val propertyProxy = camera.cameraPropertyProvider
466 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.ART_FILTER)
473 private fun changeArtFilterUp()
475 val propertyProxy = camera.cameraPropertyProvider
476 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.ART_FILTER)
484 private fun changeAEModeDown()
486 val propertyProxy = camera.cameraPropertyProvider
487 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.AE_MODE)
494 private fun changeAEModeUp()
496 val propertyProxy = camera.cameraPropertyProvider
497 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.AE_MODE)
504 private fun changeAEMode(direction: Int)
506 val propertyProxy = camera.cameraPropertyProvider
507 propertyProxy.changeCameraProperty(IOlyCameraProperty.AE_MODE, direction)
514 private fun changeIsoSensitivityDown()
516 val propertyProxy = camera.cameraPropertyProvider
517 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.ISO_SENSITIVITY)
524 private fun changeIsoSensitivityUp()
526 val propertyProxy = camera.cameraPropertyProvider
527 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.ISO_SENSITIVITY)
535 private fun changeWhiteBalanceDown()
539 if (thetaWhiteBalanceIndex > 0)
541 thetaWhiteBalanceIndex--
543 val optionStr = context.resources.getStringArray(R.array.white_balance_value)[thetaWhiteBalanceIndex]
544 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
547 catch (e : Exception)
557 private fun changeWhiteBalanceUp()
561 if (thetaWhiteBalanceIndex < MAX_WHITE_BALANCE)
563 thetaWhiteBalanceIndex++
565 val optionStr = context.resources.getStringArray(R.array.white_balance_value)[thetaWhiteBalanceIndex]
566 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
569 catch (e : Exception)
579 private fun changeMovieQualityModeDown()
581 val propertyProxy = camera.cameraPropertyProvider
582 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.QUALITY_MOVIE)
589 private fun changeMovieQualityModeUp()
591 val propertyProxy = camera.cameraPropertyProvider
592 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.QUALITY_MOVIE)
597 * 動画撮影モードがショートムービーのときの撮影時間を1段階さげる
600 private fun changeShortMovieRecordLengthDown()
602 val propertyProxy = camera.cameraPropertyProvider
603 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.SHORT_MOVIE_RECORD_TIME)
607 * 動画撮影モードがショートムービーのときの撮影時間を1段階あげる
610 private fun changeShortMovieRecordLengthUp()
612 val propertyProxy = camera.cameraPropertyProvider
613 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.SHORT_MOVIE_RECORD_TIME)
621 private fun changeMovieTakeModeDown()
623 val propertyProxy = camera.cameraPropertyProvider
624 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.TAKE_MODE_MOVIE)
631 private fun changeMovieTakeModeUp()
633 val propertyProxy = camera.cameraPropertyProvider
634 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.TAKE_MODE_MOVIE)
640 * @param waitSeconds 撮影待ち時間(単位:秒)
642 private fun intervalOneShot(waitSeconds: Int)
644 camera.bracketingShot(IBracketingShotStyle.BRACKET_NONE, 1, waitSeconds)
650 * @param style 撮影スタイル
653 private fun bracketingShot(style: Int, count: Int)
655 camera.bracketingShot(style, count, 0)
663 private fun showFavoriteDialog()
666 statusDrawer.showFavoriteSettingsDialog()
672 * @param direction ズーム操作の方向
674 private fun driveZoomLens(direction: Int): Boolean
676 var isExecute = false
677 val zoom = camera.zoomLensHolder
686 zoom.driveZoomLens(direction)
698 private fun resetDigitalZoom()
700 val zoom = camera.zoomLensHolder
704 zoom.changeDigitalZoomScale(1.0f, false)
708 private fun driveDigitalZoom(zoomType: Int): Boolean
710 var isExecute = false
711 val zoom = camera.zoomLensHolder
715 var magnify = zoomType.toFloat()
720 val currentScale = zoom.currentDigitalZoomScale
721 val targetScale = currentScale + magnify * 0.5f
722 zoom.changeDigitalZoomScale(targetScale, zoomType == 0)
729 * ライブビューのサイズを指定した倍率に拡大する(拡大中の場合にはもとに戻す。)
732 * @return 実行した場合true, 実行しなかった場合はfalse
734 private fun changeLiveViewMagnify(scale: Int): Boolean
736 var isExecute = false
737 val zoom = camera.zoomLensHolder
740 isExecute = zoom.magnifyLiveView(scale)
749 private fun showSettingsScreen()
753 Log.v(TAG, " --- showSettingsScreen() ---")
763 private val TAG = ThetaFeatureDispatcher::class.java.simpleName
765 private const val MAX_EXPOSURE_COMPENSATION = 12 // exposureCompensation
766 private const val MAX_EXPOSURE_PROGRAM = 4 // exposureProgram
767 private const val MAX_FILTER_SELECTION = 4 // _filter
768 private const val MAX_WHITE_BALANCE = 11 // whiteBalance