Deep-Live-Cam
Deep-Live-Cam copied to clipboard
feat: Overhaul UI with Theme Toggle, Tooltips, and Layout Adjustments
This pull request introduces a major user interface overhaul with the following enhancements:
Theme Management: Added a persistent theme toggle (Light/Dark) with professional icons, saving the user's preference across sessions.
Improved Tooltips: Implemented a robust, centralized ToolTipManager to fix flickering bugs and improve the stability and
positioning of informational tooltips.
Info Buttons: Added clear '?' info buttons with detailed tooltips for all major settings, significantly improving user
experience and clarity.
UI Layout Refinements:
- Refactored the UI layout for better organization and component placement.
- Increased the main window width to 800px for better spacing.
- Adjusted the placement of help icons to ensure consistent positioning.
Summary by Sourcery
Overhaul the main UI to add persistent theme toggling, centralized tooltip handling, and clearer setting explanations while widening the main window layout.
New Features:
- Introduce a global theme toggle button with sun/moon styling that remembers the user’s light or dark mode preference across sessions.
- Add reusable helper for creating '?' info buttons with contextual tooltips for key settings throughout the UI.
Bug Fixes:
- Replace per-widget tooltip windows with a singleton tooltip manager to eliminate flickering and stuck tooltips, including better cleanup on window events.
Enhancements:
- Refine layout of switches and controls, including resizing and repositioning elements to fit an increased 800px-wide window.
- Improve tooltip placement logic to keep tooltips within the main window bounds during interaction and resizing.
Reviewer's Guide
Major UI overhaul in modules/ui.py introducing a centralized tooltip manager, a persistent light/dark theme toggle with icon button, expanded window width, and contextual info “?” buttons with tooltips for all major switches, along with layout adjustments for better spacing and stability.
Sequence diagram for centralized tooltip show and hide behavior
sequenceDiagram
actor User as "User"
participant InfoButton as "'?' info button"
participant ToolTip as "ToolTip controller"
participant ToolTipManager as "ToolTipManager singleton"
participant TooltipWindow as "Tooltip CTkToplevel"
User->>InfoButton: "Move mouse over button (<Enter>)"
InfoButton->>ToolTip: "<Enter> event callback"
ToolTip->>ToolTipManager: "schedule_show(widget, text)"
ToolTipManager->>ToolTipManager: "cancel_timers()"
ToolTipManager->>ToolTipManager: "start 300ms delay via widget.after()"
Note over ToolTipManager,TooltipWindow: "After 300ms, if still hovered, tooltip is shown"
ToolTipManager->>ToolTipManager: "_show(widget, text)"
ToolTipManager->>TooltipWindow: "_get_tip_window(parent) (create or reuse)"
TooltipWindow-->>ToolTipManager: "returns existing or new window"
ToolTipManager->>TooltipWindow: "configure label text and geometry"
ToolTipManager->>TooltipWindow: "deiconify() (show tooltip)"
ToolTipManager->>ToolTipManager: "start 3000ms hide timer via after()"
User->>InfoButton: "Move mouse away (<Leave>) or click"
InfoButton->>ToolTip: "<Leave> or <ButtonPress> event callback"
ToolTip->>ToolTipManager: "hide()"
ToolTipManager->>ToolTipManager: "cancel_timers()"
ToolTipManager->>TooltipWindow: "withdraw() (hide tooltip)"
Sequence diagram for theme toggle and preference persistence
sequenceDiagram
actor User as "User"
participant ThemeButton as "Theme toggle button"
participant ThemeUtils as "Theme utilities"
participant CTk as "CustomTkinter (ctk)"
participant File as "theme_preference.json"
rect rgb(230,230,250)
CTk->>ThemeUtils: "load_theme_preference() on startup"
ThemeUtils->>File: "read theme_preference.json"
File-->>ThemeUtils: "saved theme or FileNotFoundError"
ThemeUtils-->>CTk: "return saved theme or 'system'"
CTk->>CTk: "set_appearance_mode(saved_theme)"
end
User->>ThemeButton: "Click to toggle theme"
ThemeButton->>ThemeUtils: "toggle_theme()"
ThemeUtils->>CTk: "get_appearance_mode()"
CTk-->>ThemeUtils: "current mode ('Dark' or 'Light')"
ThemeUtils->>CTk: "set_appearance_mode('light' or 'dark')"
ThemeUtils->>ThemeUtils: "save_theme_preference()"
ThemeUtils->>File: "write current theme to theme_preference.json"
ThemeUtils->>ThemeButton: "update_theme_button(theme_button)"
ThemeButton-->>User: "Updated icon and color indicating new theme"
Updated class diagram for tooltip management and theme utilities
classDiagram
class ToolTipManager {
- _tip_window
- _label
- _show_timer
- _hide_timer
+ _get_tip_window()
+ schedule_show(widget, text)
+ hide()
+ cancel_timers()
}
class ToolTip {
- widget
- text
+ ToolTip(widget, text)
+ on_enter(event)
+ on_leave(event)
}
class ThemeUtilities {
+ get_theme_icon_char(mode)
+ get_theme_icon_color(mode)
+ update_theme_button(theme_button)
+ toggle_theme()
+ save_theme_preference()
+ load_theme_preference()
}
class UIGlobals {
- ROOT_HEIGHT = 750
- ROOT_WIDTH = 800
- ROOT
- theme_button
}
ToolTip ..> ToolTipManager : uses for tooltip show/hide
ToolTipManager ..> UIGlobals : reads ROOT for positioning
ThemeUtilities ..> UIGlobals : updates theme_button
ThemeUtilities ..> UIGlobals : uses global theme state
Flow diagram for tooltip lifecycle and window interactions
flowchart TD
A["User hovers over '?' info button"] --> B["ToolTip.on_enter() is called"]
B --> C["ToolTipManager.schedule_show(widget, text)"]
C --> D["ToolTipManager.cancel_timers()"]
D --> E["Start 300ms show timer via widget.after()"]
E --> F{"Is cursor still over widget when timer fires?"}
F -- "No" --> G["Do nothing (tooltip remains hidden)"]
F -- "Yes" --> H["ToolTipManager._show(widget, text)"]
H --> I["Get or create shared tooltip window (CTkToplevel)"]
I --> J["Update label text and compute position within main window"]
J --> K["Set tooltip geometry and deiconify() to show"]
K --> L["Start 3000ms auto-hide timer"]
L --> M["Auto-hide timer fires"]
M --> N["ToolTipManager.hide(): cancel timers and withdraw()"]
K --> O["Window resize or focus events"]
O --> P["close_all_tooltips() -> ToolTipManager.hide()"]
K --> Q["User moves mouse away or clicks button"]
Q --> R["ToolTip.on_leave() calls ToolTipManager.hide()"]
R --> N
File-Level Changes
| Change | Details | Files |
|---|---|---|
| Introduce centralized ToolTipManager and refactor tooltip handling to fix flickering and improve positioning. |
|
modules/ui.py |
| Add reusable '?' info button component and wire it up for major settings. |
|
modules/ui.py |
| Implement persistent theme toggle with professional icons and integrate theme preference loading/saving. |
|
modules/ui.py |
| Adjust main window dimensions and layout constants to accommodate the new UI elements. |
|
modules/ui.py |
Tips and commands
Interacting with Sourcery
- Trigger a new review: Comment
@sourcery-ai reviewon the pull request. - Continue discussions: Reply directly to Sourcery's review comments.
- Generate a GitHub issue from a review comment: Ask Sourcery to create an
issue from a review comment by replying to it. You can also reply to a
review comment with
@sourcery-ai issueto create an issue from it. - Generate a pull request title: Write
@sourcery-aianywhere in the pull request title to generate a title at any time. You can also comment@sourcery-ai titleon the pull request to (re-)generate the title at any time. - Generate a pull request summary: Write
@sourcery-ai summaryanywhere in the pull request body to generate a PR summary at any time exactly where you want it. You can also comment@sourcery-ai summaryon the pull request to (re-)generate the summary at any time. - Generate reviewer's guide: Comment
@sourcery-ai guideon the pull request to (re-)generate the reviewer's guide at any time. - Resolve all Sourcery comments: Comment
@sourcery-ai resolveon the pull request to resolve all Sourcery comments. Useful if you've already addressed all the comments and don't want to see them anymore. - Dismiss all Sourcery reviews: Comment
@sourcery-ai dismisson the pull request to dismiss all existing Sourcery reviews. Especially useful if you want to start fresh with a new review - don't forget to comment@sourcery-ai reviewto trigger a new review!
Customizing Your Experience
Access your dashboard to:
- Enable or disable review features such as the Sourcery-generated pull request summary, the reviewer's guide, and others.
- Change the review language.
- Add, remove or edit custom review instructions.
- Adjust other review settings.
Getting Help
- Contact our support team for questions or feedback.
- Visit our documentation for detailed guides and information.
- Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.