Func is one button with a dark panel of functions; Translator (⌃⌥R or Func): selected text RU<->EN via macOS Translation or claude Haiku, card holds the notch open
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,23 +13,93 @@ import Darwin
|
||||
struct FuncPill: View {
|
||||
@ObservedObject var state: AppState
|
||||
@Binding var showSystem: Bool
|
||||
@State private var open = false
|
||||
@State private var hovered = false
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 6) {
|
||||
Text("Func")
|
||||
.font(.system(size: 12, weight: .semibold, design: .monospaced))
|
||||
.foregroundColor(Color(hex: "#8E939C"))
|
||||
.padding(.leading, 12)
|
||||
Spacer(minLength: 4)
|
||||
FuncButton(symbol: "eyedropper", title: "Пипетка") { ColorPicking.start(state: state) }
|
||||
FuncButton(symbol: "cpu", title: "Мак") {
|
||||
withAnimation(.easeOut(duration: 0.18)) { showSystem.toggle() }
|
||||
Button { open.toggle() } label: {
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: "square.grid.2x2.fill")
|
||||
.font(.system(size: 13))
|
||||
.foregroundColor(Color(hex: "#A78BFA"))
|
||||
Text("Func")
|
||||
.font(.system(size: 13, weight: .semibold, design: .monospaced))
|
||||
.foregroundColor(Color(hex: "#F5F6F8"))
|
||||
Spacer(minLength: 4)
|
||||
Image(systemName: open ? "chevron.up" : "chevron.down")
|
||||
.font(.system(size: 9, weight: .semibold))
|
||||
.foregroundColor(Color(hex: "#5F646D"))
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.background(RoundedRectangle(cornerRadius: 14, style: .continuous)
|
||||
.fill(hovered || open ? Color(hex: "#A78BFA").opacity(0.14) : Color(hex: "#0E0F11")))
|
||||
.overlay(RoundedRectangle(cornerRadius: 14, style: .continuous)
|
||||
.stroke(Color(hex: "#A78BFA").opacity(hovered || open ? 0.5 : 0.2), lineWidth: 1))
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.padding(.trailing, 6)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.background(RoundedRectangle(cornerRadius: 14, style: .continuous).fill(Color(hex: "#0E0F11")))
|
||||
.overlay(RoundedRectangle(cornerRadius: 14, style: .continuous).stroke(Color.white.opacity(0.10), lineWidth: 1))
|
||||
.buttonStyle(.plain)
|
||||
.onHover { h in withAnimation(.easeOut(duration: 0.12)) { hovered = h } }
|
||||
.popover(isPresented: $open, arrowEdge: .bottom) {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
FuncRow(symbol: "eyedropper", color: "#F472B6", title: "Пипетка",
|
||||
subtitle: "цвет пикселя во всех форматах", hint: nil) {
|
||||
open = false
|
||||
ColorPicking.start(state: state)
|
||||
}
|
||||
FuncRow(symbol: "cpu", color: "#34D399", title: "Мак",
|
||||
subtitle: "CPU, ядра, ОЗУ, SSD", hint: nil) {
|
||||
open = false
|
||||
state.translation = nil
|
||||
withAnimation(.easeOut(duration: 0.18)) { showSystem = true }
|
||||
}
|
||||
FuncRow(symbol: "character.bubble", color: "#60A5FA", title: "Переводчик",
|
||||
subtitle: "выделенный текст RU ↔ EN", hint: "⌃⌥R") {
|
||||
open = false
|
||||
showSystem = false
|
||||
TranslatorRun.start(state: state)
|
||||
}
|
||||
}
|
||||
.padding(8)
|
||||
.frame(width: 280)
|
||||
.notchPopoverStyle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct FuncRow: View {
|
||||
let symbol: String
|
||||
let color: String
|
||||
let title: String
|
||||
let subtitle: String
|
||||
let hint: String?
|
||||
let action: () -> Void
|
||||
@State private var hovered = false
|
||||
|
||||
var body: some View {
|
||||
Button(action: action) {
|
||||
HStack(spacing: 10) {
|
||||
Image(systemName: symbol)
|
||||
.font(.system(size: 13, weight: .semibold))
|
||||
.foregroundColor(Color(hex: color))
|
||||
.frame(width: 26, height: 26)
|
||||
.background(RoundedRectangle(cornerRadius: 7).fill(Color(hex: color).opacity(0.15)))
|
||||
VStack(alignment: .leading, spacing: 1) {
|
||||
Text(title).font(.system(size: 13, weight: .semibold))
|
||||
Text(subtitle).font(.system(size: 11)).foregroundColor(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
if let hint {
|
||||
Text(hint).font(.system(size: 11, design: .rounded)).foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 6)
|
||||
.background(RoundedRectangle(cornerRadius: 8).fill(Color.primary.opacity(hovered ? 0.08 : 0)))
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.onHover { hovered = $0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user