| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- """
- Styles Module
- Centralized stylesheet definitions for the application.
- """
- from utils.config import UI_COLORS
- # ==================== COLOR CONSTANTS ====================
- # Export COLORS dictionary for tab modules
- COLORS = {
- # Primary colors
- 'primary': '#3498db',
- 'primary_dark': '#2c3e50',
- 'primary_light': '#34495e',
-
- # Status colors
- 'success': '#27ae60',
- 'warning': '#f39c12',
- 'error': '#e74c3c',
- 'info': '#3498db',
-
- # Background colors
- 'bg_light': '#f8f9fa',
- 'bg_white': '#ffffff',
- 'bg_dark': '#2c3e50',
- 'card_bg': '#ffffff',
-
- # Text colors
- 'text_primary': '#2c3e50',
- 'text_secondary': '#7f8c8d',
- 'text_light': '#bdc3c7',
-
- # Border colors
- 'border': '#ddd',
- 'border_light': '#ecf0f1',
-
- # Phase 8: Classification colors
- 'ripeness_unripe': '#95a5a6',
- 'ripeness_midripe': '#f39c12',
- 'ripeness_ripe': '#27ae60',
- 'ripeness_overripe': '#e74c3c',
-
- # Phase 8: Panel header colors
- 'panel_rgb': '#3498db',
- 'panel_multispectral': '#8e44ad',
- 'panel_audio': '#16a085',
- 'panel_results': '#27ae60',
- 'panel_control': '#34495e',
-
- # Phase 8: Status indicators
- 'status_online': '#27ae60',
- 'status_offline': '#e74c3c',
- 'status_processing': '#f39c12',
- }
- # Export STYLES dictionary for common button styles
- STYLES = {
- 'button_primary': f"""
- QPushButton {{
- background-color: {COLORS['primary']};
- border: 2px solid {COLORS['primary']};
- border-radius: 8px;
- color: white;
- font-weight: bold;
- font-size: 14px;
- padding: 10px 20px;
- }}
- QPushButton:hover {{
- background-color: #2980b9;
- }}
- QPushButton:pressed {{
- background-color: #2471a3;
- }}
- QPushButton:disabled {{
- background-color: {COLORS['text_secondary']};
- border-color: {COLORS['text_secondary']};
- }}
- """,
- 'button_success': f"""
- QPushButton {{
- background-color: {COLORS['success']};
- border: 2px solid {COLORS['success']};
- border-radius: 8px;
- color: white;
- font-weight: bold;
- font-size: 14px;
- padding: 10px 20px;
- }}
- QPushButton:hover {{
- background-color: #229954;
- }}
- QPushButton:pressed {{
- background-color: #1e8449;
- }}
- """,
- }
- # ==================== MAIN WINDOW STYLES ====================
- MAIN_WINDOW_STYLE = f"""
- QMainWindow {{
- background-color: {UI_COLORS['bg_light']};
- }}
- """
- # ==================== GROUP BOX STYLES ====================
- GROUP_BOX_STYLE = f"""
- QGroupBox {{
- font-weight: bold;
- font-size: 16px;
- border: 2px solid #ddd;
- border-radius: 5px;
- margin-top: 10px;
- padding-top: 10px;
- background-color: {UI_COLORS['bg_white']};
- }}
- QGroupBox::title {{
- subcontrol-origin: margin;
- left: 10px;
- padding: 0 10px 0 10px;
- color: {UI_COLORS['text_dark']};
- background-color: {UI_COLORS['bg_panel']};
- }}
- """
- # ==================== BUTTON STYLES ====================
- def get_button_style(
- bg_color: str,
- hover_color: str,
- pressed_color: str = None,
- border_color: str = None,
- text_color: str = "white"
- ) -> str:
- """
- Generate a button stylesheet with the given colors.
-
- Args:
- bg_color: Background color
- hover_color: Hover state color
- pressed_color: Pressed state color (defaults to hover_color)
- border_color: Border color (defaults to hover_color)
- text_color: Text color (defaults to white)
-
- Returns:
- str: Complete button stylesheet
- """
- if pressed_color is None:
- pressed_color = hover_color
- if border_color is None:
- border_color = hover_color
-
- return f"""
- QPushButton {{
- background-color: {bg_color};
- border: 2px solid {border_color};
- border-radius: 8px;
- color: {text_color};
- font-weight: bold;
- font-size: 16px;
- padding: 15px;
- }}
- QPushButton:hover {{
- background-color: {hover_color};
- }}
- QPushButton:pressed {{
- background-color: {pressed_color};
- }}
- """
- RIPENESS_BUTTON_STYLE = get_button_style(
- UI_COLORS['btn_green'],
- UI_COLORS['btn_green_hover'],
- "#1e8449"
- )
- QUALITY_BUTTON_STYLE = get_button_style(
- UI_COLORS['btn_blue'],
- UI_COLORS['btn_blue_hover'],
- "#2471a3"
- )
- CALIBRATION_BUTTON_STYLE = get_button_style(
- UI_COLORS['btn_orange'],
- UI_COLORS['btn_orange_hover'],
- "#d68910"
- )
- BATCH_BUTTON_STYLE = get_button_style(
- UI_COLORS['btn_purple'],
- UI_COLORS['btn_purple_hover'],
- "#7d3c98"
- )
- LOCULE_BUTTON_STYLE = get_button_style(
- "#16a085", # Teal
- "#138d75", # Darker teal
- "#117864" # Even darker teal
- )
- EMERGENCY_BUTTON_STYLE = f"""
- QPushButton {{
- background-color: {UI_COLORS['btn_red']};
- border: 2px solid {UI_COLORS['btn_red_hover']};
- border-radius: 15px;
- color: white;
- font-weight: bold;
- font-size: 14px;
- }}
- QPushButton:hover {{
- background-color: {UI_COLORS['btn_red_hover']};
- }}
- """
- STANDARD_BUTTON_STYLE = f"""
- QPushButton {{
- background-color: {UI_COLORS['primary_light']};
- border: 1px solid {UI_COLORS['primary_dark']};
- border-radius: 4px;
- color: white;
- padding: 10px;
- font-size: 16px;
- }}
- QPushButton:hover {{
- background-color: {UI_COLORS['primary_dark']};
- }}
- """
- # ==================== TABLE STYLES ====================
- TABLE_STYLE = f"""
- QTableWidget {{
- gridline-color: #ddd;
- background-color: {UI_COLORS['bg_white']};
- alternate-background-color: {UI_COLORS['bg_light']};
- font-size: 16px;
- }}
- QHeaderView::section {{
- background-color: {UI_COLORS['bg_light']};
- padding: 8px;
- border: 1px solid #ddd;
- font-weight: bold;
- font-size: 16px;
- }}
- """
- # ==================== TAB WIDGET STYLES ====================
- TAB_WIDGET_STYLE = f"""
- QTabWidget::pane {{
- border: 1px solid {UI_COLORS['primary_light']};
- background-color: {UI_COLORS['bg_white']};
- }}
- QTabBar::tab {{
- background-color: {UI_COLORS['primary_light']};
- color: {UI_COLORS['bg_panel']};
- padding: 12px 16px;
- margin-right: 2px;
- font-size: 14px;
- font-weight: bold;
- min-width: 120px;
- max-width: 180px;
- }}
- QTabBar::tab:selected {{
- background-color: {UI_COLORS['accent_blue']};
- color: white;
- }}
- QTabBar::tab:hover {{
- background-color: {UI_COLORS['accent_blue']};
- opacity: 0.8;
- }}
- QTabBar::left-button, QTabBar::right-button {{
- background-color: {UI_COLORS['primary_light']};
- border: none;
- }}
- """
- # ==================== HEADER STYLES ====================
- HEADER_STYLE = f"""
- QFrame {{
- background-color: {UI_COLORS['primary_dark']};
- }}
- QLabel {{
- color: white;
- }}
- """
- HEADER_ICON_BUTTON_STYLE = f"""
- QPushButton {{
- background-color: transparent;
- border: 2px solid transparent;
- border-radius: 8px;
- color: white;
- font-size: 20px;
- padding: 8px 12px;
- min-width: 45px;
- min-height: 45px;
- }}
- QPushButton:hover {{
- background-color: rgba(255, 255, 255, 0.1);
- border: 2px solid rgba(255, 255, 255, 0.3);
- }}
- QPushButton:pressed {{
- background-color: rgba(255, 255, 255, 0.2);
- }}
- """
- # ==================== STATUS BAR STYLES ====================
- STATUS_BAR_STYLE = f"""
- QFrame {{
- background-color: {UI_COLORS['primary_light']};
- }}
- QLabel {{
- color: {UI_COLORS['bg_panel']};
- font-size: 16px;
- }}
- """
- # ==================== LABEL STYLES ====================
- def get_label_style(
- color: str = None,
- font_size: int = 16,
- font_weight: str = "normal",
- background: str = None
- ) -> str:
- """
- Generate a label stylesheet.
-
- Args:
- color: Text color
- font_size: Font size in pixels
- font_weight: Font weight (normal, bold)
- background: Background color
-
- Returns:
- str: Label stylesheet
- """
- styles = []
-
- if color:
- styles.append(f"color: {color};")
- if font_size:
- styles.append(f"font-size: {font_size}px;")
- if font_weight:
- styles.append(f"font-weight: {font_weight};")
- if background:
- styles.append(f"background-color: {background};")
-
- return " ".join(styles)
- HEADER_LABEL_STYLE = get_label_style(
- color=UI_COLORS['text_dark'],
- font_size=16,
- font_weight="bold"
- )
- INFO_LABEL_STYLE = get_label_style(
- color=UI_COLORS['text_medium'],
- font_size=16
- )
- STATUS_LABEL_STYLE = get_label_style(
- color=UI_COLORS['text_dark'],
- font_size=16
- )
- # ==================== FEED/DISPLAY STYLES ====================
- def get_feed_style(bg_color: str, border_color: str) -> str:
- """
- Generate a camera feed display stylesheet.
-
- Args:
- bg_color: Background color
- border_color: Border color
-
- Returns:
- str: Feed display stylesheet
- """
- return f"""
- background-color: {bg_color};
- border: 1px solid {border_color};
- color: white;
- font-size: 16px;
- """
- RGB_FEED_STYLE = get_feed_style(UI_COLORS['primary_dark'], UI_COLORS['primary_light'])
- MS_FEED_STYLE = get_feed_style(UI_COLORS['btn_purple'], "#9b59b6")
- THERMAL_FEED_STYLE = get_feed_style(UI_COLORS['text_medium'], "#95a5a6")
- AUDIO_FEED_STYLE = get_feed_style("#16a085", "#1abc9c")
- # ==================== APPLICATION STYLE ====================
- APPLICATION_STYLE = """
- QApplication {
- font-family: Arial, sans-serif;
- }
- """
- # ==================== LOADING OVERLAY STYLE ====================
- LOADING_STYLE = """
- background-color: rgba(255, 255, 255, 0%);
- """
- # ==================== UTILITY FUNCTIONS ====================
- def get_status_indicator_style(status: str) -> str:
- """
- Get the stylesheet for a status indicator.
-
- Args:
- status: Status type ('online', 'offline', 'updating')
-
- Returns:
- str: Stylesheet for the status indicator
- """
- status_colors = {
- "online": UI_COLORS['online'],
- "offline": UI_COLORS['offline'],
- "updating": UI_COLORS['updating'],
- }
-
- color = status_colors.get(status, UI_COLORS['text_medium'])
-
- return f"background-color: {color}; border-radius: 6px;"
- def get_grade_color(grade: str) -> str:
- """
- Get the color for a quality grade.
-
- Args:
- grade: Grade letter ('A', 'B', 'C', etc.)
-
- Returns:
- str: Color hex code
- """
- # Handle None or empty grades
- if not grade:
- return UI_COLORS['text_dark']
-
- grade_colors = {
- "A": UI_COLORS['grade_a'],
- "B": UI_COLORS['grade_b'],
- "C": UI_COLORS['grade_c'],
- }
-
- return grade_colors.get(str(grade).upper(), UI_COLORS['text_dark'])
- def get_ripeness_color(ripeness: str) -> str:
- """
- Get the color for a ripeness classification.
-
- Args:
- ripeness: Ripeness type ('Ripe', 'Overripe', 'Unripe')
-
- Returns:
- str: Color hex code
- """
- ripeness_colors = {
- "Ripe": UI_COLORS['online'],
- "Overripe": UI_COLORS['updating'],
- "Unripe": UI_COLORS['text_medium'],
- }
-
- return ripeness_colors.get(ripeness, UI_COLORS['text_dark'])
|