UI System - edgeof8/tIRC GitHub Wiki
tIRC features a responsive and modular terminal-based user interface (TUI) built using the Python curses library. This page provides an overview of its architecture, key components, and the recent UI overhaul.
For details on UI-related commands, see the Command System documentation. For information on how views are managed, refer to the ClientViewManager section in Core Components.
The UI system is designed to:
- Provide a clean, navigable interface for IRC interaction.
- Support features like split-screen views with independent scrolling.
- Adapt to different terminal sizes.
- Offer color-coded messages and status indicators.
- Handle user input efficiently in an asynchronous environment.
The recent UI overhaul focused on transforming tIRC's UI into a modern, consistent, and highly readable experience, significantly enhancing visual aesthetics and functional clarity.
- Visual Appeal & Eye Strain Reduction: The UI prioritizes visual comfort with a "much nicer" appearance.
-
Main Backgrounds: Dark but distinctly colored, specifically using dark purple/magenta tones (
#2C003E), avoiding pure black. This applies to message panels, sidebar, and general window areas. -
Status Bar: Visually distinct and "stark" through high contrast, avoiding pure black. It features a minimalist, high-contrast look with a light grey or white foreground (
#E0E0E0) on a dark cyan/teal background (#004040). -
Input Bar: The sole UI element permitted to use pure black (
#000000) as a background. -
Consistent Highlighting: A robust system for consistent color-highlighting of
#channels,@nicks, and+modesacross all UI windows (chat, user lists, topic bars). This extends to standard event members (server names, timestamps, message types). - 256-Color Support: tIRC now implements full 256-color support using hex codes if the terminal supports it, falling back to a carefully mapped 8-color palette if not.
This palette defines the hex codes and their semantic usage, managed centrally in tirc_core/client/ui_colors.py.
Base Colors:
-
Main Background (Dark Purple/Magenta):
#2C003E- Semantic Usage: Default background for message panels, sidebar, and general window areas.
-
Input Bar Background (Pure Black):
#000000- Semantic Usage: Exclusive background for the input line.
-
Status Bar Background (Dark Cyan/Teal):
#004040- Semantic Usage: Background for the status bar.
Highlighting System Colors:
-
Channels (
#channels):#00FF00(Bright Green)- Semantic Usage: Identifies IRC channels.
-
Nicks (
@nicks):#00FFFF(Cyan)- Semantic Usage: Identifies user nicknames.
-
Modes (
+modes):#FFFF00(Bright Yellow)- Semantic Usage: Identifies user modes (e.g., op, voice).
-
My Messages:
#FFA500(Orange)- Semantic Usage: Messages sent by the current user.
-
Other Messages:
#FFFFFF(White)- Semantic Usage: Messages from other users.
-
System Messages:
#C0C0C0(Silver/Light Gray)- Semantic Usage: General system information, joins/parts, server notices.
-
Error Messages:
#FF0000(Red)- Semantic Usage: Critical errors, connection failures.
-
Highlight (Mentions):
#FFD700(Gold)- Semantic Usage: When your nick is mentioned.
-
Timestamps:
#808080(Gray)- Semantic Usage: Timestamp prefixes for messages.
-
Server Names:
#ADD8E6(Light Blue)- Semantic Usage: Server names in status messages or events.
-
Active Window (Sidebar):
#FFFFFF(White foreground) on#004040(Dark Cyan/Teal background)- Semantic Usage: Highlights the currently active window in the sidebar.
-
Unread Window (Sidebar):
#FFD700(Gold foreground) on#2C003E(Dark Purple/Magenta background)- Semantic Usage: Indicates windows with unread messages.
-
Status Bar Foreground:
#E0E0E0(Light Grey)- Semantic Usage: Text on the status bar.
graph TD
A[Terminal Window] --> B(Message Panel)
A --> C(Sidebar)
A --> D(Status Bar)
A --> E(Input Bar)
subgraph Message Panel
B1[Chat Messages]
B2[Event Messages]
end
subgraph Sidebar
C1[Windows List]
C2[User List]
end
style B fill:#2C003E,stroke:#333,stroke-width:2px
style C fill:#2C003E,stroke:#333,stroke-width:2px
style D fill:#004040,stroke:#333,stroke-width:2px
style E fill:#000000,stroke:#333,stroke-width:2px
Textual Description:
-
Message Panel: Occupies the main left/center area. Background:
#2C003E(Dark Purple/Magenta). Text colors will vary based on message type and highlighting rules. -
Sidebar: Located on the right. Background:
#2C003E(Dark Purple/Magenta). Contains the "Windows" list and "Users" list. -
Status Bar: A single line at the bottom, above the input bar. Background:
#004040(Dark Cyan/Teal). Foreground:#E0E0E0(Light Grey). -
Input Bar: The very bottom line. Background:
#000000(Pure Black). Foreground:#FFFFFF(White).
graph TD
MP[Message Panel] --> M1("Timestamp Nick: Message text #channel @nick +mode")
MP --> M2("System message (e.g., Join/Part)")
MP --> M3("My message")
MP --> M4("Highlighted message (mention)")
style M1 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFFFFF
style M2 fill:#2C003E,stroke:#333,stroke-width:1px,color:#C0C0C0
style M3 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFA500
style M4 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFD700
Textual Description:
-
General Message:
[Timestamp] <Nick>: Message text- Timestamp:
#808080(Gray) - Nick:
#00FFFF(Cyan) - Message Text:
#FFFFFF(White) -
#channelwithin message:#00FF00(Bright Green) -
@nickwithin message:#00FFFF(Cyan) -
+modewithin message:#FFFF00(Bright Yellow)
- Timestamp:
-
My Message:
[Timestamp] <MyNick>: My message text- MyNick:
#FFA500(Orange) - Message Text:
#FFA500(Orange)
- MyNick:
-
System Message (Join/Part):
[Timestamp] -- Nick has joined #channel --- All text:
#C0C0C0(Silver/Light Gray)
- All text:
-
Highlighted Message (Mention):
[Timestamp] <OtherNick>: Hey MyNick, check this out!-
MyNick(when mentioned):#FFD700(Gold) - Rest of message:
#FFFFFF(White)
-
graph TD
SB[Sidebar] --> W1("Windows:")
SB --> W2("> *Status (1)")
SB --> W3(" #channel_active")
SB --> W4("* #channel_unread (5)")
SB --> W5(" #channel_read")
SB --> U1("Users in #channel_active (X):")
SB --> U2(" @OpNick")
SB --> U3(" +VoiceNick")
SB --> U4(" NormalNick")
style W1 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFFFFF
style W2 fill:#004040,stroke:#333,stroke-width:1px,color:#FFFFFF
style W3 fill:#2C003E,stroke:#333,stroke-width:1px,color:#00FF00
style W4 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFD700
style W5 fill:#2C003E,stroke:#333,stroke-width:1px,color:#00FF00
style U1 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFFFFF
style U2 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFFF00
style U3 fill:#2C003E,stroke:#333,stroke-width:1px,color:#FFFF00
style U4 fill:#2C003E,stroke:#333,stroke-width:1px,color:#00FFFF
Textual Description:
-
Windows Header: "Windows:" - Foreground:
#FFFFFF(White), Background:#2C003E(Dark Purple/Magenta). -
Active Window:
> *Status (1)or> #channel_active- Prefix
>:#FFFFFF(White) on#004040(Dark Cyan/Teal) - Text (e.g.,
Status,channel_active):#FFFFFF(White) on#004040(Dark Cyan/Teal) -
#for channel:#00FF00(Bright Green) on#004040(Dark Cyan/Teal)
- Prefix
-
Unread Window:
* #channel_unread (5)- Prefix
*:#FFD700(Gold) on#2C003E(Dark Purple/Magenta) - Text (e.g.,
channel_unread):#FFD700(Gold) on#2C003E(Dark Purple/Magenta) -
#for channel:#00FF00(Bright Green) on#2C003E(Dark Purple/Magenta)
- Prefix
-
Read Window:
#channel_read- Prefix
:#2C003E(Dark Purple/Magenta) - Text (e.g.,
channel_read):#00FF00(Bright Green) on#2C003E(Dark Purple/Magenta)
- Prefix
-
Users Header: "Users in #channel (X):" - Foreground:
#FFFFFF(White), Background:#2C003E(Dark Purple/Magenta). -
User List Items:
-
@OpNick:@in#FFFF00(Bright Yellow),OpNickin#00FFFF(Cyan). Background:#2C003E(Dark Purple/Magenta). -
+VoiceNick:+in#FFFF00(Bright Yellow),VoiceNickin#00FFFF(Cyan). Background:#2C003E(Dark Purple/Magenta). -
NormalNick:#00FFFF(Cyan). Background:#2C003E(Dark Purple/Magenta).
-
This section outlines the necessary modifications and estimated effort.
-
CursesManager Refactor for 256-colors:
- Modify
tirc_core/client/curses_manager.pyto supportcurses.init_colorandcurses.can_change_color. - Introduce a mechanism to check
curses.COLORSandcurses.has_colors()to determine 256-color support. - If 256-color is supported, use
curses.init_colorto define custom RGB values from hex codes. - Map the hex codes from the new color palette to curses color numbers (0-255).
- Update
_init_color_pairto use these new color numbers. - Add a fallback mechanism to map hex codes to the closest 8-color curses palette if 256-color is not supported. This will involve a simple mapping function.
- Modify
-
Centralized Color Definitions:
- Create a new module (
tirc_core/client/ui_colors.py) to store the hex codes and their semantic names. This replaces theDEFAULT_COLOR_constants intirc_core/config_defs.pyfor UI purposes. - Update
CursesManagerto import colors from this new module. - Remove
DEFAULT_COLOR_constants related to UI fromtirc_core/config_defs.py.
- Create a new module (
-
Apply New Backgrounds:
- Modify
tirc_core/client/curses_manager.pyandtirc_core/client/window_layout_manager.pyto use the new background color pairs (message_panel_bg,list_panel_bg,status_bar,input) as defined in the palette. - Ensure
input_winspecifically uses pure black background.
- Modify
-
Message Panel Highlighting (
tirc_core/client/message_panel_renderer.py):- Implement a text parsing function that identifies
#channels,@nicks,+modes, timestamps, and server names within message strings. - This function should return a list of
(text_segment, color_pair_id)tuples for each segment of the message. - Integrate this parsing logic into
_draw_messages_in_windowto apply the correct color pairs for each segment. - Ensure "My Messages" and "Highlight (Mentions)" override other highlighting for the entire line or specific words.
- Implement a text parsing function that identifies
-
Sidebar Highlighting (
tirc_core/client/sidebar_panel_renderer.py):-
Context List:
- Update
_draw_sidebar_context_listto usesidebar_activeandsidebar_unreadcolor pairs as defined. - Ensure
#channelnames within the context list are highlighted with thechannelcolor, while respecting the active/unread background. This will require careful handling ofcurses.init_pairfor temporary foreground/background combinations.
- Update
-
User List:
- Update
_draw_sidebar_user_list_items_and_indicatorsto applymodecolor for prefixes (@,+) andnickcolor for nicknames. - Ensure the background for user list items remains the
list_panel_bgcolor.
- Update
-
Context List:
-
Status Bar Rendering (
tirc_core/client/status_bar_renderer.py):- Ensure the status bar uses the
status_barcolor pair (light grey foreground on dark cyan/teal background). - If any dynamic elements like server names or nicks appear in the status bar, ensure they use their respective highlighting colors while maintaining the status bar's background.
- Ensure the status bar uses the
-
Refactor
tirc_core/client/directory:- Review all renderer classes (
MessagePanelRenderer,SidebarPanelRenderer,StatusBarRenderer,InputLineRenderer) to ensure they consistently use thecolorsdictionary passed fromUIManagerandCursesManager. - Ensure
SafeCursesUtilsis used consistently for all curses operations. - Consider if any new helper functions are needed in
SafeCursesUtilsfor complex text rendering with multiple colors on a single line (e.g., a function that takes a list of(text, color_pair_id)tuples).
- Review all renderer classes (
-
Integration with
tirc_core/commands/ui/:- The UI commands (e.g.,
window_navigation_commands.py,split_screen_commands.py) primarily interact withClientViewManagerandUIManagerto change state (active window, split mode). - No direct color or rendering logic changes are expected here, but ensure that state changes correctly trigger
UIManager.refresh_all_windows()to apply the new UI.
- The UI commands (e.g.,
-
Documentation Update (
tIRC.wiki/UI-System.md):- Update the "Core UI Components" section to reflect the new
ui_colors.pymodule. - Add a new section "UI Color Palette & Highlighting System" detailing the hex codes, semantic usage, and the 256-color/8-color fallback details.
- Describe the 256-color support implementation and fallback.
- Add a section on "UI Redesign Principles" outlining the dark backgrounds, stark status bar, and pure black input bar.
- Include the Mermaid diagrams and textual descriptions from this plan.
- Update any other relevant sections to reflect the UI overhaul.
- Update the "Core UI Components" section to reflect the new
-
Cross-Platform Consistency:
- The
curseslibrary itself handles much of the terminal compatibility. The 256-color implementation with an 8-color fallback directly addresses this. - Thorough testing on different terminal emulators (e.g.,
xterm,gnome-terminal,Windows Terminal,PuTTY) will be crucial during implementation to ensure consistent appearance. - Document any known limitations or variations across platforms in
tIRC.wiki/UI-System.md.
- The
-
Performance Implications & Maintainability:
-
Performance:
- The current
curses_utils.pyalready includes safe wrappers to prevent errors. - Batching updates with
noutrefreshanddoupdate(as seen inUIManager.refresh_all_windows) is good practice and should be maintained. - Minimize redundant
erase()andbkgd()calls within renderers;WindowLayoutManagershould set the background once during window creation. (Noted and addressed in my analysis of the current code). - Efficient string slicing and rendering in
MessagePanelRendererandSidebarPanelRendererwill be key. Avoid re-calculating or re-parsing text unnecessarily.
- The current
-
Maintainability:
- Centralizing color definitions in
ui_colors.pyimproves maintainability. - The modular renderer approach is already good; ensure new highlighting logic is encapsulated within these renderers.
- Clear comments and docstrings for new functions and modifications.
- Centralizing color definitions in
-
Performance:
- Phase 1: Color System Modernization: 3-5 days
- Phase 2: Consistent Highlighting System: 5-7 days
- Phase 3: Architectural & Documentation Strategy: 2-3 days
- Total Estimated Effort: 10-15 days (excluding testing and refinement)