Skip to content

Commit

Permalink
fix punctuation config ui (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
eagleoflqj authored May 3, 2024
1 parent 170236d commit fe60dde
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 15 deletions.
Binary file modified assets/zh-Hans.lproj/Localizable.strings
Binary file not shown.
21 changes: 20 additions & 1 deletion src/config/config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func jsonToConfig(_ json: JSON, _ pathPrefix: String) throws -> Config {
let description = json["Description"].stringValue
// Option
if let type = json["Type"].string,
!type.contains("$")
!type.contains("$") || type.hasPrefix("List|")
{
do {
let option = try jsonToOption(json, type)
Expand Down Expand Up @@ -104,6 +104,8 @@ private func jsonToOption(_ json: JSON, _ type: String) throws -> any Option {
return try ListOption<StringOption>.decode(json: json)
} else if type == "List|Enum" {
return try ListOption<EnumOption>.decode(json: json)
} else if type == "List|Entries$PunctuationMapEntryConfig" {
return try ListOption<PunctuationMapOption>.decode(json: json)
} else if type == "External" {
return try ExternalOption.decode(json: json)
} else {
Expand Down Expand Up @@ -214,6 +216,23 @@ extension Array: FcitxCodable where Element: FcitxCodable {
}
}

extension Dictionary: FcitxCodable where Key == String, Value: FcitxCodable {
static func decode(json: JSON) throws -> Self {
var result: [Key: Value] = [:]
for (key, subJson): (String, JSON) in json {
result[key] = try Value.decode(json: subJson)
}
return result
}
func encodeValueJSON() -> JSON {
var json = JSON()
for (key, value) in self {
json[key] = value.encodeValueJSON()
}
return json
}
}

extension Optional: FcitxCodable where Wrapped: FcitxCodable {
static func decode(json: JSON) throws -> Self {
do {
Expand Down
33 changes: 31 additions & 2 deletions src/config/optionmodels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,35 @@ class AppIMOption: Option, ObservableObject, EmptyConstructible {
}
}

class PunctuationMapOption: Option, ObservableObject, EmptyConstructible {
typealias Storage = [String: String]
let defaultValue: [String: String]
var value: [String: String]

required init(defaultValue: Storage, value: Storage?) {
self.defaultValue = defaultValue
self.value = value ?? defaultValue
}

static func decode(json: JSON) throws -> Self {
return Self(
defaultValue: try Storage.decode(json: json["DefaultValue"]),
value: try Storage?.decode(json: json["Value"])
)
}

func encodeValueJSON() -> JSON {
return value.encodeValueJSON()
}

func resetToDefault() {
}

static func empty(json: JSON) throws -> Self {
return Self(defaultValue: [:], value: [:])
}
}

class ListOption<T: Option & EmptyConstructible>: Option, ObservableObject {
let defaultValue: [T]
@Published var value: [Identified<T>]
Expand All @@ -366,10 +395,10 @@ class ListOption<T: Option & EmptyConstructible>: Option, ObservableObject {

static func decode(json: JSON) throws -> Self {
let defaultOptions = try [T.Storage].decode(json: json["DefaultValue"]).map {
try T.decode(json: try json.merged(with: ["DefaultValue": $0, "Value": $0]))
return try T.decode(json: ["DefaultValue": $0, "Value": $0])
}
let options = try [T.Storage].decode(json: json["Value"]).map {
try T.decode(json: try json.merged(with: ["DefaultValue": $0, "Value": $0]))
try T.decode(json: ["DefaultValue": $0, "Value": $0])
}
return Self(
defaultValue: defaultOptions,
Expand Down
45 changes: 33 additions & 12 deletions src/config/optionviews.swift
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,6 @@ struct ListOptionView<T: Option & EmptyConstructible>: OptionView {
.disabled(index == 0)
.buttonStyle(BorderlessButtonStyle())

Button(action: { moveDown(index: index) }) {
Image(systemName: "arrow.down")
}
.disabled(index == model.value.count - 1)
.buttonStyle(BorderlessButtonStyle())

Button(action: { remove(at: index) }) {
Image(systemName: "minus")
}
Expand Down Expand Up @@ -310,12 +304,6 @@ struct ListOptionView<T: Option & EmptyConstructible>: OptionView {
model.value.swapAt(index, index - 1)
}
}

private func moveDown(index: Int) {
if index < model.value.count - 1 {
model.value.swapAt(index, index + 1)
}
}
}

struct FontOptionView: OptionView {
Expand Down Expand Up @@ -461,6 +449,35 @@ struct AppIMOptionView: OptionView {
}
}

struct PunctuationMapOptionView: OptionView {
let label: String
let overrideLabel: String? = nil
@ObservedObject var model: PunctuationMapOption

var body: some View {
HStack {
TextField(
NSLocalizedString("Key", comment: ""),
text: Binding(
get: { model.value["Key"] ?? "" },
set: { model.value["Key"] = $0 }
))
TextField(
NSLocalizedString("Mapping", comment: ""),
text: Binding(
get: { model.value["Mapping"] ?? "" },
set: { model.value["Mapping"] = $0 }
))
TextField(
NSLocalizedString("Alternative Mapping", comment: ""),
text: Binding(
get: { model.value["AltMapping"] ?? "" },
set: { model.value["AltMapping"] = $0 }
))
}
}
}

struct GroupOptionView: OptionView {
let label: String
let overrideLabel: String? = nil
Expand Down Expand Up @@ -525,6 +542,8 @@ func buildViewImpl(label: String, option: any Option) -> any OptionView {
return IntegerOptionView(label: label, model: option)
} else if let option = option as? ColorOption {
return ColorOptionView(label: label, model: option)
} else if let option = option as? PunctuationMapOption {
return PunctuationMapOptionView(label: label, model: option)
} else if let option = option as? ListOption<FontOption> {
return ListOptionView<FontOption>(label: label, model: option)
} else if let option = option as? ListOption<AppIMOption> {
Expand All @@ -533,6 +552,8 @@ func buildViewImpl(label: String, option: any Option) -> any OptionView {
return ListOptionView<StringOption>(label: label, model: option)
} else if let option = option as? ListOption<EnumOption> {
return ListOptionView<EnumOption>(label: label, model: option)
} else if let option = option as? ListOption<PunctuationMapOption> {
return ListOptionView<PunctuationMapOption>(label: label, model: option)
} else {
return UnsupportedOptionView(model: option)
}
Expand Down

0 comments on commit fe60dde

Please sign in to comment.