Polish tab UI styling with enhanced visual design
Document tabs (header bar): - Add rounded corners with subtle backgrounds - Highlight active tabs with accent color and bottom border - Improve hover states with smooth 200ms transitions - Enhance close button visibility and hover effects - Reduce spacing for more compact appearance - Increase tab name truncation limit to 25 chars Stack switchers (Headers/Body tabs): - Add pill-style rounded buttons (6px radius) - Style active tabs with accent colors and bold text - Add smooth crossfade transitions (150ms) - Improve spacing with 8px top/bottom margins All styling uses GNOME color tokens for consistent theming across light and dark modes.
This commit is contained in:
parent
2545cdd88d
commit
2ff4a39e04
106
src/window.py
106
src/window.py
@ -83,6 +83,9 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
# Create window actions
|
# Create window actions
|
||||||
self._create_actions()
|
self._create_actions()
|
||||||
|
|
||||||
|
# Setup custom CSS
|
||||||
|
self._setup_custom_css()
|
||||||
|
|
||||||
# Setup UI
|
# Setup UI
|
||||||
self._setup_method_dropdown()
|
self._setup_method_dropdown()
|
||||||
self._setup_request_tabs()
|
self._setup_request_tabs()
|
||||||
@ -158,6 +161,88 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
# User confirmed - close the window
|
# User confirmed - close the window
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
def _setup_custom_css(self):
|
||||||
|
"""Setup custom CSS for enhanced tab styling."""
|
||||||
|
css_provider = Gtk.CssProvider()
|
||||||
|
css_provider.load_from_data(b"""
|
||||||
|
/* Document tabs in header bar */
|
||||||
|
.tab-button {
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: alpha(@window_fg_color, 0.08);
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button:hover {
|
||||||
|
background: alpha(@window_fg_color, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button-active {
|
||||||
|
background: alpha(@accent_bg_color, 0.2);
|
||||||
|
box-shadow: inset 0 -2px 0 0 @accent_bg_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button-active:hover {
|
||||||
|
background: alpha(@accent_bg_color, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab label button */
|
||||||
|
.tab-label-btn {
|
||||||
|
padding: 4px 12px;
|
||||||
|
min-height: 28px;
|
||||||
|
border-radius: 6px 0 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button-active .tab-label-btn {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab close button */
|
||||||
|
.tab-close-btn {
|
||||||
|
padding: 4px 8px;
|
||||||
|
min-width: 24px;
|
||||||
|
min-height: 24px;
|
||||||
|
margin: 2px 4px 2px 0;
|
||||||
|
border-radius: 0 6px 6px 0;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-close-btn:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background: alpha(@window_fg_color, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button-active .tab-close-btn:hover {
|
||||||
|
background: alpha(@accent_bg_color, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stack switchers styling (Headers/Body tabs) */
|
||||||
|
stackswitcher button {
|
||||||
|
padding: 6px 16px;
|
||||||
|
min-height: 32px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
stackswitcher button:checked {
|
||||||
|
background: @accent_bg_color;
|
||||||
|
color: @accent_fg_color;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add some polish to the tab bar container */
|
||||||
|
#tab_bar_container {
|
||||||
|
margin: 0 6px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
Gtk.StyleContext.add_provider_for_display(
|
||||||
|
self.get_display(),
|
||||||
|
css_provider,
|
||||||
|
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
|
||||||
|
)
|
||||||
|
|
||||||
def _setup_sourceview_theme(self):
|
def _setup_sourceview_theme(self):
|
||||||
"""Set up GtkSourceView theme based on system color scheme."""
|
"""Set up GtkSourceView theme based on system color scheme."""
|
||||||
# Get the style manager to detect dark mode
|
# Get the style manager to detect dark mode
|
||||||
@ -355,18 +440,22 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
# Add tab buttons with close button
|
# Add tab buttons with close button
|
||||||
for tab in self.tab_manager.tabs:
|
for tab in self.tab_manager.tabs:
|
||||||
# Create a box for tab label + close button
|
# Create a box for tab label + close button
|
||||||
tab_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
tab_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||||
|
tab_box.add_css_class("tab-button")
|
||||||
|
|
||||||
|
# Add active styling if this is the current tab
|
||||||
|
if tab.id == self.current_tab_id:
|
||||||
|
tab_box.add_css_class("tab-button-active")
|
||||||
|
|
||||||
# Tab label with modified indicator
|
# Tab label with modified indicator
|
||||||
tab_label = tab.name[:20] # Truncate long names
|
tab_label = tab.name[:25] # Truncate long names
|
||||||
if tab.is_modified():
|
if tab.is_modified():
|
||||||
tab_label += " •" # Add dot for unsaved changes
|
tab_label += " •" # Add dot for unsaved changes
|
||||||
|
|
||||||
# Tab label button
|
# Tab label button
|
||||||
tab_label_btn = Gtk.Button(label=tab_label)
|
tab_label_btn = Gtk.Button(label=tab_label)
|
||||||
tab_label_btn.add_css_class("flat")
|
tab_label_btn.add_css_class("flat")
|
||||||
if tab.id == self.current_tab_id:
|
tab_label_btn.add_css_class("tab-label-btn")
|
||||||
tab_label_btn.add_css_class("suggested-action")
|
|
||||||
tab_label_btn.connect("clicked", lambda btn, tid=tab.id: self._switch_to_tab(tid))
|
tab_label_btn.connect("clicked", lambda btn, tid=tab.id: self._switch_to_tab(tid))
|
||||||
tab_box.append(tab_label_btn)
|
tab_box.append(tab_label_btn)
|
||||||
|
|
||||||
@ -375,6 +464,7 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
close_btn.set_icon_name("window-close-symbolic")
|
close_btn.set_icon_name("window-close-symbolic")
|
||||||
close_btn.add_css_class("flat")
|
close_btn.add_css_class("flat")
|
||||||
close_btn.add_css_class("circular")
|
close_btn.add_css_class("circular")
|
||||||
|
close_btn.add_css_class("tab-close-btn")
|
||||||
close_btn.set_tooltip_text("Close tab")
|
close_btn.set_tooltip_text("Close tab")
|
||||||
close_btn.connect("clicked", lambda btn, tid=tab.id: self._close_tab(tid))
|
close_btn.connect("clicked", lambda btn, tid=tab.id: self._close_tab(tid))
|
||||||
tab_box.append(close_btn)
|
tab_box.append(close_btn)
|
||||||
@ -532,11 +622,15 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
# Create stack for switching between pages
|
# Create stack for switching between pages
|
||||||
self.request_stack = Gtk.Stack()
|
self.request_stack = Gtk.Stack()
|
||||||
self.request_stack.set_vexpand(True)
|
self.request_stack.set_vexpand(True)
|
||||||
|
self.request_stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
|
||||||
|
self.request_stack.set_transition_duration(150)
|
||||||
|
|
||||||
# Create stack switcher for the tabs
|
# Create stack switcher for the tabs
|
||||||
request_switcher = Gtk.StackSwitcher()
|
request_switcher = Gtk.StackSwitcher()
|
||||||
request_switcher.set_stack(self.request_stack)
|
request_switcher.set_stack(self.request_stack)
|
||||||
request_switcher.set_halign(Gtk.Align.CENTER)
|
request_switcher.set_halign(Gtk.Align.CENTER)
|
||||||
|
request_switcher.set_margin_top(8)
|
||||||
|
request_switcher.set_margin_bottom(8)
|
||||||
|
|
||||||
# Add switcher and stack to container
|
# Add switcher and stack to container
|
||||||
self.request_tabs_container.append(request_switcher)
|
self.request_tabs_container.append(request_switcher)
|
||||||
@ -634,11 +728,15 @@ class RosterWindow(Adw.ApplicationWindow):
|
|||||||
# Create stack for switching between pages
|
# Create stack for switching between pages
|
||||||
self.response_stack = Gtk.Stack()
|
self.response_stack = Gtk.Stack()
|
||||||
self.response_stack.set_vexpand(True)
|
self.response_stack.set_vexpand(True)
|
||||||
|
self.response_stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
|
||||||
|
self.response_stack.set_transition_duration(150)
|
||||||
|
|
||||||
# Create stack switcher for the tabs
|
# Create stack switcher for the tabs
|
||||||
response_switcher = Gtk.StackSwitcher()
|
response_switcher = Gtk.StackSwitcher()
|
||||||
response_switcher.set_stack(self.response_stack)
|
response_switcher.set_stack(self.response_stack)
|
||||||
response_switcher.set_halign(Gtk.Align.CENTER)
|
response_switcher.set_halign(Gtk.Align.CENTER)
|
||||||
|
response_switcher.set_margin_top(8)
|
||||||
|
response_switcher.set_margin_bottom(8)
|
||||||
|
|
||||||
# Add switcher and stack to container
|
# Add switcher and stack to container
|
||||||
self.response_tabs_container.append(response_switcher)
|
self.response_tabs_container.append(response_switcher)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user