updated themeeditor to work with teh background color

added suiColor as a get/set property on colorcodable
trying to fix the wierd jumpiness when shaking the color in the green bit
trying to fix the wierd drift when increasing the "brightness"
savethemes will clear themes before starting to append
updated updatetheme to savethemes aswell
	modified:   ShhShell/Host/HostsManager.swift
	modified:   ShhShell/Themes/ColorCodable.swift
	modified:   ShhShell/Themes/ThemeCodable.swift
	modified:   ShhShell/Views/Themes/ThemeEditorView.swift
This commit is contained in:
neon443
2025-07-08 14:27:13 +01:00
parent bcdece3bee
commit e5e0a47f4f
4 changed files with 128 additions and 57 deletions

View File

@@ -61,6 +61,7 @@ class HostsManager: ObservableObject, @unchecked Sendable {
guard let decodedThemes = try? JSONDecoder().decode([ThemeCodable].self, from: dataTheme) else { return } guard let decodedThemes = try? JSONDecoder().decode([ThemeCodable].self, from: dataTheme) else { return }
self.themes = []
for index in 0..<decodedThemes.count { for index in 0..<decodedThemes.count {
guard let encoded = try? JSONEncoder().encode(decodedThemes[index]) else { return } guard let encoded = try? JSONEncoder().encode(decodedThemes[index]) else { return }
guard let synthedTheme = Theme.decodeTheme(data: encoded) else { return } guard let synthedTheme = Theme.decodeTheme(data: encoded) else { return }
@@ -117,6 +118,7 @@ class HostsManager: ObservableObject, @unchecked Sendable {
func updateTheme(_ theme: Theme) { func updateTheme(_ theme: Theme) {
guard let index = themes.firstIndex(where: { $0.id == theme.id }) else { return } guard let index = themes.firstIndex(where: { $0.id == theme.id }) else { return }
themes[index] = theme themes[index] = theme
saveThemes()
} }
func renameTheme(_ theme: Theme?, to newName: String) { func renameTheme(_ theme: Theme?, to newName: String) {

View File

@@ -38,17 +38,27 @@ struct ColorCodable: Codable, Hashable, Equatable {
} }
} }
extension ColorCodable {
var suiColor: SwiftUI.Color {
get {
let red = CGFloat(self.red)
let green = CGFloat(self.green)
let blue = CGFloat(self.blue)
return Color(UIColor(red: red, green: green, blue: blue, alpha: 1))
}
set {
let cc = ColorCodable(color: newValue)
self.red = cc.red
self.green = cc.green
self.blue = cc.blue
}
}
}
extension ColorCodable { extension ColorCodable {
var stColor: SwiftTerm.Color { var stColor: SwiftTerm.Color {
return SwiftTerm.Color(self) return SwiftTerm.Color(self)
} }
var suiColor: SwiftUI.Color {
let red = CGFloat(self.red)/65535
let green = CGFloat(self.green)/65535
let blue = CGFloat(self.blue)/65535
return Color(UIColor(red: red, green: green, blue: blue, alpha: 1))
}
} }
extension SwiftTerm.Color { extension SwiftTerm.Color {

View File

@@ -113,23 +113,72 @@ extension ThemeCodable {
} }
} }
set { set {
let cc = ColorCodable(color: newValue)
switch index { switch index {
case 0: ansi0 = ColorCodable(color: newValue) case 0:
case 1: ansi1 = ColorCodable(color: newValue) ansi0.red = cc.red
case 2: ansi2 = ColorCodable(color: newValue) ansi0.green = cc.green
case 3: ansi3 = ColorCodable(color: newValue) ansi0.blue = cc.blue
case 4: ansi4 = ColorCodable(color: newValue) case 1:
case 5: ansi5 = ColorCodable(color: newValue) ansi1.red = cc.red
case 6: ansi6 = ColorCodable(color: newValue) ansi1.green = cc.green
case 7: ansi7 = ColorCodable(color: newValue) ansi1.blue = cc.blue
case 8: ansi8 = ColorCodable(color: newValue) case 2:
case 9: ansi9 = ColorCodable(color: newValue) ansi2.red = cc.red
case 10: ansi10 = ColorCodable(color: newValue) ansi2.green = cc.green
case 11: ansi11 = ColorCodable(color: newValue) ansi2.blue = cc.blue
case 12: ansi12 = ColorCodable(color: newValue) case 3:
case 13: ansi13 = ColorCodable(color: newValue) ansi3.red = cc.red
case 14: ansi14 = ColorCodable(color: newValue) ansi3.green = cc.green
case 15: ansi15 = ColorCodable(color: newValue) ansi3.blue = cc.blue
case 4:
ansi4.red = cc.red
ansi4.green = cc.green
ansi4.blue = cc.blue
case 5:
ansi5.red = cc.red
ansi5.green = cc.green
ansi5.blue = cc.blue
case 6:
ansi6.red = cc.red
ansi6.green = cc.green
ansi6.blue = cc.blue
case 7:
ansi7.red = cc.red
ansi7.green = cc.green
ansi7.blue = cc.blue
case 8:
ansi8.red = cc.red
ansi8.green = cc.green
ansi8.blue = cc.blue
case 9:
ansi9.red = cc.red
ansi9.green = cc.green
ansi9.blue = cc.blue
case 10:
ansi10.red = cc.red
ansi10.green = cc.green
ansi10.blue = cc.blue
case 11:
ansi11.red = cc.red
ansi11.green = cc.green
ansi11.blue = cc.blue
case 12:
ansi12.red = cc.red
ansi12.green = cc.green
ansi12.blue = cc.blue
case 13:
ansi13.red = cc.red
ansi13.green = cc.green
ansi13.blue = cc.blue
case 14:
ansi14.red = cc.red
ansi14.green = cc.green
ansi14.blue = cc.blue
case 15:
ansi15.red = cc.red
ansi15.green = cc.green
ansi15.blue = cc.blue
default: fatalError() default: fatalError()
} }
} }

View File

@@ -11,57 +11,67 @@ import SwiftTerm
struct ThemeEditorView: View { struct ThemeEditorView: View {
@ObservedObject var hostsManager: HostsManager @ObservedObject var hostsManager: HostsManager
// @State var theme: Theme // @State var theme: Theme
@State var themeCodable: ThemeCodable @State var themeCodable: ThemeCodable
init(hostsManager: HostsManager, theme: Theme) { init(hostsManager: HostsManager, theme: Theme) {
self.hostsManager = hostsManager self.hostsManager = hostsManager
// self.theme = theme // self.theme = theme
self.themeCodable = theme.themeCodable self.themeCodable = theme.themeCodable
} }
var body: some View { var body: some View {
NavigationStack { NavigationStack {
// List { List {
// TextField("Name", text: $themeCodable.name) TextField(
"Name",
ThemePreview(hostsManager: HostsManager(), theme: themeCodable.toTheme(), canModify: false) text: Binding(get: { themeCodable.name ?? "Theme" }, set: { themeCodable.name = $0 })
.id(themeCodable) )
.textFieldStyle(.roundedBorder)
Group {
Rectangle() ThemePreview(hostsManager: HostsManager(), theme: themeCodable.toTheme(), canModify: false)
.fill(themeCodable.foreground.stColor.suiColor) .id(themeCodable)
Rectangle()
.fill(themeCodable.background.stColor.suiColor) Group {
Rectangle() HStack {
.fill(themeCodable.bold.stColor.suiColor) Rectangle()
Rectangle() .fill(themeCodable.foreground.suiColor)
.fill(themeCodable.cursor.stColor.suiColor) Text("Foreground")
Rectangle() Spacer()
.fill(themeCodable.cursorText.stColor.suiColor) ColorPicker("", selection: $themeCodable.foreground.suiColor, supportsOpacity: false)
Rectangle() .labelsHidden()
.fill(themeCodable.selection.stColor.suiColor) }
Rectangle() Rectangle()
.fill(themeCodable.selectedText.stColor.suiColor) .fill(themeCodable.background.suiColor)
} Rectangle()
.frame(width: 100) .fill(themeCodable.bold.suiColor)
.toolbar { Rectangle()
Button() { .fill(themeCodable.cursor.suiColor)
Rectangle()
} label: { .fill(themeCodable.cursorText.suiColor)
Label("Donw", systemImage: "checkmark") Rectangle()
.fill(themeCodable.selection.suiColor)
Rectangle()
.fill(themeCodable.selectedText.suiColor)
} }
}
ForEach(0...1, id: \.self) { row in ForEach(0...1, id: \.self) { row in
HStack { HStack {
ForEach(1...8, id: \.self) { col in ForEach(1...8, id: \.self) { col in
let index = (col + (row * 8)) - 1 let index = (col + (row * 8)) - 1
ColorPicker("Ansi \(index+1)", selection: $themeCodable[ansiIndex: index]) ColorPicker("Ansi \(index+1)", selection: $themeCodable[ansiIndex: index], supportsOpacity: false)
} }
} }
} }
// } }
.navigationTitle("Edit Theme")
.toolbar {
Button() {
hostsManager.updateTheme(themeCodable.toTheme())
} label: {
Label("Done", systemImage: "checkmark")
}
}
} }
} }
} }