Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/jabs/ui/dialogs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""JABS UI Dialogs Package."""

from .about_dialog import AboutDialog
from .annotation_edit_dialog import AnnotationEditDialog
from .annotation_info_dialog import AnnotationInfoDialog
from .archive_behavior_dialog import ArchiveBehaviorDialog
from .behavior_search_dialog import BehaviorSearchDialog, BehaviorSearchQuery
from .license_dialog import LicenseAgreementDialog
from .message_dialog import MessageDialog
from .progress_dialog import CustomProgressDialog
from .project_pruning_dialog import ProjectPruningDialog
from .training_report import TrainingReportDialog
from .update_check_dialog import UpdateCheckDialog
from .user_guide_dialog import UserGuideDialog

__all__ = [
"AboutDialog",
"AnnotationEditDialog",
"AnnotationInfoDialog",
"ArchiveBehaviorDialog",
"BehaviorSearchDialog",
"CustomProgressDialog",
"LicenseAgreementDialog",
"MessageDialog",
"ProjectPruningDialog",
"TrainingReportDialog",
"UpdateCheckDialog",
"UserGuideDialog",
]
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
)
from qt_material_icons import MaterialIcon

from jabs.ui.annotation_edit_dialog import AnnotationEditDialog
from jabs.ui.util import find_central_widget

from .annotation_edit_dialog import AnnotationEditDialog

if TYPE_CHECKING:
from jabs.ui.central_widget import CentralWidget
from ..main_window.central_widget import CentralWidget

# Swatch size constant for color display
SWATCH_SIZE = 20
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
QVBoxLayout,
)

from ..constants import APP_NAME, APP_NAME_LONG
from jabs.constants import APP_NAME, APP_NAME_LONG


def _read_license_text() -> str:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 5 additions & 0 deletions src/jabs/ui/main_control_widget/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""JABS Main Control Widget"""

from .main_control_widget import MainControlWidget

__all__ = ["MainControlWidget"]
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@

from jabs.classifier import Classifier
from jabs.types import ClassifierType
from jabs.ui.ear_tag_icons import EarTagIconManager

from .colors import (
from ..colors import (
BEHAVIOR_BUTTON_COLOR_BRIGHT,
BEHAVIOR_BUTTON_DISABLED_COLOR,
BEHAVIOR_COLOR,
NOT_BEHAVIOR_BUTTON_DISABLED_COLOR,
NOT_BEHAVIOR_COLOR,
NOT_BEHAVIOR_COLOR_BRIGHT,
)
from ..ear_tag_icons import EarTagIconManager
from .k_fold_slider_widget import KFoldSliderWidget
from .label_count_widget import FrameLabelCountWidget

Expand Down
10 changes: 9 additions & 1 deletion src/jabs/ui/main_window/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ This package contains the refactored MainWindow implementation, split into focus
```
main_window/
├── __init__.py # Package interface, re-exports MainWindow
├── central_widget.py # Widget managing the main content area of JABS, set as MainWindow's central widget
├── constants.py # Configuration constants and settings keys
├── menu_builder.py # Menu construction logic
├── menu_handlers.py # Menu action callbacks
├── main_window.py # Core MainWindow class
└── README.md # This file
├── README.md # This file
└── video_list_widget.py # Video List Widget, implemented as a dockable widget that can be attached to MainWindow
```

## Module Responsibilities

### `central_widget.py`
- `CentralWidget` class: Manages the main content area of the JABS Window

### `constants.py`
- Application settings keys (e.g., `RECENT_PROJECTS_KEY`, `SESSION_TRACKING_ENABLED_KEY`)
- Default values (e.g., `DEFAULT_WINDOW_WIDTH`, `DEFAULT_WINDOW_HEIGHT`)
Expand Down Expand Up @@ -48,6 +53,9 @@ main_window/

**When to add here:** Core window functionality, widget initialization, keyboard shortcuts, or methods that need access to Qt's object model.

### `video_list_widget.py`
- `VideoListWidget` class: Dockable widget for displaying the list of videos in the project. By default, it is docked to the left side of MainWindow. It can dragged to the top or right sides, or floated as a separate window. It can be shown/hidden via the View menu.

## Design Principles

### 1. Tight Coupling is Intentional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@
from jabs.pose_estimation import PoseEstimation, PoseEstimationV8
from jabs.project import Project, TimelineAnnotations, TrackLabels, VideoLabels
from jabs.types import ClassifierType
from jabs.ui.search_bar_widget import SearchBarWidget

from .annotation_edit_dialog import AnnotationEditDialog
from .classification_thread import ClassifyThread
from .exceptions import ThreadTerminatedError
from .main_control_widget import MainControlWidget
from .player_widget import PlayerWidget
from .progress_dialog import create_cancelable_progress_dialog
from .stacked_timeline_widget import StackedTimelineWidget
from .training_report import TrainingReportDialog
from .training_thread import TrainingThread

from ..classification_thread import ClassifyThread
from ..dialogs import AnnotationEditDialog, TrainingReportDialog
from ..dialogs.progress_dialog import create_cancelable_progress_dialog
from ..exceptions import ThreadTerminatedError
from ..main_control_widget import MainControlWidget
from ..player_widget import PlayerWidget
from ..search_bar_widget import SearchBarWidget
from ..stacked_timeline_widget import StackedTimelineWidget
from ..training_thread import TrainingThread

_CLICK_THRESHOLD = 20
_DEBOUNCE_SEARCH_DELAY_MS = 100
Expand Down
8 changes: 4 additions & 4 deletions src/jabs/ui/main_window/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
from jabs.utils.process_pool_manager import ProcessPoolManager
from jabs.version import version_str

from ..central_widget import CentralWidget
from ..license_dialog import LicenseAgreementDialog
from ..dialogs import LicenseAgreementDialog
from ..dialogs.progress_dialog import create_progress_dialog
from ..player_widget import PlayerWidget
from ..progress_dialog import create_progress_dialog
from ..project_loader_thread import ProjectLoaderThread
from ..video_list_widget import VideoListDockWidget
from .central_widget import CentralWidget
from .constants import (
DEFAULT_WINDOW_HEIGHT,
DEFAULT_WINDOW_WIDTH,
Expand All @@ -26,6 +25,7 @@
)
from .menu_builder import MenuBuilder
from .menu_handlers import MenuHandlers
from .video_list_widget import VideoListDockWidget

logger = logging.getLogger(__name__)

Expand Down
16 changes: 9 additions & 7 deletions src/jabs/ui/main_window/menu_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@
from jabs.project import export_training_data
from jabs.utils import FINAL_TRAIN_SEED, check_for_update

from ..about_dialog import AboutDialog
from ..archive_behavior_dialog import ArchiveBehaviorDialog
from ..behavior_search_dialog import BehaviorSearchDialog
from ..license_dialog import LicenseAgreementDialog
from ..dialogs import (
AboutDialog,
ArchiveBehaviorDialog,
BehaviorSearchDialog,
LicenseAgreementDialog,
ProjectPruningDialog,
UpdateCheckDialog,
UserGuideDialog,
)
from ..player_widget import PlayerWidget
from ..project_pruning_dialog import ProjectPruningDialog
from ..settings_dialog import SettingsDialog
from ..stacked_timeline_widget import StackedTimelineWidget
from ..update_check_dialog import UpdateCheckDialog
from ..user_guide_dialog import UserGuideDialog
from ..util import send_file_to_recycle_bin
from .constants import SESSION_TRACKING_ENABLED_KEY, USE_NATIVE_FILE_DIALOG

Expand Down
2 changes: 1 addition & 1 deletion src/jabs/ui/player_widget/overlays/annotation_overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from PySide6 import QtCore, QtGui

from .annotation_info_dialog import AnnotationInfoDialog
from ...dialogs import AnnotationInfoDialog
from .overlay import Overlay

if TYPE_CHECKING:
Expand Down
2 changes: 1 addition & 1 deletion src/jabs/ui/search_bar_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def __init__(self, parent=None):

layout.addWidget(self.done_button)

self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_StyledBackground, True)
self.setObjectName("SearchBarWidget")
self.setStyleSheet("""
#SearchBarWidget {
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/test_training_report_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
try:
from PySide6.QtWidgets import QApplication

from jabs.ui.training_report import TrainingReportDialog
from jabs.ui.dialogs import TrainingReportDialog

SKIP_UI_TESTS = False
SKIP_REASON = None
except ImportError as e:
# Qt/PySide6 not available (likely headless environment)
SKIP_UI_TESTS = True
Expand Down