Skip to content
Merged
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
10 changes: 6 additions & 4 deletions Sources/WeiBei/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1662,7 +1662,7 @@ private struct UnifiedTopBarView: View {
// Light/dark quick toggle — keeps the active style pair, flips the
// preference. Command palette stays reachable on ⌘K.
topIconButton(
store.appearanceMode.isDark ? "sun.max" : "moon.stars",
store.appearanceMode.isDark ? "sun.max" : "moon",
help: store.ui("切换深浅外观", "Toggle Light / Dark"),
actionID: "appearance"
) {
Expand All @@ -1678,6 +1678,7 @@ private struct UnifiedTopBarView: View {
}

}
.background { WeiBeiToolbarGroupBackground() }
}

private var customTopBar: some View {
Expand Down Expand Up @@ -1818,20 +1819,21 @@ private struct UnifiedTopBarView: View {
.transition(.opacity.combined(with: .scale(scale: 0.94)))
}
}
.background { WeiBeiToolbarGroupBackground() }
}

@ViewBuilder
private var navigationButtons: some View {
HStack(spacing: 0) {
topIconButton("arrow.left", help: store.ui("后退", "Back"), actionID: "back") {
topIconButton("chevron.left", help: store.ui("后退", "Back"), actionID: "back") {
withAnimation(WeiBeiMotion.layout) {
store.navigateBackInWorkspace()
}
}
.weiBeiKeyboardShortcut(store.executableChord(for: .navigateBack))
.disabled(!store.canNavigateBack)

topIconButton("arrow.right", help: store.ui("前进", "Forward"), actionID: "forward") {
topIconButton("chevron.right", help: store.ui("前进", "Forward"), actionID: "forward") {
withAnimation(WeiBeiMotion.layout) {
store.navigateForwardInWorkspace()
}
Expand All @@ -1852,7 +1854,7 @@ private struct UnifiedTopBarView: View {
),
WeiBeiSegmentedControl.Segment(
id: "agent",
systemImage: "bubble.left.and.text.bubble.right",
systemImage: "text.bubble",
help: agentPaneToggleHelp,
isSelected: store.isPaneToggleActive(.agent),
action: store.toggleAgent
Expand Down
40 changes: 34 additions & 6 deletions Sources/WeiBei/Views/WeiBeiSegmentedControl.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import SwiftUI
import WeiBeiCore

/// One toolbar control for pane segments and the surrounding icon actions.
/// Segments share their moving hover pill; standalone actions draw the same pill.
/// Reading toolbar controls share an outline symbol, a fixed hit region, and
/// a cinnabar selected symbol with a neutral fill. Segments also share their moving hover pill.
struct WeiBeiTopBarButton: View {
static let width: CGFloat = 34
static let height: CGFloat = 28
Expand Down Expand Up @@ -31,13 +31,23 @@ struct WeiBeiTopBarButton: View {
action()
} label: {
Image(systemName: systemImage)
.weiBeiText(13, weight: .semibold)
.symbolRenderingMode(.monochrome)
.symbolVariant(.none)
.weiBeiText(14, weight: .medium)
.foregroundStyle(iconColor)
.frame(width: Self.width * textScale, height: Self.height * textScale)
.contentShape(Rectangle())
}
.buttonStyle(WeiBeiTopBarPressStyle(reduceMotion: reduceMotion))
.background {
Capsule()
.fill(WeiBeiTheme.ink.opacity(colorScheme == .dark ? 0.16 : 0.09))
.frame(width: (Self.width - Self.hoverInset * 2) * textScale,
height: (Self.height - Self.hoverInset * 2) * textScale)
.opacity(isSelected && isEnabled ? 1 : 0)
.animation(reduceMotion ? nil : WeiBeiMotion.hover, value: isSelected)
.allowsHitTesting(false)
.accessibilityHidden(true)
if !usesGroupHover {
RoundedRectangle(cornerRadius: (Self.height - Self.hoverInset * 2) * textScale / 2,
style: .continuous)
Expand Down Expand Up @@ -69,12 +79,29 @@ struct WeiBeiTopBarButton: View {
private var iconColor: Color {
if !isEnabled { return WeiBeiTheme.secondaryInk.opacity(0.4) }
if isSelected { return WeiBeiTheme.cinnabar }
return isHovered ? WeiBeiTheme.ink : WeiBeiTheme.secondaryInk
return isHovered ? WeiBeiTheme.ink : WeiBeiTheme.ink.opacity(0.85)
}
}

/// Pane switches share the toolbar's transparent surface. Selection stays on
/// the cinnabar icon; only pointer hover adds a transient, translucent highlight.
/// A quiet group outline, sized by the existing controls so grouping does not
/// change their hit regions or the native toolbar's overflow measurements.
struct WeiBeiToolbarGroupBackground: View {
@Environment(\.colorScheme) private var colorScheme

var body: some View {
Capsule()
.fill(WeiBeiTheme.paperRaised.opacity(colorScheme == .dark ? 0.65 : 0.55))
.overlay {
Capsule()
.strokeBorder(WeiBeiTheme.ink.opacity(colorScheme == .dark ? 0.18 : 0.10), lineWidth: 0.5)
}
.allowsHitTesting(false)
.accessibilityHidden(true)
}
}

/// Independent pane switches share a reading-toolbar capsule. Each open pane
/// keeps its own selected fill; the moving hover highlight is only transient.
struct WeiBeiSegmentedControl: View {
struct Segment: Identifiable {
let id: String
Expand Down Expand Up @@ -107,6 +134,7 @@ struct WeiBeiSegmentedControl: View {
}
.frame(height: height)
.background(alignment: .leading) { hoverPill }
.background { WeiBeiToolbarGroupBackground() }
.accessibilityElement(children: .contain)
}

Expand Down
Loading