Initial commit: COPILOT D6 Flutter keyboard controller
Flutter web app replacing legacy WPF CCTV surveillance keyboard controller. Includes wall overview, section view with monitor grid, camera input, PTZ control, alarm/lock/sequence BLoCs, and legacy-matching UI styling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
394
Docs/plans/2026-02-03-flutter-ui-design.md
Normal file
394
Docs/plans/2026-02-03-flutter-ui-design.md
Normal file
@@ -0,0 +1,394 @@
|
||||
# Flutter COPILOT Keyboard UI Design
|
||||
|
||||
## Overview
|
||||
|
||||
This document defines the Flutter UI implementation based on the existing D6 application and the Klavesnice Business Analysis specification.
|
||||
|
||||
## Screen Structure
|
||||
|
||||
### 1. Main Screen (Basic View)
|
||||
|
||||
The main screen consists of three primary areas:
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| Connection Status Bar |
|
||||
+--------------------------------------------------+
|
||||
| |
|
||||
| Video Wall Grid |
|
||||
| (Physical Monitors with Viewers) |
|
||||
| |
|
||||
+--------------------------------------------------+
|
||||
| Bottom Toolbar |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
### 2. Video Wall Grid
|
||||
|
||||
Based on D6 screenshots, the wall is divided into **5 sections**:
|
||||
- Vrchní část (Top section) - monitors 210-234
|
||||
- Pravá část (Right section)
|
||||
- Levá část (Left section)
|
||||
- Dolní část (Bottom section)
|
||||
- Střední část (Middle section)
|
||||
|
||||
Each section contains:
|
||||
- Section header with name
|
||||
- Grid of physical monitors
|
||||
- Each physical monitor can contain 1-4 viewers (quad view)
|
||||
|
||||
#### Monitor Display States
|
||||
|
||||
| State | Visual |
|
||||
|-------|--------|
|
||||
| Normal | Dark background, white text |
|
||||
| Selected (touched) | Cyan/blue border (thick) |
|
||||
| Active Alarm | Red background |
|
||||
| Alarm + Selected | Red background + cyan border |
|
||||
| Locked by current user | Lock icon visible |
|
||||
| Locked by other user | Lock icon + disabled |
|
||||
|
||||
#### Viewer Number Display
|
||||
|
||||
- Each viewer shows its viewer number (e.g., 210, 211, 212, 213)
|
||||
- Quad view: 4 viewers in one physical monitor with visible border around physical monitor
|
||||
- Single view: One viewer fills the physical monitor
|
||||
|
||||
### 3. Bottom Toolbar (Button Strip)
|
||||
|
||||
Dynamic button strip that changes based on context:
|
||||
|
||||
#### Default State (No Selection)
|
||||
```
|
||||
[Search] [500] [501] [502] [HOME] [F1] [F2] [F3] [F4] [F5] [F6] [F7]
|
||||
```
|
||||
|
||||
#### Monitor Selected (Camera View)
|
||||
```
|
||||
[←] [PREPOS] [PvZ] [ALARM] [LOCK/UNLOCK] [SEARCH]
|
||||
```
|
||||
|
||||
Where:
|
||||
- **←** Back to default
|
||||
- **PREPOS** Open preposition list (only for PTZ cameras when unlocked)
|
||||
- **PvZ** Enter playback mode (only if keyboard has permission)
|
||||
- **ALARM** Open alarm history list
|
||||
- **LOCK/UNLOCK** Toggle PTZ lock
|
||||
- **SEARCH** Open camera search dialog
|
||||
|
||||
### 4. Camera Prefix Selection
|
||||
|
||||
Three prefix buttons for camera number input:
|
||||
- **500** - GeViScope cameras (500001-500999)
|
||||
- **501** - G-CORE cameras (501001-501999)
|
||||
- **502** - GeViServer cameras (502001-502999)
|
||||
|
||||
Selected prefix is highlighted. User then types 3-digit camera number.
|
||||
|
||||
### 5. Camera Number Input
|
||||
|
||||
```
|
||||
+----------------------------------+
|
||||
| Input Field: [500] + [ ] |
|
||||
| Current: 500201 |
|
||||
+----------------------------------+
|
||||
| [1] [2] [3] |
|
||||
| [4] [5] [6] |
|
||||
| [7] [8] [9] |
|
||||
| [C] [0] [OK] |
|
||||
+----------------------------------+
|
||||
```
|
||||
|
||||
- Number input via touchscreen or physical USB keyboard
|
||||
- C = Clear, OK = Confirm CrossSwitch
|
||||
- ESC/Back = Cancel
|
||||
|
||||
---
|
||||
|
||||
## Secondary Screens
|
||||
|
||||
### 6. Search Screen
|
||||
|
||||
Opened via Search button when monitor is selected:
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| Search Camera [X] |
|
||||
+--------------------------------------------------+
|
||||
| Camera Number: [________] |
|
||||
| |
|
||||
| [Keyboard toggle] |
|
||||
+--------------------------------------------------+
|
||||
| Search Results: |
|
||||
| [500001 - Jindřišská, tramvaj] |
|
||||
| [500002 - Václavské náměstí] |
|
||||
| ... |
|
||||
+--------------------------------------------------+
|
||||
| [←] [OK] |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
### 7. Preposition List Screen
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| PREPOZICE - Kamera 500005 [X] |
|
||||
+--------------------------------------------------+
|
||||
| [2] Jindřišská, tramvajový ostrůvek |
|
||||
| [10] Jindřišská, křižovatka [●] |
|
||||
| [15] U Bulhara směr centrum |
|
||||
| ... |
|
||||
+--------------------------------------------------+
|
||||
| [←] [+] [🗑] [✓] |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
- Blue highlight on selected preposition
|
||||
- [+] Add new preposition (disabled if AppServer unavailable)
|
||||
- [🗑] Delete preposition (disabled if editable=0 or positions 1-9)
|
||||
- [✓] Confirm/go to selected preposition
|
||||
|
||||
### 8. Add Preposition Screen
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| Nová prepozice - Kamera 500005 [X] |
|
||||
+--------------------------------------------------+
|
||||
| Číslo prepozice: [__] (10-99 only) |
|
||||
| |
|
||||
| Název prepozice: [________________] |
|
||||
| |
|
||||
| [Keyboard] |
|
||||
+--------------------------------------------------+
|
||||
| [←] [ULOŽIT] |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
Save button disabled until both fields filled.
|
||||
|
||||
### 9. Playback Mode (PvZ) Screen
|
||||
|
||||
Overlay controls on main view:
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| PvZ: Kamera 500005 |
|
||||
| Čas: 2026-02-03 14:35:22 |
|
||||
+--------------------------------------------------+
|
||||
| [|◄] [◄◄] [◄] [⏸] [►] [►►] [►|] [LIVE] |
|
||||
+--------------------------------------------------+
|
||||
| Speed: [-7 ... -1] [0] [+1 ... +7] |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
Jog-shuttle speed table:
|
||||
- Position -7 to -1: Reverse (slow to fast)
|
||||
- Position 0: Pause
|
||||
- Position +1 to +7: Forward (slow to fast)
|
||||
|
||||
### 10. Alarm List Screen
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| Alarmy - Kamera 500005 [X] |
|
||||
+--------------------------------------------------+
|
||||
| Od: [2026-02-01] [📅] Do: [2026-02-03] [📅] |
|
||||
+--------------------------------------------------+
|
||||
| Začátek | Konec |
|
||||
| 02-03 14:30:15 | 02-03 14:32:45 [●] |
|
||||
| 02-03 12:15:30 | 02-03 12:18:22 |
|
||||
| 02-02 23:45:00 | 02-02 23:47:15 |
|
||||
+--------------------------------------------------+
|
||||
| [←] [LIVE] [⏩] [▶⏩] [◄◄] [⏸] |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
- [⏩] Jump to timestamp (paused)
|
||||
- [▶⏩] Jump to timestamp and play
|
||||
- [◄◄] Reverse playback
|
||||
- [⏸] Stop playback
|
||||
- [LIVE] Return to live stream
|
||||
|
||||
### 11. Function Button Config (F1-F7, HOME)
|
||||
|
||||
Each function button triggers predefined wall configuration:
|
||||
- Stored on Application Server
|
||||
- Can set camera or sequence per monitor
|
||||
- Before CrossSwitch, check if sequence is running and stop it
|
||||
|
||||
### 12. Service Menu
|
||||
|
||||
Activated by holding Backspace for 3 seconds:
|
||||
|
||||
```
|
||||
+----------------------------------+
|
||||
| Servisní Menu [X] |
|
||||
+----------------------------------+
|
||||
| (1) Restartovat aplikaci |
|
||||
| (2) Restartovat klávesnici |
|
||||
| (3) Vypnout klávesnici |
|
||||
+----------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Component Specifications
|
||||
|
||||
### Color Palette
|
||||
|
||||
| Element | Color | Hex |
|
||||
|---------|-------|-----|
|
||||
| Background | Dark blue-gray | #1a2332 |
|
||||
| Monitor normal | Dark gray | #2d3748 |
|
||||
| Monitor selected | Cyan border | #00d4ff |
|
||||
| Monitor alarm | Red | #ff4444 |
|
||||
| Button active | Blue | #3182ce |
|
||||
| Button disabled | Gray | #4a5568 |
|
||||
| Text primary | White | #ffffff |
|
||||
| Text secondary | Gray | #a0aec0 |
|
||||
| Preposition highlight | Blue | #2b6cb0 |
|
||||
|
||||
### Typography
|
||||
|
||||
- Monitor numbers: Monospace, bold, 16-20px
|
||||
- Section headers: Sans-serif, semibold, 14px
|
||||
- Button labels: Sans-serif, medium, 12-14px
|
||||
- Input fields: Monospace, regular, 16px
|
||||
|
||||
### Touch Targets
|
||||
|
||||
- Minimum touch target: 44x44 pixels
|
||||
- Monitor tiles: Variable (based on grid)
|
||||
- Toolbar buttons: 48px height
|
||||
- List items: 48px height minimum
|
||||
|
||||
---
|
||||
|
||||
## State Management (BLoC)
|
||||
|
||||
### Required BLoCs
|
||||
|
||||
1. **ConnectionBloc** - Server connection states
|
||||
2. **WallBloc** - Video wall state, monitor selection
|
||||
3. **AlarmBloc** - Active alarms, alarm history
|
||||
4. **CameraBloc** - Camera input, CrossSwitch operations
|
||||
5. **PTZBloc** - Lock state, telemetry controls
|
||||
6. **PlaybackBloc** - PvZ mode, jog-shuttle
|
||||
7. **PrepositionBloc** - Preposition list, add/delete
|
||||
8. **FunctionButtonBloc** - Function button configurations
|
||||
9. **SequenceBloc** - Sequence state per monitor
|
||||
|
||||
### Events & States Example (WallBloc)
|
||||
|
||||
```dart
|
||||
// Events
|
||||
abstract class WallEvent {}
|
||||
class LoadWallConfig extends WallEvent {}
|
||||
class SelectMonitor extends WallEvent { final int viewerId; }
|
||||
class DeselectMonitor extends WallEvent {}
|
||||
class CrossSwitchCamera extends WallEvent { final int cameraId; final int viewerId; }
|
||||
|
||||
// States
|
||||
abstract class WallState {}
|
||||
class WallLoading extends WallState {}
|
||||
class WallLoaded extends WallState {
|
||||
final List<WallSection> sections;
|
||||
final int? selectedViewerId;
|
||||
final int? selectedPhysicalMonitorId;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Priority
|
||||
|
||||
### Phase 1: Core UI (MVP)
|
||||
1. Main screen layout with wall grid
|
||||
2. Monitor selection (touch)
|
||||
3. Camera number input (prefix + digits)
|
||||
4. CrossSwitch command
|
||||
5. Connection status bar
|
||||
|
||||
### Phase 2: Alarms & Status
|
||||
1. Alarm state display (red monitors)
|
||||
2. Alarm blocking (prevent CrossSwitch on active alarm)
|
||||
3. Monitor lock indicators
|
||||
|
||||
### Phase 3: PTZ & Playback
|
||||
1. PTZ lock/unlock
|
||||
2. Telemetry controls (pan/tilt/zoom)
|
||||
3. Playback mode (PvZ)
|
||||
4. Jog-shuttle controls
|
||||
|
||||
### Phase 4: Advanced Features
|
||||
1. Preposition management
|
||||
2. Alarm history list
|
||||
3. Function buttons (F1-F7, HOME)
|
||||
4. Sequences
|
||||
5. Search functionality
|
||||
|
||||
### Phase 5: Polish
|
||||
1. Service menu
|
||||
2. CAMEA integration
|
||||
3. Autonomous mode fallbacks
|
||||
4. Error handling dialogs
|
||||
|
||||
---
|
||||
|
||||
## Autonomous Mode Behavior
|
||||
|
||||
When Application Server is unavailable:
|
||||
|
||||
| Feature | Available | Notes |
|
||||
|---------|-----------|-------|
|
||||
| CrossSwitch | ✓ | Direct to bridge |
|
||||
| PTZ Lock | ✓ | Local lock only |
|
||||
| CAMEA Reserve | ✓ | Direct to CAMEA |
|
||||
| Preposition List | ✓ | Cached config |
|
||||
| Add Preposition | ✗ | Requires AppServer |
|
||||
| Delete Preposition | ✗ | Requires AppServer |
|
||||
| Sequences | ✗ | Run by AppServer |
|
||||
| Function Buttons | ✓ | Cached config |
|
||||
| Alarm Management | ✗ | Run by GeViSoft |
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
lib/
|
||||
├── presentation/
|
||||
│ ├── screens/
|
||||
│ │ ├── main_screen.dart
|
||||
│ │ ├── search_screen.dart
|
||||
│ │ ├── preposition_screen.dart
|
||||
│ │ ├── alarm_list_screen.dart
|
||||
│ │ ├── playback_overlay.dart
|
||||
│ │ └── service_menu_dialog.dart
|
||||
│ ├── widgets/
|
||||
│ │ ├── wall_grid/
|
||||
│ │ │ ├── wall_grid.dart
|
||||
│ │ │ ├── wall_section.dart
|
||||
│ │ │ ├── physical_monitor.dart
|
||||
│ │ │ └── viewer_tile.dart
|
||||
│ │ ├── toolbar/
|
||||
│ │ │ ├── bottom_toolbar.dart
|
||||
│ │ │ ├── prefix_buttons.dart
|
||||
│ │ │ ├── function_buttons.dart
|
||||
│ │ │ └── action_buttons.dart
|
||||
│ │ ├── input/
|
||||
│ │ │ ├── camera_input.dart
|
||||
│ │ │ ├── numeric_keypad.dart
|
||||
│ │ │ └── datetime_picker.dart
|
||||
│ │ └── common/
|
||||
│ │ ├── connection_status_bar.dart
|
||||
│ │ └── confirmation_dialog.dart
|
||||
│ └── blocs/
|
||||
│ ├── wall/
|
||||
│ ├── alarm/
|
||||
│ ├── camera/
|
||||
│ ├── ptz/
|
||||
│ ├── playback/
|
||||
│ ├── preposition/
|
||||
│ └── function_button/
|
||||
```
|
||||
Reference in New Issue
Block a user