Zum Inhalt

ios/Sources/LooksSection.swift

import SwiftUI

/// Save the current look (params + mask) under a name, and load/delete saved
/// looks. Reuses the portable CustomPresetStore (Application Support JSON).
struct LooksSection: View {
    @ObservedObject var model: EditorModel
    @State private var name = ""
    // Filled in onAppear: a default expression here would re-read the store
    // from disk on every ControlsView body evaluation (i.e. every slider tick),
    // because @State initial values are evaluated on each struct init.
    @State private var looks: [CustomPreset] = []

    var body: some View {
        Section("Looks") {
            HStack {
                TextField("Name", text: $name)
                Button("Save") { save() }
                    .disabled(name.trimmingCharacters(in: .whitespaces).isEmpty)
            }
            .onAppear { refresh() }
            ForEach(looks, id: \.id) { look in
                Button(look.name) { load(look) }
            }
            .onDelete { idx in
                idx.map { looks[$0] }.forEach { CustomPresetStore.delete(id: $0.id) }
                refresh()
            }
        }
    }

    private func save() {
        guard let data = try? JSONEncoder().encode(model.preset),
              let json = String(data: data, encoding: .utf8) else { return }
        CustomPresetStore.save(name: name.trimmingCharacters(in: .whitespaces), paramsJSON: json,
                               maskImage: model.maskOn ? model.maskBase64 : nil,
                               maskInvert: model.maskInvert, maskFill: model.maskFill)
        name = ""; refresh()
    }
    private func load(_ look: CustomPreset) {
        // Params and mask apply together or not at all — a half-applied look
        // (old params + new mask) would silently misrepresent the saved state.
        guard let p = try? JSONDecoder().decode(Preset.self, from: Data(look.paramsJSON.utf8)) else { return }
        model.preset = p
        if let img = look.maskImage {
            model.maskBase64 = img
            model.maskImageData = Data(base64Encoded: img)
            model.maskInvert = look.maskInvert; model.maskFill = look.maskFill; model.maskOn = true
        } else {
            model.maskOn = false
        }
    }
    private func refresh() { looks = CustomPresetStore.list() }
}