fix: repaired scene prefs
This commit is contained in:
@@ -1,66 +1,18 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
private let generationDoubleFormat = FloatingPointFormatStyle<Double>.number.precision(.fractionLength(0...2))
|
|
||||||
private let generationIntegerFormat = IntegerFormatStyle<Int>.number.grouping(.never)
|
|
||||||
|
|
||||||
struct GenerationDefaultsEditor: View {
|
struct GenerationDefaultsEditor: View {
|
||||||
@Binding var settings: GenerationSettings
|
@Binding var settings: GenerationSettings
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Toggle("Enable thinking mode", isOn: $settings.thinkingEnabled)
|
Toggle("Enable thinking mode", isOn: $settings.thinkingEnabled)
|
||||||
doubleRow("Temperature", value: $settings.temperature)
|
DecimalSettingRow(title: "Temperature", value: $settings.temperature)
|
||||||
doubleRow("Top P", value: $settings.topP)
|
DecimalSettingRow(title: "Top P", value: $settings.topP)
|
||||||
intRow("Top K", value: $settings.topK)
|
IntegerSettingRow(title: "Top K", value: $settings.topK)
|
||||||
doubleRow("Min P", value: $settings.minP)
|
DecimalSettingRow(title: "Min P", value: $settings.minP)
|
||||||
intRow("Max tokens", value: $settings.maxTokens)
|
IntegerSettingRow(title: "Max tokens", value: $settings.maxTokens)
|
||||||
optionalDoubleRow("Repetition penalty", value: $settings.repetitionPenalty)
|
OptionalDecimalSettingRow(title: "Repetition penalty", value: $settings.repetitionPenalty, fallbackValue: 1.0)
|
||||||
optionalDoubleRow("Presence penalty", value: $settings.presencePenalty)
|
OptionalDecimalSettingRow(title: "Presence penalty", value: $settings.presencePenalty, fallbackValue: 0.0)
|
||||||
optionalDoubleRow("Frequency penalty", value: $settings.frequencyPenalty)
|
OptionalDecimalSettingRow(title: "Frequency penalty", value: $settings.frequencyPenalty, fallbackValue: 0.0)
|
||||||
}
|
|
||||||
|
|
||||||
private func doubleRow(_ title: String, value: Binding<Double>) -> some View {
|
|
||||||
HStack {
|
|
||||||
Text(title)
|
|
||||||
Spacer()
|
|
||||||
TextField(title, value: value, format: generationDoubleFormat)
|
|
||||||
.multilineTextAlignment(.trailing)
|
|
||||||
.frame(width: 90)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func intRow(_ title: String, value: Binding<Int>) -> some View {
|
|
||||||
HStack {
|
|
||||||
Text(title)
|
|
||||||
Spacer()
|
|
||||||
TextField(title, value: value, format: generationIntegerFormat)
|
|
||||||
.multilineTextAlignment(.trailing)
|
|
||||||
.frame(width: 90)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func optionalDoubleRow(_ title: String, value: Binding<Double?>) -> some View {
|
|
||||||
HStack {
|
|
||||||
Text(title)
|
|
||||||
Spacer()
|
|
||||||
TextField(title, value: binding(for: value), format: generationDoubleFormat)
|
|
||||||
.multilineTextAlignment(.trailing)
|
|
||||||
.frame(width: 90)
|
|
||||||
Button(value.wrappedValue == nil ? "Set" : "Clear") {
|
|
||||||
if value.wrappedValue == nil {
|
|
||||||
value.wrappedValue = 1.0
|
|
||||||
} else {
|
|
||||||
value.wrappedValue = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.buttonStyle(.link)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func binding(for value: Binding<Double?>) -> Binding<Double> {
|
|
||||||
Binding(
|
|
||||||
get: { value.wrappedValue ?? 1.0 },
|
|
||||||
set: { value.wrappedValue = $0 }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,69 +28,228 @@ struct GenerationOverridesEditor: View {
|
|||||||
Text("Disabled").tag(Optional(false))
|
Text("Disabled").tag(Optional(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
optionalDoubleRow("Temperature", value: $overrides.temperature, inheritedValue: inheritedSettings.temperature)
|
OptionalDecimalSettingRow(title: "Temperature", value: $overrides.temperature, fallbackValue: inheritedSettings.temperature, inherited: true)
|
||||||
optionalDoubleRow("Top P", value: $overrides.topP, inheritedValue: inheritedSettings.topP)
|
OptionalDecimalSettingRow(title: "Top P", value: $overrides.topP, fallbackValue: inheritedSettings.topP, inherited: true)
|
||||||
optionalIntRow("Top K", value: $overrides.topK, inheritedValue: inheritedSettings.topK)
|
OptionalIntegerSettingRow(title: "Top K", value: $overrides.topK, fallbackValue: inheritedSettings.topK, inherited: true)
|
||||||
optionalDoubleRow("Min P", value: $overrides.minP, inheritedValue: inheritedSettings.minP)
|
OptionalDecimalSettingRow(title: "Min P", value: $overrides.minP, fallbackValue: inheritedSettings.minP, inherited: true)
|
||||||
optionalIntRow("Max tokens", value: $overrides.maxTokens, inheritedValue: inheritedSettings.maxTokens)
|
OptionalIntegerSettingRow(title: "Max tokens", value: $overrides.maxTokens, fallbackValue: inheritedSettings.maxTokens, inherited: true)
|
||||||
optionalDoubleRow("Repetition penalty", value: $overrides.repetitionPenalty, inheritedValue: inheritedSettings.repetitionPenalty ?? 0)
|
OptionalDecimalSettingRow(title: "Repetition penalty", value: $overrides.repetitionPenalty, fallbackValue: inheritedSettings.repetitionPenalty ?? 0, inherited: true)
|
||||||
optionalDoubleRow("Presence penalty", value: $overrides.presencePenalty, inheritedValue: inheritedSettings.presencePenalty ?? 0)
|
OptionalDecimalSettingRow(title: "Presence penalty", value: $overrides.presencePenalty, fallbackValue: inheritedSettings.presencePenalty ?? 0, inherited: true)
|
||||||
optionalDoubleRow("Frequency penalty", value: $overrides.frequencyPenalty, inheritedValue: inheritedSettings.frequencyPenalty ?? 0)
|
OptionalDecimalSettingRow(title: "Frequency penalty", value: $overrides.frequencyPenalty, fallbackValue: inheritedSettings.frequencyPenalty ?? 0, inherited: true)
|
||||||
|
|
||||||
Text("Unset fields inherit from \(inheritedSource). The values shown are the effective starting values for this scene.")
|
Text("Unset fields inherit from \(inheritedSource). The values shown are the effective starting values for this scene.")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func optionalDoubleRow(_ title: String, value: Binding<Double?>, inheritedValue: Double) -> some View {
|
private struct DecimalSettingRow: View {
|
||||||
|
let title: String
|
||||||
|
@Binding var value: Double
|
||||||
|
@State private var text: String
|
||||||
|
|
||||||
|
init(title: String, value: Binding<Double>) {
|
||||||
|
self.title = title
|
||||||
|
self._value = value
|
||||||
|
self._text = State(initialValue: NumericFieldFormatting.doubleString(value.wrappedValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
Text(title)
|
Text(title)
|
||||||
Spacer()
|
Spacer()
|
||||||
TextField(title, value: Binding(
|
TextField("", text: $text)
|
||||||
get: { value.wrappedValue ?? inheritedValue },
|
|
||||||
set: { value.wrappedValue = $0 }
|
|
||||||
), format: generationDoubleFormat)
|
|
||||||
.multilineTextAlignment(.trailing)
|
.multilineTextAlignment(.trailing)
|
||||||
.frame(width: 90)
|
.frame(width: 90)
|
||||||
if value.wrappedValue == nil {
|
.onChange(of: text) {
|
||||||
Text("Inherited")
|
if let parsed = NumericFieldFormatting.parseDouble(text) {
|
||||||
.font(.caption)
|
value = parsed
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
Button(value.wrappedValue == nil ? "Override" : "Clear") {
|
|
||||||
if value.wrappedValue == nil {
|
|
||||||
value.wrappedValue = inheritedValue
|
|
||||||
} else {
|
|
||||||
value.wrappedValue = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.link)
|
.onChange(of: value) {
|
||||||
|
let formatted = NumericFieldFormatting.doubleString(value)
|
||||||
|
if text != formatted {
|
||||||
|
text = formatted
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func optionalIntRow(_ title: String, value: Binding<Int?>, inheritedValue: Int) -> some View {
|
|
||||||
HStack {
|
|
||||||
Text(title)
|
|
||||||
Spacer()
|
|
||||||
TextField(title, value: Binding(
|
|
||||||
get: { value.wrappedValue ?? inheritedValue },
|
|
||||||
set: { value.wrappedValue = $0 }
|
|
||||||
), format: generationIntegerFormat)
|
|
||||||
.multilineTextAlignment(.trailing)
|
|
||||||
.frame(width: 90)
|
|
||||||
if value.wrappedValue == nil {
|
|
||||||
Text("Inherited")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
Button(value.wrappedValue == nil ? "Override" : "Clear") {
|
|
||||||
if value.wrappedValue == nil {
|
|
||||||
value.wrappedValue = inheritedValue
|
|
||||||
} else {
|
|
||||||
value.wrappedValue = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.buttonStyle(.link)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct IntegerSettingRow: View {
|
||||||
|
let title: String
|
||||||
|
@Binding var value: Int
|
||||||
|
@State private var text: String
|
||||||
|
|
||||||
|
init(title: String, value: Binding<Int>) {
|
||||||
|
self.title = title
|
||||||
|
self._value = value
|
||||||
|
self._text = State(initialValue: NumericFieldFormatting.intString(value.wrappedValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Text(title)
|
||||||
|
Spacer()
|
||||||
|
TextField("", text: $text)
|
||||||
|
.multilineTextAlignment(.trailing)
|
||||||
|
.frame(width: 90)
|
||||||
|
.onChange(of: text) {
|
||||||
|
if let parsed = NumericFieldFormatting.parseInt(text) {
|
||||||
|
value = parsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onChange(of: value) {
|
||||||
|
let formatted = NumericFieldFormatting.intString(value)
|
||||||
|
if text != formatted {
|
||||||
|
text = formatted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct OptionalDecimalSettingRow: View {
|
||||||
|
let title: String
|
||||||
|
@Binding var value: Double?
|
||||||
|
let fallbackValue: Double
|
||||||
|
var inherited = false
|
||||||
|
@State private var text: String
|
||||||
|
|
||||||
|
init(title: String, value: Binding<Double?>, fallbackValue: Double, inherited: Bool = false) {
|
||||||
|
self.title = title
|
||||||
|
self._value = value
|
||||||
|
self.fallbackValue = fallbackValue
|
||||||
|
self.inherited = inherited
|
||||||
|
self._text = State(initialValue: NumericFieldFormatting.doubleString(value.wrappedValue ?? fallbackValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Text(title)
|
||||||
|
Spacer()
|
||||||
|
TextField("", text: $text)
|
||||||
|
.multilineTextAlignment(.trailing)
|
||||||
|
.frame(width: 90)
|
||||||
|
.onChange(of: text) {
|
||||||
|
if let parsed = NumericFieldFormatting.parseDouble(text) {
|
||||||
|
value = parsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onChange(of: value) {
|
||||||
|
syncText()
|
||||||
|
}
|
||||||
|
.onChange(of: fallbackValue) {
|
||||||
|
if value == nil {
|
||||||
|
syncText()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if inherited && value == nil {
|
||||||
|
Text("Inherited")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
Button(value == nil ? "Override" : "Clear") {
|
||||||
|
if value == nil {
|
||||||
|
value = fallbackValue
|
||||||
|
} else {
|
||||||
|
value = nil
|
||||||
|
}
|
||||||
|
syncText()
|
||||||
|
}
|
||||||
|
.buttonStyle(.link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func syncText() {
|
||||||
|
let formatted = NumericFieldFormatting.doubleString(value ?? fallbackValue)
|
||||||
|
if text != formatted {
|
||||||
|
text = formatted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct OptionalIntegerSettingRow: View {
|
||||||
|
let title: String
|
||||||
|
@Binding var value: Int?
|
||||||
|
let fallbackValue: Int
|
||||||
|
var inherited = false
|
||||||
|
@State private var text: String
|
||||||
|
|
||||||
|
init(title: String, value: Binding<Int?>, fallbackValue: Int, inherited: Bool = false) {
|
||||||
|
self.title = title
|
||||||
|
self._value = value
|
||||||
|
self.fallbackValue = fallbackValue
|
||||||
|
self.inherited = inherited
|
||||||
|
self._text = State(initialValue: NumericFieldFormatting.intString(value.wrappedValue ?? fallbackValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Text(title)
|
||||||
|
Spacer()
|
||||||
|
TextField("", text: $text)
|
||||||
|
.multilineTextAlignment(.trailing)
|
||||||
|
.frame(width: 90)
|
||||||
|
.onChange(of: text) {
|
||||||
|
if let parsed = NumericFieldFormatting.parseInt(text) {
|
||||||
|
value = parsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onChange(of: value) {
|
||||||
|
syncText()
|
||||||
|
}
|
||||||
|
.onChange(of: fallbackValue) {
|
||||||
|
if value == nil {
|
||||||
|
syncText()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if inherited && value == nil {
|
||||||
|
Text("Inherited")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
Button(value == nil ? "Override" : "Clear") {
|
||||||
|
if value == nil {
|
||||||
|
value = fallbackValue
|
||||||
|
} else {
|
||||||
|
value = nil
|
||||||
|
}
|
||||||
|
syncText()
|
||||||
|
}
|
||||||
|
.buttonStyle(.link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func syncText() {
|
||||||
|
let formatted = NumericFieldFormatting.intString(value ?? fallbackValue)
|
||||||
|
if text != formatted {
|
||||||
|
text = formatted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum NumericFieldFormatting {
|
||||||
|
static func parseDouble(_ text: String) -> Double? {
|
||||||
|
let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !trimmed.isEmpty else { return nil }
|
||||||
|
return Double(trimmed.replacingOccurrences(of: ",", with: "."))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func parseInt(_ text: String) -> Int? {
|
||||||
|
let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !trimmed.isEmpty else { return nil }
|
||||||
|
return Int(trimmed)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func doubleString(_ value: Double) -> String {
|
||||||
|
if value.rounded() == value {
|
||||||
|
return String(Int(value))
|
||||||
|
}
|
||||||
|
return String(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func intString(_ value: Int) -> String {
|
||||||
|
String(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user