-/*
- Copyright (C) 2024 Rubén Beltrán del Río
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see https://map.tranquil.systems.
- */
+// Copyright (C) 2024 Rubén Beltrán del Río
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see https://map.tranquil.systems.
import SwiftUI
struct MapEditor: View {
@State var selectedEvolution: StageType = .behavior
@State var isSearching: Bool = false
+ private let changeDebouncer: Debouncer = Debouncer(seconds: 0.05)
+
@AppStorage("viewStyle") var viewStyle: ViewStyle = .horizontal
let zoomRange = Constants.kMinZoom...Constants.kMaxZoom
@State var searchTerm = ""
@State var selectedTerm = 0
- var results: [Range<String.Index>] {
+ @State var results: [Range<String.Index>] = []
+
+ private func updateRanges() {
if !isSearching || searchTerm.isEmpty {
- return []
+ results = []
}
let options: NSString.CompareOptions = [.caseInsensitive, .diacriticInsensitive]
var searchRange = document.text.startIndex..<document.text.endIndex
searchRange = range.upperBound..<document.text.endIndex
}
- return ranges
+ results = ranges
}
},
onDismiss: {
- withAnimation {
- isSearching = false
- }
+ isSearching = false
}
)
.onChange(
of: searchTerm,
{
- selectedTerm = 0
+ changeDebouncer.debounce {
+ updateRanges()
+ selectedTerm = 0
+ }
})
Divider()
}
adaptiveStack {
ZStack(alignment: .topLeading) {
MapTextEditor(document: $document, highlightRanges: results, selectedRange: selectedTerm)
- .background(Color.ui.background)
- .foregroundColor(Color.ui.foreground)
+ .background(Color.UI.background)
+ .foregroundColor(Color.UI.foreground)
.frame(minHeight: 96.0)
- }.padding(.top, 8.0).padding(.leading, 8.0).background(Color.ui.background).cornerRadius(
+ }.padding(.top, 8.0).padding(.leading, 8.0).background(Color.UI.background).cornerRadius(
5.0)
GeometryReader { geometry in
ScrollView([.horizontal, .vertical]) {
).scaleEffect(zoom, anchor: .center).frame(
width: (Dimensions.mapSize.width + 2 * Dimensions.mapPadding) * zoom,
height: (Dimensions.mapSize.height + 2 * Dimensions.mapPadding) * zoom)
- }.background(Color.ui.background)
+ }.background(Color.UI.background)
.gesture(
MagnificationGesture()
.onChanged { value in
value: $zoom, in: zoomRange, step: 0.1,
label: {
Text(formatZoom(zoom))
- .font(.theme.smallControl)
+ .font(.Theme.smallControl)
},
minimumValueLabel: {
Image(systemName: "minus.magnifyingglass")
- .font(.theme.smallControl)
+ .font(.Theme.smallControl)
.help("Zoom Out (⌘-)")
},
maximumValueLabel: {
Image(systemName: "plus.magnifyingglass")
- .font(.theme.smallControl)
+ .font(.Theme.smallControl)
.help("Zoom In (⌘+)")
}
).frame(width: 200).padding(.trailing, 10.0)