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>
12 KiB
12 KiB
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
- ConnectionBloc - Server connection states
- WallBloc - Video wall state, monitor selection
- AlarmBloc - Active alarms, alarm history
- CameraBloc - Camera input, CrossSwitch operations
- PTZBloc - Lock state, telemetry controls
- PlaybackBloc - PvZ mode, jog-shuttle
- PrepositionBloc - Preposition list, add/delete
- FunctionButtonBloc - Function button configurations
- SequenceBloc - Sequence state per monitor
Events & States Example (WallBloc)
// 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)
- Main screen layout with wall grid
- Monitor selection (touch)
- Camera number input (prefix + digits)
- CrossSwitch command
- Connection status bar
Phase 2: Alarms & Status
- Alarm state display (red monitors)
- Alarm blocking (prevent CrossSwitch on active alarm)
- Monitor lock indicators
Phase 3: PTZ & Playback
- PTZ lock/unlock
- Telemetry controls (pan/tilt/zoom)
- Playback mode (PvZ)
- Jog-shuttle controls
Phase 4: Advanced Features
- Preposition management
- Alarm history list
- Function buttons (F1-F7, HOME)
- Sequences
- Search functionality
Phase 5: Polish
- Service menu
- CAMEA integration
- Autonomous mode fallbacks
- 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/