# 画面機能仕様書 (Screen Specification)

本ドキュメントでは，SmTIAS-Capture アプリの画面設計・画面遷移・各画面の UI と動作・パーミッションを定義する．

- カメラ制御・撮影フロー・ファイル管理は [SPEC_02 カメラ撮影仕様書](SPEC_02_カメラ撮影仕様書.md) を参照
- アーキテクチャ・非機能要件は [SPEC_03 アーキテクチャと非機能](SPEC_03_アーキテクチャと非機能.md) を参照

## 画面一覧 (Screen List)

| ID | 画面名 | 概要 |
| --- | --- | --- |
| S-01 | 撮影画面 | インカメラのライブプレビューを表示し，撮影を行う |
| S-02 | 一覧画面 | 撮影済み画像のサムネイル一覧を表示し，確認・削除を行う |

※ 初期バージョンでは 2 画面構成とする．

## 画面遷移 (Screen Transition)

```text
[アプリ起動]
    │
    ▼
┌──────────┐       BottomNavigationBar       ┌──────────┐
│  S-01    │ ◄──────────────────────────────► │  S-02    │
│ 撮影画面  │         タブ切り替え              │ 一覧画面  │
└──────────┘                                  └──────────┘
                                                   │
                                                   │ サムネイルタップ
                                                   ▼
                                              ┌──────────┐
                                              │ 詳細表示   │
                                              │(インライン) │
                                              └──────────┘
```

- アプリ起動時のデフォルト画面は **撮影画面（S-01）** とする
- 画面切り替えには `home_screen.dart` の `BottomNavigationBar` を使用する（タブ 2 つ: 撮影 / 一覧）
- 画像の詳細表示は一覧画面内の `Stack` オーバーレイで実装し，独立画面・ダイアログとしない

## 撮影画面 (S-01: Capture Screen)

### レイアウト

アプリ全体を `app.dart` の `MaterialApp` ごと `Transform.rotate(angle: pi)` で 180° 回転する．これにより画面・ダイアログ・スナックバー等すべての UI が自動的に回転されるため，個々のウィジェットで回転を意識する必要がない．以下は**コード上の配置順**（回転前）を示す．操作者が逆さに置いた端末を見ると，上下が反転して表示される．

```text
操作者の視点（回転後）            コード上の配置（回転前）
┌─────────────────────┐      ┌─────────────────────┐
│ （黒い空白）          │      │  BottomNavBar        │
│  アタッチメントで隠れる │      │  明るさスライダー      │
├─────────────────────┤      │                     │
│                     │      │  カメラプレビュー      │
│  カメラプレビュー      │      │  （中央クロップ）      │
│  （中央クロップ）      │      │                     │
│                     │      ├─────────────────────┤
│  明るさスライダー      │      │ （黒い空白）          │
│  BottomNavBar        │      │  アタッチメントで隠れる │
└─────────────────────┘      └─────────────────────┘
```

※ アタッチメント（SmTIAS）により画面の約 1/3 が隠れるため，その領域は黒い空白とし，UI 要素は見える領域に配置する．

### UI 要素

| 要素 | 仕様 |
| --- | --- |
| カメラプレビュー | インカメラのライブ映像．鏡像（左右反転）＋上下反転で表示．画面いっぱいに拡大し中央をクロップ |
| シャッターボタン | 丸型ボタン（画面下部中央）．タップで撮影実行．連続撮影可 |
| タイマーボタン | 画面左下に配置．ON（黄色）/ OFF（グレー）を切り替える．ON 時はシャッター押下後 3 秒のカウントダウン表示の後に撮影 |
| サウンドボタン | 画面右下に配置．シャッター音・保存完了音の ON（黄色）/ OFF（グレー）を切り替える．設定は次回起動時も保持（`shared_preferences`） |
| 明るさスライダー | ナビバーの直下に配置．画面の輝度を手動で調整する（デフォルト: 0.8．詳細は SPEC_03 非機能要件） |
| BottomNavigationBar | 撮影タブ（アクティブ）/ 一覧タブ．背景色は黒系で統一．保存中はタップ無効 |

### 動作仕様

- **起動時**: カメラの初期化を行い，プレビューを開始する
- **即時撮影**: タイマー OFF 時，シャッターボタンタップで即座に撮影する
- **タイマー撮影**: タイマー ON 時，シャッターボタンタップで 3, 2, 1 のカウントダウン後に撮影する（手ブレ・振動防止用）
- **連続撮影**: 前回の保存完了を待ってから次の撮影が可能
- **保存中表示**: カメラの画像ストリーム（`startImageStream`）から最新フレームを保持し，撮影開始時に Android ネイティブの `YuvImage.compressToJpeg()` で JPEG 変換して表示する（オーバーレイなし・瞬時）
- **フィードバック**: 撮影成功時にスナックバーで「保存しました: [ファイル名]」を表示する
- **エラー時**: カメラ初期化失敗やストレージ書き込み失敗時は，エラーメッセージをスナックバーで表示する

> 撮影の内部処理（Camera2 マニュアル制御・撮影フロー・保存ファイル）は [SPEC_02 カメラ撮影仕様書](SPEC_02_カメラ撮影仕様書.md) を参照．

## 一覧画面 (S-02: Gallery Screen)

### レイアウト

```text
┌─────────────────────────┐
│     BottomNavBar         │
├─────────────────────────┤
│ ┌─────┐ ┌─────┐ ┌─────┐│
│ │     │ │     │ │     ││
│ │ img │ │ img │ │ img ││
│ │     │ │     │ │     ││
│ └─────┘ └─────┘ └─────┘│
│ ┌─────┐ ┌─────┐ ┌─────┐│
│ │     │ │     │ │     ││
│ │ img │ │ img │ │ img ││
│ │     │ │     │ │     ││
│ └─────┘ └─────┘ └─────┘│
│          ...             │
├─────────────────────────┤
│   [画面上部エリア]        │  ← 逆さ配置のため上部が操作側
└─────────────────────────┘
```

※ 撮影画面と同様に UI 全体を 180° 回転して表示する．

### UI 要素

| 要素 | 仕様 |
| --- | --- |
| サムネイルグリッド | 3 列のグリッド表示．新しい画像が先頭（降順） |
| サムネイル | 正方形クロップ．タップで拡大表示 |
| ファイル名ラベル | 各サムネイル下部にファイル名を表示 |
| BottomNavigationBar | 撮影タブ / 一覧タブ（アクティブ） |

### 詳細表示（インラインオーバーレイ）

| 要素 | 仕様 |
| --- | --- |
| 画像 | 一覧画面エリアを全面に覆うオーバーレイで表示．カメラプレビューと同様に上下をクロップして全面表示（`BoxFit.cover`）．ピンチ操作でズーム可能 |
| ファイル名 | オーバーレイ上部に半透明背景とともに表示 |
| 削除ボタン | オーバーレイ下部に半透明背景とともに配置．タップで削除確認ダイアログを表示 |
| 閉じるボタン | ヘッダー右端の × ボタンで閉じる |

### 動作仕様

- **画面表示時**: `Pictures/MiniTIAS/` 内のプレビュー JPEG（`.preview.jpg`）と旧通常モードの `.png` を走査し，一覧を構築する（DNG 本体は一覧では直接表示しない）
- **リフレッシュ**: 撮影画面から戻った際に一覧を再取得する
- **詳細表示**: サムネイルタップで詳細表示オーバーレイを開く．× ボタンで閉じる
- **削除**: 詳細表示の削除ボタンから確認ダイアログで「削除」を選択すると，ファイルをストレージから削除し，一覧から除去する（連動削除の詳細は SPEC_02 ファイル管理仕様）
- **空状態**: 画像が 0 件の場合は「撮影した画像がありません」のメッセージを表示する

## パーミッション管理 (Permission Handling)

### 必要なパーミッション

| パーミッション | 用途 | 対象 API レベル |
| --- | --- | --- |
| `CAMERA` | カメラプレビュー・撮影 | 全バージョン |
| `WRITE_EXTERNAL_STORAGE` | 画像保存 | API 28 以下 |
| `READ_EXTERNAL_STORAGE` | 画像一覧取得 | API 28 以下 |
| `READ_MEDIA_IMAGES` | 画像一覧取得 | API 33 以上 |

※ API 29〜32 では Scoped Storage により，アプリが MediaStore 経由で保存したファイルは追加権限なしでアクセス可能．

### パーミッション要求フロー

```text
アプリ起動
    │
    ▼
カメラ権限を確認
    │
    ├── 許可済み → カメラプレビュー開始
    │
    └── 未許可 → 権限リクエストダイアログ表示
              │
              ├── 許可 → カメラプレビュー開始
              │
              └── 拒否 → 「カメラの権限が必要です」メッセージ表示
                         ＋ 設定画面への誘導ボタン
```

- ストレージ権限は撮影時・一覧表示時にそれぞれ確認する
- `permission_handler` パッケージを使用する
