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(val context: AppCompatActivity, val statusDrawer: IShowInformation, val camera: ICameraController, private val preferences: PreferenceDataStore, val liveImageView: ILiveImageStatusNotify, val optionSet : ThetaOptionUpdateControl, val statusHolder : IThetaStatusHolder, 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)
40 var duration = IShowInformation.VIBRATE_PATTERN_SIMPLE_SHORT
41 when (featureNumber) {
42 ICameraFeatureDispatcher.FEATURE_TOGGLE_SHOW_GRID -> // グリッド標示ON/OFF
43 changeShowGrid(objectId)
44 ICameraFeatureDispatcher.FEATURE_SHUTTER_SINGLESHOT -> // シャッター(一枚撮影)
46 ICameraFeatureDispatcher.FEATURE_SETTINGS -> {
47 showSettingsScreen() // 設定画面を開く
48 duration = IShowInformation.VIBRATE_PATTERN_NONE
50 ICameraFeatureDispatcher.FEATURE_CONTROL_MOVIE -> // 動画の撮影・撮影終了
52 ICameraFeatureDispatcher.FEATURE_CHANGE_TAKEMODE -> // 撮影モードの変更
54 ICameraFeatureDispatcher.FEATURE_CHANGE_TAKEMODE_REVERSE -> // 撮影モードの変更(逆順)
55 changeTakeModeReverse()
56 ICameraFeatureDispatcher.FEATURE_EXPOSURE_BIAS_DOWN -> // 露出補正を1段階下げる
57 changeExposureBiasValueDown()
58 ICameraFeatureDispatcher.FEATURE_EXPOSURE_BIAS_UP -> // 露出補正を1段階上げる
59 changeExposureBiasValueUp()
60 ICameraFeatureDispatcher.FEATURE_SHOW_FAVORITE_DIALOG -> // FILTER MODE (SHOW_FAVORITE_DIALOG)
62 ICameraFeatureDispatcher.FEATURE_CHAGE_AE_LOCK_MODE -> // Exposure Program(AE LOCKのON/OFF切り替え)
63 changeExposureProgram()
64 ICameraFeatureDispatcher.FEATURE_WB_DOWN -> // ホワイトバランスを選択
65 changeWhiteBalanceDown()
66 ICameraFeatureDispatcher.FEATURE_WB_UP -> // ホワイトバランスを選択
67 changeWhiteBalanceUp()
70 ICameraFeatureDispatcher.FEATURE_APERTURE_DOWN -> // 絞り値を1段階下げる
71 changeApertureValueDown()
72 ICameraFeatureDispatcher.FEATURE_APERTURE_UP -> // 絞り値を1段階上げる
73 changeApertureValueUp()
74 ICameraFeatureDispatcher.FEATURE_SHUTTER_SPEED_DOWN -> // シャッター速度を1段階下げる
75 changeShutterSpeedDown()
76 ICameraFeatureDispatcher.FEATURE_SHUTTER_SPEED_UP -> // シャッター速度を1段階上げる
77 changeShutterSpeedUp()
78 ICameraFeatureDispatcher.FEATURE_COLORTONE_DOWN -> // 仕上がり・ピクチャーモードを選択
80 ICameraFeatureDispatcher.FEATURE_COLORTONE_UP -> // 仕上がり・ピクチャーモードを選択
82 ICameraFeatureDispatcher.FEATURE_ART_FILTER_DOWN -> // アートフィルターを選択
84 ICameraFeatureDispatcher.FEATURE_ART_FILTER_UP -> // アートフィルターを選択
86 ICameraFeatureDispatcher.FEATURE_TOGGLE_SHOW_LEVEL_GAUGE -> // デジタル水準器の表示・非表示
87 changeShowLevelGauge()
88 ICameraFeatureDispatcher.FEATURE_AE_DOWN -> // AE(測光方式)を選択
90 ICameraFeatureDispatcher.FEATURE_AE_UP -> // AE(測光方式)を選択
92 ICameraFeatureDispatcher.FEATURE_ISO_DOWN -> // ISO感度を選択
93 changeIsoSensitivityDown()
94 ICameraFeatureDispatcher.FEATURE_ISO_UP -> // ISO感度を選択
95 changeIsoSensitivityUp()
96 ICameraFeatureDispatcher.FEATURE_QUALITY_MOVIE_DOWN -> // 動画撮影クオリティを選択
97 changeMovieQualityModeDown()
98 ICameraFeatureDispatcher.FEATURE_QUALITY_MOVIE_UP -> // 動画撮影クオリティを選択
99 changeMovieQualityModeUp()
100 ICameraFeatureDispatcher.FEATURE_SHORT_MOVIE_RECORD_TIME_DOWN -> // ショートムービー時の撮影時間を選択
101 changeShortMovieRecordLengthDown()
102 ICameraFeatureDispatcher.FEATURE_SHORT_MOVIE_RECORD_TIME_UP -> // ショートムービー時の撮影時間を選択
103 changeShortMovieRecordLengthUp()
104 ICameraFeatureDispatcher.FEATURE_EXPOSE_MOVIE_SELECT_DOWN -> // 動画の撮影モードを選択
105 changeMovieTakeModeDown()
106 ICameraFeatureDispatcher.FEATURE_EXPOSE_MOVIE_SELECT_UP -> // 動画の撮影モードを選択
107 changeMovieTakeModeUp()
108 ICameraFeatureDispatcher.FEATURE_CHANGE_AF_MF -> // AF/MFの切り替えを行う
110 ICameraFeatureDispatcher.FEATURE_CHANGE_AE -> // AE(測光方式)を選択
112 ICameraFeatureDispatcher.FEATURE_CHANGE_AE_REVERSE -> // AE(測光方式)を選択
114 ICameraFeatureDispatcher.FEATURE_SHOT_INTERVAL_3SEC -> // 3秒待ってから1枚撮影する
116 ICameraFeatureDispatcher.FEATURE_SHOT_INTERVAL_5SEC -> // 5秒待ってから1枚撮影する
118 ICameraFeatureDispatcher.FEATURE_SHOT_INTERVAL_10SEC -> // 10秒待ってから1枚撮影する
120 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_EXPOSURE -> // 露出ブラケット撮影を行う (5枚)
121 bracketingShot(IBracketingShotStyle.BRACKET_EXPREV, 5)
122 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_APERATURE -> // 絞りブラケット撮影を行う
123 bracketingShot(IBracketingShotStyle.BRACKET_APERTURE, 5)
124 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_SHUTTER -> // シャッターブラケット撮影を行う
125 bracketingShot(IBracketingShotStyle.BRACKET_SHUTTER, 5)
126 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_COLORTONE -> // カラートーンブラケット撮影を行う
127 bracketingShot(IBracketingShotStyle.BRACKET_COLOR_TONE, 11)
128 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_WB -> // ホワイトバランスブラケット撮影を行う
129 bracketingShot(IBracketingShotStyle.BRACKET_WB, 7)
130 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_ART_FILTER -> // アートフィルターブラケット撮影を行う
131 bracketingShot(IBracketingShotStyle.BRACKET_ART_FILTER, 5)
132 ICameraFeatureDispatcher.FEATURE_SHOT_BRACKET_ISO -> // ブラケット撮影を行う
133 bracketingShot(IBracketingShotStyle.BRACKET_ISO, 3)
134 ICameraFeatureDispatcher.FEATURE_SHOW_FAVORITE_DIALOG -> // お気に入りのダイアログ表示を行う
136 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMIN -> // ズームイン(パワーズームレンズ装着時)
137 if (!driveZoomLens(1)) {
138 duration = IShowInformation.VIBRATE_PATTERN_NONE
140 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMOUT -> // ズームアウト(パワーズームレンズ装着時)
141 if (!driveZoomLens(-1)) {
142 duration = IShowInformation.VIBRATE_PATTERN_NONE
144 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMIN_2X -> // ズームイン(パワーズームレンズ装着時)
145 if (!driveZoomLens(2)) {
146 duration = IShowInformation.VIBRATE_PATTERN_NONE
148 ICameraFeatureDispatcher.FEATURE_LENS_ZOOMOUT_2X -> // ズームアウト(パワーズームレンズ装着時)
149 if (!driveZoomLens(-2)) {
150 duration = IShowInformation.VIBRATE_PATTERN_NONE
152 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOM_RESET -> // デジタルズームのリセット
154 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOM_CHANGE -> // デジタルズームの設定 (繰り返し)
155 if (!driveDigitalZoom(0)) {
156 duration = IShowInformation.VIBRATE_PATTERN_NONE
158 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOMIN -> // デジタルズーム ズームイン
159 if (!driveDigitalZoom(1)) {
160 duration = IShowInformation.VIBRATE_PATTERN_NONE
162 ICameraFeatureDispatcher.FEATURE_DIGITAL_ZOOMOUT -> // デジタルズーム ズームアウト
163 if (!driveDigitalZoom(-1)) {
164 duration = IShowInformation.VIBRATE_PATTERN_NONE
166 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X5 -> // ライブビュー拡大(5倍)
167 if (!changeLiveViewMagnify(5)) {
168 duration = IShowInformation.VIBRATE_PATTERN_NONE
170 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X7 -> // ライブビュー拡大(7倍)
171 if (!changeLiveViewMagnify(7)) {
172 duration = IShowInformation.VIBRATE_PATTERN_NONE
174 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X10 -> // ライブビュー拡大(10倍)
175 if (!changeLiveViewMagnify(10)) {
176 duration = IShowInformation.VIBRATE_PATTERN_NONE
178 ICameraFeatureDispatcher.FEATURE_CHANGE_LIVEVIEW_MAGNIFY_X14 -> // ライブビュー拡大(14倍)
179 if (!changeLiveViewMagnify(14)) {
180 duration = IShowInformation.VIBRATE_PATTERN_NONE
183 else -> // 上記以外...なにもしない
184 duration = IShowInformation.VIBRATE_PATTERN_NONE
188 statusDrawer.vibrate(duration)
192 override fun dispatchAreaAction(event: MotionEvent?, areaFeatureNumber: Int): Boolean
195 when (areaFeatureNumber)
197 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_DRIVE_AUTOFOCUS -> ret = camera.driveAutoFocus(event)
198 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_NOT_CONNECTED -> {
200 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_CHECK_CONTAINS_AUTOFOCUS_AREA -> // AUTOFOCUS エリアに含まれているかどうかチェックする
201 ret = camera.isContainsAutoFocusPoint(event)
202 ICameraFeatureDispatcher.FEATURE_AREA_ACTION_NONE -> // 何もしない
213 override fun getTakeMode(): String
215 return (statusHolder.captureMode)
221 private fun changeTakeMode()
224 camera.updateTakeMode();
229 * (iAuto < P < A < S < M < ART < movie < iAuto < ...)
231 private fun changeTakeModeReverse()
238 * (現在は、連続撮影モードについてはまだ非対応)
240 private fun pushShutterButton()
250 private fun movieControl()
252 camera.movieControl()
259 private fun changeFilterMode()
263 thetaFilterModeIndex++
264 if (thetaFilterModeIndex > MAX_FILTER_SELECTION)
266 thetaFilterModeIndex = 0
268 val optionStr = context.resources.getStringArray(R.array.theta_filter_set_value)[thetaFilterModeIndex]
269 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
271 catch (e : Exception)
281 private fun changeExposureProgram()
285 exposureProgramIndex++
286 if (exposureProgramIndex > MAX_EXPOSURE_PROGRAM)
288 exposureProgramIndex = 0
290 val optionStr = context.resources.getStringArray(R.array.exposure_program_value)[exposureProgramIndex]
291 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
293 catch (e : Exception)
302 private fun toggleAfMf()
304 camera.toggleManualFocus()
308 * グリッド表示の ON/OFFを切り替える
311 private fun changeShowGrid(objectId: Int)
313 liveImageView.toggleShowGridFrame()
314 updateGridStatusButton(objectId)
318 * デジタル水準器の ON/OFFを切り替える
321 private fun changeShowLevelGauge()
323 liveImageView.toggleShowLevelGauge()
330 private fun changeAeLockMode()
332 camera.toggleAutoExposure()
336 * グリッドフレームの表示・非表示ボタンを更新する
339 private fun updateGridStatusButton(buttonId: Int)
342 btnResId = if (liveImageView.isShowGrid) {
343 // グリッドがON状態、グリッドをOFFにするボタンを出す
344 R.drawable.btn_ic_grid_off
346 // グリッドがOFF状態、グリッドをONにするボタンを出す
347 R.drawable.btn_ic_grid_on
349 statusDrawer.setButtonDrawable(buttonId, btnResId)
355 private fun changeExposureBiasValueDown()
359 if (exposureCompensationIndex > 0)
361 exposureCompensationIndex--
363 val optionStr = context.resources.getStringArray(R.array.exposure_compensation_value)[exposureCompensationIndex]
364 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
367 catch (e : Exception)
377 private fun changeExposureBiasValueUp()
381 if (exposureCompensationIndex < MAX_EXPOSURE_COMPENSATION)
383 exposureCompensationIndex++
385 val optionStr = context.resources.getStringArray(R.array.exposure_compensation_value)[exposureCompensationIndex]
386 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
389 catch (e : Exception)
398 private fun changeApertureValueDown()
400 val propertyProxy = camera.cameraPropertyProvider
401 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.APERTURE)
408 private fun changeApertureValueUp()
410 val propertyProxy = camera.cameraPropertyProvider
411 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.APERTURE)
417 private fun changeShutterSpeedDown()
419 val propertyProxy = camera.cameraPropertyProvider
420 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.SHUTTER_SPEED)
427 private fun changeShutterSpeedUp()
429 val propertyProxy = camera.cameraPropertyProvider
430 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.SHUTTER_SPEED)
434 * 仕上がり・ピクチャーモードを1段階下げる
436 private fun changeColorToneDown()
438 val propertyProxy = camera.cameraPropertyProvider
439 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.COLOR_TONE)
443 * 仕上がり・ピクチャーモードを1段階あげる
446 private fun changeColorToneUp()
448 val propertyProxy = camera.cameraPropertyProvider
449 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.COLOR_TONE)
456 private fun changeArtFilterDown()
458 val propertyProxy = camera.cameraPropertyProvider
459 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.ART_FILTER)
466 private fun changeArtFilterUp()
468 val propertyProxy = camera.cameraPropertyProvider
469 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.ART_FILTER)
477 private fun changeAEModeDown()
479 val propertyProxy = camera.cameraPropertyProvider
480 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.AE_MODE)
487 private fun changeAEModeUp()
489 val propertyProxy = camera.cameraPropertyProvider
490 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.AE_MODE)
497 private fun changeAEMode(direction: Int)
499 val propertyProxy = camera.cameraPropertyProvider
500 propertyProxy.changeCameraProperty(IOlyCameraProperty.AE_MODE, direction)
507 private fun changeIsoSensitivityDown()
509 val propertyProxy = camera.cameraPropertyProvider
510 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.ISO_SENSITIVITY)
517 private fun changeIsoSensitivityUp()
519 val propertyProxy = camera.cameraPropertyProvider
520 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.ISO_SENSITIVITY)
528 private fun changeWhiteBalanceDown()
532 if (thetaWhiteBalanceIndex > 0)
534 thetaWhiteBalanceIndex--
536 val optionStr = context.resources.getStringArray(R.array.white_balance_value)[thetaWhiteBalanceIndex]
537 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
540 catch (e : Exception)
550 private fun changeWhiteBalanceUp()
554 if (thetaWhiteBalanceIndex < MAX_WHITE_BALANCE)
556 thetaWhiteBalanceIndex++
558 val optionStr = context.resources.getStringArray(R.array.white_balance_value)[thetaWhiteBalanceIndex]
559 optionSet.setOptions(optionStr, sessionIdProvider.sessionId.isEmpty())
562 catch (e : Exception)
572 private fun changeMovieQualityModeDown()
574 val propertyProxy = camera.cameraPropertyProvider
575 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.QUALITY_MOVIE)
582 private fun changeMovieQualityModeUp()
584 val propertyProxy = camera.cameraPropertyProvider
585 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.QUALITY_MOVIE)
590 * 動画撮影モードがショートムービーのときの撮影時間を1段階さげる
593 private fun changeShortMovieRecordLengthDown()
595 val propertyProxy = camera.cameraPropertyProvider
596 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.SHORT_MOVIE_RECORD_TIME)
600 * 動画撮影モードがショートムービーのときの撮影時間を1段階あげる
603 private fun changeShortMovieRecordLengthUp()
605 val propertyProxy = camera.cameraPropertyProvider
606 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.SHORT_MOVIE_RECORD_TIME)
614 private fun changeMovieTakeModeDown()
616 val propertyProxy = camera.cameraPropertyProvider
617 propertyProxy.updateCameraPropertyDown(IOlyCameraProperty.TAKE_MODE_MOVIE)
624 private fun changeMovieTakeModeUp()
626 val propertyProxy = camera.cameraPropertyProvider
627 propertyProxy.updateCameraPropertyUp(IOlyCameraProperty.TAKE_MODE_MOVIE)
633 * @param waitSeconds 撮影待ち時間(単位:秒)
635 private fun intervalOneShot(waitSeconds: Int)
637 camera.bracketingShot(IBracketingShotStyle.BRACKET_NONE, 1, waitSeconds)
643 * @param style 撮影スタイル
646 private fun bracketingShot(style: Int, count: Int)
648 camera.bracketingShot(style, count, 0)
656 private fun showFavoriteDialog()
659 statusDrawer.showFavoriteSettingsDialog()
665 * @param direction ズーム操作の方向
667 private fun driveZoomLens(direction: Int): Boolean
669 var isExecute = false
670 val zoom = camera.zoomLensHolder
679 zoom.driveZoomLens(direction)
691 private fun resetDigitalZoom()
693 val zoom = camera.zoomLensHolder
697 zoom.changeDigitalZoomScale(1.0f, false)
701 private fun driveDigitalZoom(zoomType: Int): Boolean
703 var isExecute = false
704 val zoom = camera.zoomLensHolder
708 var magnify = zoomType.toFloat()
713 val currentScale = zoom.currentDigitalZoomScale
714 val targetScale = currentScale + magnify * 0.5f
715 zoom.changeDigitalZoomScale(targetScale, zoomType == 0)
722 * ライブビューのサイズを指定した倍率に拡大する(拡大中の場合にはもとに戻す。)
725 * @return 実行した場合true, 実行しなかった場合はfalse
727 private fun changeLiveViewMagnify(scale: Int): Boolean
729 var isExecute = false
730 val zoom = camera.zoomLensHolder
733 isExecute = zoom.magnifyLiveView(scale)
742 private fun showSettingsScreen()
746 Log.v(TAG, " --- showSettingsScreen() ---")
756 private val TAG = ThetaFeatureDispatcher::class.java.simpleName
758 private const val MAX_EXPOSURE_COMPENSATION = 12 // exposureCompensation
759 private const val MAX_EXPOSURE_PROGRAM = 4 // exposureProgram
760 private const val MAX_FILTER_SELECTION = 4 // _filter
761 private const val MAX_WHITE_BALANCE = 11 // whiteBalance