|
1 | | -# Event Editor Widget |
| 1 | +# 📍 Event Editor Widget |
2 | 2 |
|
3 | 3 | ## Overview |
4 | 4 |
|
5 | | -This module is responsible for the **Right Panel** of the Localization (Action Spotting) interface. It provides the primary mechanisms for users to: |
6 | | -1. **Create Events**: "Spot" actions at specific timestamps using dynamic category buttons. |
7 | | -2. **Manage Schema**: Add, rename, or delete annotation categories (Heads) and labels. |
8 | | -3. **Edit Events**: View, sort, and modify existing events in a detailed table view. |
9 | | -4. **Control History**: Access Undo/Redo functionality for the localization task. |
| 5 | +This module is responsible for the **Right Panel** of the Localization (Action Spotting) interface. With the latest updates, it has evolved from a purely manual tool into a **Tabbed Command Center** supporting both manual spotting and AI-powered batch inference. |
10 | 6 |
|
11 | | -## Directory Structure |
| 7 | +It provides the primary mechanisms for users to: |
| 8 | +1. **Hand Annotation**: "Spot" actions at specific timestamps using dynamic category buttons. |
| 9 | +2. **Smart Annotation**: Select a time range, run AI inference, and review predicted events before confirming them. |
| 10 | +3. **Manage Schema**: Add, rename, or delete annotation categories (Heads) and labels dynamically. |
| 11 | +4. **Edit & Sync Events**: View, sort, and modify existing events in a detailed table view, including a new feature to instantly snap an existing event to the player's current timestamp. |
| 12 | +5. **Control History**: Access global Undo/Redo functionality for the localization task. |
| 13 | + |
| 14 | +## 📂 Directory Structure |
12 | 15 |
|
13 | 16 | ```text |
14 | 17 | ui/localization/event_editor/ |
15 | | -├── __init__.py # Package entry point; assembles components into LocRightPanel. |
16 | | -├── spotting_controls.py # Top section: Tabbed interface for action spotting buttons. |
17 | | -└── annotation_table.py # Bottom section: Data grid showing the list of events. |
18 | | -
|
| 18 | +├── __init__.py # Package entry point; assembles the tabbed LocRightPanel. |
| 19 | +├── smart_spotting.py # [NEW] Interface for AI inference & prediction review. |
| 20 | +├── spotting_controls.py # Tabbed interface for dynamic action spotting buttons. |
| 21 | +└── annotation_table.py # Data grid showing the list of events (with cell editing). |
19 | 22 | ``` |
20 | 23 |
|
21 | | -## Components Breakdown |
| 24 | +## 🧩 Components Breakdown |
22 | 25 |
|
23 | 26 | ### 1. `__init__.py` |
24 | 27 |
|
25 | 28 | **Main Class:** `LocRightPanel` |
26 | 29 |
|
27 | 30 | * **Role**: The main container widget that acts as the "Right Panel" in the Localization layout. |
28 | 31 | * **Composition**: |
29 | | -* **Header**: Contains the "Annotation Controls" label and the **Undo/Redo** buttons. |
30 | | -* **Top Widget**: `AnnotationManagementWidget` (imported from `spotting_controls.py`). |
31 | | -* **Bottom Widget**: `AnnotationTableWidget` (imported from `annotation_table.py`). |
32 | | - |
| 32 | + * **Header**: Contains the "Annotation Controls" label and the global **Undo/Redo** buttons. |
| 33 | + * **Main Tabs**: A `QTabWidget` that strictly separates workflows: |
| 34 | + * **Tab 0 (Hand Annotation)**: Stacks `AnnotationManagementWidget` (Top) and `AnnotationTableWidget` (Bottom). |
| 35 | + * **Tab 1 (Smart Annotation)**: Hosts the `SmartSpottingWidget`. |
33 | 36 |
|
34 | | -* **Usage**: This class is instantiated by the `UnifiedTaskPanel` (or `MainWindowUI`) to construct the UI. |
| 37 | +### 2. `smart_spotting.py` (⭐ NEW) |
35 | 38 |
|
36 | | -### 2. `spotting_controls.py` |
37 | | - |
38 | | -**Role**: Handles the dynamic creation of buttons based on the JSON schema. It allows users to click a button to record an event at the current video timestamp. |
| 39 | +**Role**: Handles the UI for the AI-powered Action Spotting workflow. |
39 | 40 |
|
40 | 41 | **Key Classes:** |
41 | 42 |
|
42 | | -* **`SpottingTabWidget`**: |
43 | | -* A `QTabWidget` where each tab represents a **Head** (Category, e.g., "Pass", "Shot"). |
44 | | -* Supports context menus on tabs to **Rename** or **Delete** heads. |
45 | | -* Contains a special `+` tab to add new heads dynamically. |
| 43 | +* **`SmartSpottingWidget`**: |
| 44 | + * **Inference Range**: Provides custom inputs to set the start and end boundaries for the AI model using the player's current time. |
| 45 | + * **Execution**: Hosts the "Run Smart Inference" button and progress bar. |
| 46 | + * **Dual Tables**: Displays unconfirmed AI predictions in a top table (allowing users to clear or confirm them) and confirmed/manual events in a bottom table. |
| 47 | +* **`TimeLineEdit`**: |
| 48 | + * A highly customized `QLineEdit` tailored for `MM:SS.mmm` formatting. Supports free typing and keyboard arrow integration (Up/Down) to smoothly increment or decrement milliseconds/seconds. |
46 | 49 |
|
| 50 | +### 3. `spotting_controls.py` |
47 | 51 |
|
48 | | -* **`HeadSpottingPage`**: |
49 | | -* The widget inside each tab. |
50 | | -* Displays a grid of `LabelButton`s for each label defined in the schema. |
51 | | -* Includes an "Add new label" button to extend the schema on the fly. |
| 52 | +**Role**: Handles the dynamic creation of buttons based on the JSON schema for manual spotting. |
52 | 53 |
|
| 54 | +**Key Classes:** |
53 | 55 |
|
| 56 | +* **`SpottingTabWidget`**: |
| 57 | + * A `QTabWidget` where each tab represents a **Head** (Category, e.g., "Pass", "Shot"). |
| 58 | + * Supports context menus on tabs to **Rename** or **Delete** heads. |
| 59 | + * Contains a special `+` tab to add new heads dynamically. |
| 60 | +* **`HeadSpottingPage`**: |
| 61 | + * The widget inside each tab. |
| 62 | + * Displays a grid of `LabelButton`s using an optimized **Bin Packing** layout to maximize horizontal space. |
| 63 | + * Includes a live-updating "Current Time" label and an "Add new label" button. |
54 | 64 | * **`LabelButton`**: |
55 | | -* A custom `QPushButton` that emits signals for Right-Click (Context Menu) and Double-Click events. |
56 | | - |
57 | | - |
58 | | - |
59 | | -**Signals:** |
| 65 | + * A custom `QPushButton` that emits signals for Right-Click (Context Menu) and Double-Click (Rename) events. |
60 | 66 |
|
61 | | -* `spottingTriggered(head, label)`: Emitted when a user spots an action. |
62 | | -* `headAdded`, `headRenamed`, `headDeleted`: Emitted when schema structure changes. |
| 67 | +### 4. `annotation_table.py` |
63 | 68 |
|
64 | | -### 3. `annotation_table.py` |
65 | | - |
66 | | -**Role**: Displays the list of recorded events for the currently selected video. It supports direct cell editing. |
| 69 | +**Role**: Displays the list of recorded events. It supports direct cell editing and timeline synchronization. |
67 | 70 |
|
68 | 71 | **Key Classes:** |
69 | 72 |
|
70 | 73 | * **`AnnotationTableModel` (`QAbstractTableModel`)**: |
71 | | -* The underlying data model connecting the UI to the list of events. |
72 | | -* Columns: **Time** (formatted `MM:SS.mmm`), **Head**, **Label**. |
73 | | -* Implements `setData` to allow users to double-click a cell and modify the time or label directly. |
74 | | - |
75 | | - |
| 74 | + * The underlying data model connecting the UI to the list of events. |
| 75 | + * Columns: **Time** (formatted `MM:SS.mmm`), **Head**, **Label**. |
| 76 | + * Implements `setData` to allow users to double-click a cell and modify the time or label directly. |
76 | 77 | * **`AnnotationTableWidget`**: |
77 | | -* Wraps the `QTableView`. |
78 | | -* Handles row selection (syncs with the video player seek). |
79 | | -* Provides a context menu to **Delete** events. |
80 | | - |
81 | | - |
82 | | - |
83 | | -**Signals:** |
84 | | - |
85 | | -* `annotationSelected(position_ms)`: Emitted when a row is clicked (tells the player to seek). |
86 | | -* `annotationModified(old_data, new_data)`: Emitted after a cell edit (tells the Controller to push an Undo command). |
87 | | -* `annotationDeleted(event_item)`: Emitted via context menu. |
88 | | - |
89 | | -## Interaction Flow |
90 | | - |
91 | | -1. **Initialization**: The `LocalizationManager` calls `update_schema()` on the `spotting_controls` to build the tabs. |
92 | | -2. **Spotting**: |
93 | | -* User clicks a button in `HeadSpottingPage`. |
94 | | -* Signal bubbles up to `LocRightPanel` -> `LocalizationManager`. |
95 | | -* Manager grabs current player time and adds an event to the Model. |
96 | | - |
97 | | - |
98 | | -3. **Data Refresh**: |
99 | | -* The Model updates the `AnnotationTableModel`. |
100 | | -* The table refreshes to show the new row. |
101 | | - |
| 78 | + * Wraps the `QTableView`. |
| 79 | + * **[NEW] Time Sync Tool**: Includes a "Set to Current Video Time" button that allows users to select an existing event and instantly update its timestamp to the current player position. |
| 80 | + * Handles row selection (syncs with the video player seek) and provides a context menu to **Delete** events. |
102 | 81 |
|
103 | | -4. **Editing**: |
104 | | -* User edits a timestamp in the table. |
105 | | -* `AnnotationTableModel` validates the input. |
106 | | -* If valid, it updates the internal data and signals the Manager to record the change for Undo/Redo. |
| 82 | +## 🔄 Interaction Flows |
107 | 83 |
|
| 84 | +### Hand Spotting Flow |
| 85 | +1. **Initialization**: The `LocalizationManager` builds the tabs in `spotting_controls` based on the JSON schema. |
| 86 | +2. **Spotting**: User clicks a category button; a signal bubbles up to the Manager to grab the player time and add an event. |
| 87 | +3. **Editing**: User selects a row in the `AnnotationTableWidget` and clicks "Set to Current Video Time", instantly snapping the event's timestamp to the current video frame. |
108 | 88 |
|
| 89 | +### Smart Spotting Flow |
| 90 | +1. **Range Selection**: User navigates to the "Smart Annotation" tab and sets the Start/End boundaries using the `TimeLineEdit` widgets. |
| 91 | +2. **Inference**: User clicks "Run Smart Inference". A background thread clips the video and runs the AI model. |
| 92 | +3. **Review**: Predictions populate the "Predicted Events List". The user can click rows to seek to those timestamps and verify the action. |
| 93 | +4. **Confirmation**: Clicking "Confirm Predictions" merges the AI events into the core application memory (pushing an Undo command) and moves them to the "Confirmed Events List". |
109 | 94 |
|
110 | | -## Dependencies |
| 95 | +## 🛠️ Dependencies |
111 | 96 |
|
112 | 97 | * **PyQt6**: `QtWidgets`, `QtCore`, `QtGui`. |
113 | 98 | * **Project Utils**: Standard signal/slot mechanisms defined in the Controller layer. |
0 commit comments