fix: match provider picker to action popup

This commit is contained in:
2026-10-18 00:05:46 +02:00
parent 11e604e79e
commit d829565188
5 changed files with 99 additions and 29 deletions
+27 -18
View File
@@ -4,7 +4,7 @@ import Security
@MainActor
final class TranslationController: NSViewController {
let providerPicker = NSPopUpButton()
private let providerButton = NSButton(title: "", target: nil, action: nil)
let providerControl = NSView()
private let languageButton = NSButton(title: "", target: nil, action: nil)
private let actionsButton = NSButton(title: "Actions", target: nil, action: nil)
@@ -21,7 +21,7 @@ final class TranslationController: NSViewController {
Locale(identifier: "en").localizedString(forLanguageCode: code) ?? code
}
private func languageName(_ code: String) -> String { Self.languageName(code) }
private var usesMyMemory: Bool { providerPicker.indexOfSelectedItem == 0 }
private var usesMyMemory: Bool
private let output = NSTextView()
private let settingsButton = NSButton(title: "Open Translate Settings", target: nil, action: nil)
private let status = NSTextField(wrappingLabelWithString: "")
@@ -52,6 +52,7 @@ final class TranslationController: NSViewController {
self.myMemory = myMemory
self.openAI = openAI
self.pasteboard = pasteboard
usesMyMemory = defaults.string(forKey: "translationProvider") != "openai"
sourceLanguage = defaults.string(forKey: "translationSourceLanguage")
.flatMap { Self.languages.contains($0) ? $0 : nil } ?? "en"
targetLanguage = defaults.string(forKey: "translationTargetLanguage")
@@ -63,30 +64,28 @@ final class TranslationController: NSViewController {
override func loadView() {
view = NSView()
providerPicker.addItems(withTitles: ["MyMemory (no key)", "OpenAI · gpt-6-luna"])
providerPicker.selectItem(at: defaults.string(forKey: "translationProvider") == "openai" ? 1 : 0)
providerPicker.setAccessibilityLabel("Translation provider")
providerPicker.target = self
providerPicker.action = #selector(providerChanged)
providerPicker.isBordered = false
(providerPicker.cell as? NSPopUpButtonCell)?.arrowPosition = .noArrow
providerPicker.font = .systemFont(ofSize: 12, weight: .medium)
providerPicker.contentTintColor = SunsetPalette.text
providerButton.title = usesMyMemory ? "MyMemory (no key)" : "OpenAI · gpt-6-luna"
providerButton.setAccessibilityLabel("Translation provider")
providerButton.target = self
providerButton.action = #selector(showProviders)
providerButton.isBordered = false
providerButton.font = .systemFont(ofSize: 12, weight: .medium)
providerButton.contentTintColor = SunsetPalette.text
let chevron = NSButton(image: NSImage(systemSymbolName: "chevron.down", accessibilityDescription: nil)!,
target: providerPicker, action: #selector(NSControl.performClick(_:)))
target: self, action: #selector(showProviders))
chevron.isBordered = false
chevron.contentTintColor = SunsetPalette.secondaryText
chevron.setAccessibilityElement(false)
stylePill(providerControl)
for control in [providerPicker, chevron] {
for control in [providerButton, chevron] {
control.translatesAutoresizingMaskIntoConstraints = false
providerControl.addSubview(control)
}
NSLayoutConstraint.activate([
providerControl.heightAnchor.constraint(equalToConstant: 36),
providerPicker.leadingAnchor.constraint(equalTo: providerControl.leadingAnchor, constant: 14),
providerPicker.centerYAnchor.constraint(equalTo: providerControl.centerYAnchor),
chevron.leadingAnchor.constraint(equalTo: providerPicker.trailingAnchor, constant: 8),
providerButton.leadingAnchor.constraint(equalTo: providerControl.leadingAnchor, constant: 14),
providerButton.centerYAnchor.constraint(equalTo: providerControl.centerYAnchor),
chevron.leadingAnchor.constraint(equalTo: providerButton.trailingAnchor, constant: 8),
chevron.centerYAnchor.constraint(equalTo: providerControl.centerYAnchor),
chevron.trailingAnchor.constraint(equalTo: providerControl.trailingAnchor, constant: -12),
chevron.widthAnchor.constraint(equalToConstant: 10),
@@ -112,6 +111,7 @@ final class TranslationController: NSViewController {
actions.changeSourceLanguage = { [weak self] in self?.chooseLanguage(source: true) }
actions.changeTargetLanguage = { [weak self] in self?.chooseLanguage(source: false) }
actions.swapLanguages = { [weak self] in self?.swapLanguages() }
actions.selectProvider = { [weak self] in self?.selectProvider(openAI: $0) }
settingsButton.target = self
settingsButton.action = #selector(openSettings)
settingsButton.isHidden = true
@@ -196,6 +196,11 @@ final class TranslationController: NSViewController {
pill.layer?.backgroundColor = SunsetPalette.background.withAlphaComponent(0.25).cgColor
}
@objc func showProviders() {
actions.showProviders(selectedOpenAI: !usesMyMemory, relativeTo: providerButton)
translateButton.keyEquivalent = actions.isShown ? "" : "\r"
}
@objc func showActions() {
actions.showTranslation(relativeTo: actionsButton)
translateButton.keyEquivalent = actions.isShown ? "" : "\r"
@@ -267,8 +272,12 @@ final class TranslationController: NSViewController {
setStatus("")
}
@objc private func providerChanged() {
defaults.set(usesMyMemory ? "mymemory" : "openai", forKey: "translationProvider")
func selectProvider(openAI: Bool) {
let newUsesMyMemory = !openAI
guard newUsesMyMemory != usesMyMemory else { return }
usesMyMemory = newUsesMyMemory
providerButton.title = usesMyMemory ? "MyMemory (no key)" : "OpenAI · gpt-6-luna"
defaults.set(openAI ? "openai" : "mymemory", forKey: "translationProvider")
inputChanged()
}