diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-07-04 22:45:30 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-07-04 22:45:30 +0200 |
| commit | e21ead77ffdff206d1ae17e5ce93ea34c4227414 (patch) | |
| tree | 816908ddf90aaf99a6476ab364f8a13c193b99c4 /Map/Presentation | |
| parent | c843d34f56c207abcf4b93e424125eea2dc601e0 (diff) | |
Add new fonts and picker style.
Diffstat (limited to 'Map/Presentation')
22 files changed, 347 insertions, 154 deletions
diff --git a/Map/Presentation/Base Components/EvolutionPicker.swift b/Map/Presentation/Base Components/EvolutionPicker.swift deleted file mode 100644 index 2df4a7f..0000000 --- a/Map/Presentation/Base Components/EvolutionPicker.swift +++ /dev/null @@ -1,46 +0,0 @@ -// 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 EvolutionPicker: View { - - @Binding var selectedEvolution: StageType - - var body: some View { - Picker("Evolution", selection: $selectedEvolution) { - ForEach(StageType.types) { stage in - Text(Stage.title(stage)).font(.Theme.Body.regular).tag(stage).padding(4.0) - } - Divider() - ForEach(StageType.characteristics) { stage in - Text(Stage.title(stage)).font(.Theme.Body.regular).tag(stage).padding(4.0).font( - .Theme.Body.regular) - } - Divider() - ForEach(StageType.properties) { stage in - Text(Stage.title(stage)).font(.Theme.Body.regular).tag(stage).padding(4.0) - } - Divider() - ForEach(StageType.custom) { stage in - Text(Stage.title(stage)).font(.Theme.Body.regular).tag(stage).padding(4.0) - } - }.font(.Theme.Body.regular).padding(.horizontal, 8.0).padding(.vertical, 4.0) - } -} - -#Preview { - let selectedEvolution: StageType = .behavior - EvolutionPicker(selectedEvolution: .constant(selectedEvolution)) -} diff --git a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift new file mode 100644 index 0000000..5748e59 --- /dev/null +++ b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPicker.swift @@ -0,0 +1,89 @@ +// 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 EvolutionPicker: View { + + @State var isShowingMenu = false + @State var isHovered = false + @FocusState var isFocused: Bool + + @Binding var selectedEvolution: StageType + + var body: some View { + + Button( + action: { + isShowingMenu = !isShowingMenu + }, + label: { + HStack(spacing: Dimensions.Spacing.loose) { + Text(Stage.title(selectedEvolution)) + .font(.Theme.Body.emphasized) + .foregroundColor(isShowingMenu ? .Theme.UI.background : .Theme.UI.foreground) + ZStack { + Image(systemName: "chevron.up") + .resizable() + .scaledToFit() + .frame( + width: Dimensions.EvolutionPicker.controlSize, + height: Dimensions.EvolutionPicker.controlSize + ) + .offset(CGSize(width: 0, height: -Dimensions.EvolutionPicker.controlSpacing)) + .foregroundColor(isShowingMenu ? .Theme.UI.background : .Theme.UI.foreground) + Image(systemName: "chevron.down") + .resizable() + .scaledToFit() + .frame( + width: Dimensions.EvolutionPicker.controlSize, + height: Dimensions.EvolutionPicker.controlSize + ) + .offset(CGSize(width: 0, height: Dimensions.EvolutionPicker.controlSpacing)) + .foregroundColor(isShowingMenu ? .Theme.UI.background : .Theme.UI.foreground) + } + } + .padding(.horizontal, Dimensions.Spacing.regular) + .padding(.vertical, Dimensions.Spacing.cozy) + } + ) + .buttonStyle(.borderless) + .background(isShowingMenu ? Color.Theme.UI.foreground : Color.clear) + .cornerRadius(4.0) + .overlay( + RoundedRectangle(cornerRadius: 4.0) + .stroke( + isShowingMenu + ? Color.Theme.UI.foreground : (isHovered ? Color.Theme.UI.foreground : Color.clear), + lineWidth: 1) + ) + .onHover { hovering in + isHovered = hovering + } + .popover( + isPresented: $isShowingMenu, + content: { + EvolutionPickerMenu(selectedEvolution: $selectedEvolution) + } + ) + .onChange(of: selectedEvolution) { + isShowingMenu = false + } + } +} + +#Preview { + @Previewable @State var selectedEvolution: StageType = .behavior + EvolutionPicker(selectedEvolution: $selectedEvolution) +} diff --git a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift new file mode 100644 index 0000000..3a396aa --- /dev/null +++ b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenu.swift @@ -0,0 +1,81 @@ +import SwiftUI + +struct EvolutionPickerMenu: View { + + @Binding var selectedEvolution: StageType + + private func select(_ evolution: StageType) { + selectedEvolution = evolution + } + + var body: some View { + VStack(alignment: .leading, spacing: 1.0) { + Section(header: EvolutionPickerMenuHeader(key: "stage_type.section.types")) { + ForEach(StageType.types) { stage in + EvolutionPickerMenuItem(stage: stage, isSelected: selectedEvolution == stage) + .onTapGesture { + selectedEvolution = stage + } + } + } + Section(header: EvolutionPickerMenuHeader(key: "stage_type.section.characteristics")) { + ForEach(StageType.characteristics) { stage in + EvolutionPickerMenuItem(stage: stage, isSelected: selectedEvolution == stage) + .onTapGesture { + selectedEvolution = stage + } + } + } + Section(header: EvolutionPickerMenuHeader(key: "stage_type.section.general_properties")) { + ForEach(StageType.properties) { stage in + EvolutionPickerMenuItem(stage: stage, isSelected: selectedEvolution == stage) + .onTapGesture { + selectedEvolution = stage + } + } + } + Section(header: EvolutionPickerMenuHeader(key: "stage_type.section.other")) { + ForEach(StageType.custom) { stage in + EvolutionPickerMenuItem(stage: stage, isSelected: selectedEvolution == stage) + .onTapGesture { + selectedEvolution = stage + } + } + } + } + .padding(Dimensions.Spacing.coziest) + .ignoresSafeArea() + + } +} + +#Preview { + EvolutionPickerMenu(selectedEvolution: .constant(.ubiquity)) +} + +/* +Picker(selection: $selectedEvolution) { + Divider() + ForEach(StageType.characteristics) { stage in + Text(Stage.title(stage)) + .font(selectedEvolution == stage ? .Theme.Body.emphasized : .Theme.Body.regular) + .tag(stage) + } + Divider() + ForEach(StageType.properties) { stage in + Text(Stage.title(stage)) + .font(selectedEvolution == stage ? .Theme.Body.emphasized : .Theme.Body.regular) + .tag(stage) + } + Divider() + ForEach(StageType.custom) { stage in + Text(Stage.title(stage)) + .font(selectedEvolution == stage ? .Theme.Body.emphasized : .Theme.Body.regular) + .tag(stage) + } +} label: { + Label("evolution_picker.label", image: "Icons/Evolution") + .font(.Theme.Body.regular) +}.padding(.horizontal, Dimensions.Spacing.regular) + .padding(.vertical, Dimensions.Spacing.cozy) + */ diff --git a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenuHeader.swift b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenuHeader.swift new file mode 100644 index 0000000..b3eeb97 --- /dev/null +++ b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenuHeader.swift @@ -0,0 +1,26 @@ +import SwiftUI + +struct EvolutionPickerMenuHeader: View { + + let key: LocalizedStringKey + + var body: some View { + HStack(alignment: .center, spacing: Dimensions.Spacing.regular) { + Text(key) + .font(.Theme.Caption.emphasized) + .padding(.vertical, Dimensions.Spacing.cozy) + .textCase(.uppercase) + .padding(.leading, Dimensions.Spacing.regular) + .layoutPriority(1) + Spacer() + .frame(height: 1) + .background(Color.Theme.UI.foreground.opacity(0.2)) + } + .padding(.horizontal, Dimensions.Spacing.regular) + .cornerRadius(Dimensions.EvolutionPicker.radius) + } +} + +#Preview { + EvolutionPickerMenuHeader(key: "stage_type.section.types") +} diff --git a/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenuItem.swift b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenuItem.swift new file mode 100644 index 0000000..1731e8d --- /dev/null +++ b/Map/Presentation/Base Components/EvolutionPicker/EvolutionPickerMenuItem.swift @@ -0,0 +1,32 @@ +import SwiftUI + +struct EvolutionPickerMenuItem: View { + + @State var isHovered: Bool = false + + let stage: StageType + let isSelected: Bool + + var body: some View { + HStack(alignment: .center, spacing: Dimensions.Spacing.coziest) { + Image(systemName: "checkmark") + .opacity(isSelected ? 1.0 : 0.0) + .bold(true) + Text(Stage.title(stage)) + .font(isSelected ? .Theme.Body.emphasized : .Theme.Body.regular) + .padding(Dimensions.Spacing.cozy) + Spacer() + } + .padding(.horizontal, Dimensions.Spacing.regular) + .background(isHovered ? Color.Theme.UI.accent : Color.clear) + .cornerRadius(Dimensions.EvolutionPicker.radius) + .onHover { hovering in + isHovered = hovering + } + } +} + +#Preview { + EvolutionPickerMenuItem(stage: .behavior, isSelected: false) + EvolutionPickerMenuItem(stage: .ubiquity, isSelected: true) +} diff --git a/Map/Presentation/Base Components/MapRender/MapAxes.swift b/Map/Presentation/Base Components/MapRender/MapAxes.swift index 1c0a147..48e0b6d 100644 --- a/Map/Presentation/Base Components/MapRender/MapAxes.swift +++ b/Map/Presentation/Base Components/MapRender/MapAxes.swift @@ -33,52 +33,54 @@ struct MapAxes: View { path.addLine(to: CGPoint(x: mapSize.width, y: mapSize.height)) path.move(to: CGPoint(x: mapSize.width, y: mapSize.height)) path.closeSubpath() - }.stroke(Color.Map.axisColor, lineWidth: lineWidth * 2) + }.stroke(Color.Theme.Map.axisColor, lineWidth: lineWidth * 2) // Y Labels - Text("Visible").font(.Theme.Map.axisLabel).foregroundColor(.Map.labelColor).rotationEffect( - Angle(degrees: -90.0) - ) - .offset(CGSize(width: -35.0, height: 0.0)) - Text("Invisible").font(.Theme.Map.axisLabel).foregroundColor(.Map.labelColor).rotationEffect( - Angle(degrees: -90.0) - ) - .offset(CGSize(width: -40.0, height: mapSize.height - 20)) + Text("Visible").font(.Theme.Map.axisLabel).foregroundColor(.Theme.Map.labelColor) + .rotationEffect( + Angle(degrees: -90.0) + ) + .offset(CGSize(width: -35.0, height: 0.0)) + Text("Invisible").font(.Theme.Map.axisLabel).foregroundColor(.Theme.Map.labelColor) + .rotationEffect( + Angle(degrees: -90.0) + ) + .offset(CGSize(width: -40.0, height: mapSize.height - 20)) // X Labels Text("Uncharted") .font(.Theme.Map.axisLabel) - .foregroundColor(.Map.labelColor) + .foregroundColor(.Theme.Map.labelColor) .frame(width: mapSize.width / 4, height: stageHeight / 2.0, alignment: .topLeading) .offset(CGSize(width: 0.0, height: -stageHeight / 4.0)) Text("Industrialised") .font(.Theme.Map.axisLabel) - .foregroundColor(.Map.labelColor) + .foregroundColor(.Theme.Map.labelColor) .frame(width: mapSize.width / 4, height: stageHeight / 2.0, alignment: .topLeading) .offset(CGSize(width: mapSize.width - 100.0, height: -stageHeight / 4.0)) Text(evolution.i) .font(.Theme.Map.axisLabel) - .foregroundColor(.Map.labelColor) + .foregroundColor(.Theme.Map.labelColor) .frame(width: w(stages[0]), height: stageHeight, alignment: .topLeading) .offset(CGSize(width: 0.0, height: mapSize.height + padding)) Text(evolution.ii) .font(.Theme.Map.axisLabel) - .foregroundColor(.Map.labelColor) + .foregroundColor(.Theme.Map.labelColor) .frame(width: w(stages[1]) - w(stages[0]), height: stageHeight, alignment: .topLeading) .offset(CGSize(width: w(stages[0]), height: mapSize.height + padding)) Text(evolution.iii) .font(.Theme.Map.axisLabel) - .foregroundColor(.Map.labelColor) + .foregroundColor(.Theme.Map.labelColor) .frame(width: w(stages[2]) - w(stages[1]), height: stageHeight, alignment: .topLeading) .offset(CGSize(width: w(stages[1]), height: mapSize.height + padding)) Text(evolution.iv) .font(.Theme.Map.axisLabel) - .foregroundColor(.Map.labelColor) + .foregroundColor(.Theme.Map.labelColor) .frame(width: mapSize.width - w(stages[2]), height: stageHeight, alignment: .topLeading) .offset(CGSize(width: w(stages[2]), height: mapSize.height + padding)) } diff --git a/Map/Presentation/Base Components/MapRender/MapBlockers.swift b/Map/Presentation/Base Components/MapRender/MapBlockers.swift index 613b792..e550ca9 100644 --- a/Map/Presentation/Base Components/MapRender/MapBlockers.swift +++ b/Map/Presentation/Base Components/MapRender/MapBlockers.swift @@ -32,7 +32,7 @@ struct MapBlockers: View { y: h(vertex.position.y) - vertexSize.height * 2 / 3), size: CGSize(width: vertexSize.width / 2, height: vertexSize.height * 2) ), cornerSize: cornerSize) - }.fill(Color.Map.blockerColor) + }.fill(Color.Theme.Map.blockerColor) } } diff --git a/Map/Presentation/Base Components/MapRender/MapEdges.swift b/Map/Presentation/Base Components/MapRender/MapEdges.swift index 3090c04..3c6ef82 100644 --- a/Map/Presentation/Base Components/MapRender/MapEdges.swift +++ b/Map/Presentation/Base Components/MapRender/MapEdges.swift @@ -66,7 +66,7 @@ struct MapEdges: View { path.closeSubpath() }.applying( CGAffineTransform(translationX: vertexSize.width / 2.0, y: vertexSize.height / 2.0) - ).stroke(Color.Map.vertexColor, lineWidth: lineWidth) + ).stroke(Color.Theme.Map.vertexColor, lineWidth: lineWidth) } } diff --git a/Map/Presentation/Base Components/MapRender/MapGroups.swift b/Map/Presentation/Base Components/MapRender/MapGroups.swift index 41ea147..1983dcd 100644 --- a/Map/Presentation/Base Components/MapRender/MapGroups.swift +++ b/Map/Presentation/Base Components/MapRender/MapGroups.swift @@ -28,7 +28,7 @@ struct MapGroups: View { } private func color(_ index: Int) -> Color { - return .Map.groupColors[index % Color.Map.groupColors.count] + return .Theme.Map.groupColors[index % Color.Theme.Map.groupColors.count] } } diff --git a/Map/Presentation/Base Components/MapRender/MapNotes.swift b/Map/Presentation/Base Components/MapRender/MapNotes.swift index 16c61ba..20aa1e1 100644 --- a/Map/Presentation/Base Components/MapRender/MapNotes.swift +++ b/Map/Presentation/Base Components/MapRender/MapNotes.swift @@ -29,8 +29,8 @@ struct MapNotes: View { .lineSpacing(Dimensions.LineHeight.Map.note - Dimensions.FontSize.Map.note) .padding(Dimensions.Spacing.cozy) .background(.white) - .foregroundColor(.Map.labelColor) - .border(Color.Map.vertexColor, width: lineWidth) + .foregroundColor(.Theme.Map.labelColor) + .border(Color.Theme.Map.vertexColor, width: lineWidth) .frame(minWidth: 16.0, maxWidth: maxWidth, alignment: .topLeading) .offset( CGSize( diff --git a/Map/Presentation/Base Components/MapRender/MapOpportunities.swift b/Map/Presentation/Base Components/MapRender/MapOpportunities.swift index 3d539d4..04d4b40 100644 --- a/Map/Presentation/Base Components/MapRender/MapOpportunities.swift +++ b/Map/Presentation/Base Components/MapRender/MapOpportunities.swift @@ -61,7 +61,7 @@ struct MapOpportunities: View { }.applying( CGAffineTransform(translationX: vertexSize.width / 2.0, y: vertexSize.height / 2.0) ).strokedPath(StrokeStyle(lineWidth: lineWidth / 4, dash: [10.0])).stroke( - Color.Map.opportunityColor) + Color.Theme.Map.opportunityColor) } } diff --git a/Map/Presentation/Base Components/MapRender/MapStages.swift b/Map/Presentation/Base Components/MapRender/MapStages.swift index d5e5965..08250f7 100644 --- a/Map/Presentation/Base Components/MapRender/MapStages.swift +++ b/Map/Presentation/Base Components/MapRender/MapStages.swift @@ -25,25 +25,25 @@ struct MapStages: View { var body: some View { ZStack(alignment: .topLeading) { PatternView( - design: .constant(.stitch), pixelSize: 1.0, foregroundColor: .Map.stageForeground, - backgroundColor: .Map.stageBackground + design: .constant(.stitch), pixelSize: 1.0, foregroundColor: .Theme.Map.stageForeground, + backgroundColor: .Theme.Map.stageBackground ) .frame(width: w(stages[0]), height: mapSize.height) PatternView( - design: .constant(.shingles), pixelSize: 1.0, foregroundColor: .Map.stageForeground, - backgroundColor: .Map.stageBackground + design: .constant(.shingles), pixelSize: 1.0, foregroundColor: .Theme.Map.stageForeground, + backgroundColor: .Theme.Map.stageBackground ) .offset(CGSize(width: w(stages[0]), height: 0)) .frame(width: w(stages[1]) - w(stages[0]), height: mapSize.height) PatternView( - design: .constant(.shadowGrid), pixelSize: 1.0, foregroundColor: .Map.stageForeground, - backgroundColor: .Map.stageBackground + design: .constant(.shadowGrid), pixelSize: 1.0, foregroundColor: .Theme.Map.stageForeground, + backgroundColor: .Theme.Map.stageBackground ) .offset(CGSize(width: w(stages[1]), height: 0)) .frame(width: w(stages[2]) - w(stages[1]), height: mapSize.height) PatternView( - design: .constant(.wicker), pixelSize: 1.0, foregroundColor: .Map.stageForeground, - backgroundColor: .Map.stageBackground + design: .constant(.wicker), pixelSize: 1.0, foregroundColor: .Theme.Map.stageForeground, + backgroundColor: .Theme.Map.stageBackground ) .offset(CGSize(width: w(stages[2]), height: 0)) .frame(width: mapSize.width - w(stages[2]), height: mapSize.height) @@ -61,7 +61,7 @@ struct MapStages: View { path.move(to: CGPoint(x: w(stages[0]), y: 0)) path.closeSubpath() }.strokedPath(StrokeStyle(lineWidth: lineWidth / 4, dash: [10.0, 18.0])).stroke( - Color.Map.axisColor) + Color.Theme.Map.axisColor) } } diff --git a/Map/Presentation/Base Components/MapRender/MapVertices.swift b/Map/Presentation/Base Components/MapRender/MapVertices.swift index 1f6cf1a..4f130c6 100644 --- a/Map/Presentation/Base Components/MapRender/MapVertices.swift +++ b/Map/Presentation/Base Components/MapRender/MapVertices.swift @@ -27,13 +27,13 @@ struct MapVertices: View { ZStack(alignment: .topLeading) { ForEach(vertices, id: \.id) { vertex in ZStack(alignment: .topLeading) { - getVertexShape(vertex).fill(Color.Map.vertexColor) + getVertexShape(vertex).fill(Color.Theme.Map.vertexColor) Text(vertex.label.replacingOccurrences(of: "\\n", with: "\n")) .font(.Theme.Map.vertexLabel) .lineSpacing( Dimensions.LineHeight.Map.vertexLabel - Dimensions.FontSize.Map.vertexLabel ) - .foregroundColor(.Map.labelColor) + .foregroundColor(.Theme.Map.labelColor) .shadow(color: .white, radius: 0, x: -0.5, y: -0.5) .shadow(color: .white, radius: 0, x: 0.5, y: 0.5) .offset( diff --git a/Map/Presentation/Base Components/MapTextEditor.swift b/Map/Presentation/Base Components/MapTextEditor.swift index 3c5c824..18b2fbc 100644 --- a/Map/Presentation/Base Components/MapTextEditor.swift +++ b/Map/Presentation/Base Components/MapTextEditor.swift @@ -64,7 +64,7 @@ class MapTextEditorController: NSViewController { scrollView.translatesAutoresizingMaskIntoConstraints = false - textView.backgroundColor = .UI.background + textView.backgroundColor = .Theme.UI.background textView.allowsUndo = true textView.delegate = self textView.textStorage?.delegate = self @@ -92,7 +92,9 @@ class MapTextEditorController: NSViewController { for (index, range) in highlightRanges.enumerated() { let nsRange = NSRange(range, in: textStorage.string) - let color = index == selectedRange ? NSColor.Syntax.highlightMatch : NSColor.Syntax.match + let color = + index == selectedRange + ? NSColor.Theme.Syntax.highlightMatch : NSColor.Theme.Syntax.match textStorage.addAttribute(.backgroundColor, value: color, range: nsRange) } @@ -156,77 +158,77 @@ extension MapTextEditorController: NSTextStorageDelegate { for match in matches { textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.vertex], range: match.range(at: 1)) + [.foregroundColor: NSColor.Theme.Syntax.vertex], range: match.range(at: 1)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.number], range: match.range(at: 2)) + [.foregroundColor: NSColor.Theme.Syntax.number], range: match.range(at: 2)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.number], range: match.range(at: 3)) + [.foregroundColor: NSColor.Theme.Syntax.number], range: match.range(at: 3)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.option], range: match.range(at: 4)) + [.foregroundColor: NSColor.Theme.Syntax.option], range: match.range(at: 4)) } matches = edgeRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.vertex], range: match.range(at: 1)) + [.foregroundColor: NSColor.Theme.Syntax.vertex], range: match.range(at: 1)) let arrowRange = match.range(at: 2) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.symbol], + [.foregroundColor: NSColor.Theme.Syntax.symbol], range: NSMakeRange(arrowRange.lowerBound - 1, arrowRange.length + 1)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.vertex], range: match.range(at: 3)) + [.foregroundColor: NSColor.Theme.Syntax.vertex], range: match.range(at: 3)) } matches = opportunityRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.option], range: match.range(at: 1)) + [.foregroundColor: NSColor.Theme.Syntax.option], range: match.range(at: 1)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.vertex], range: match.range(at: 2)) + [.foregroundColor: NSColor.Theme.Syntax.vertex], range: match.range(at: 2)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.symbol], range: match.range(at: 3)) + [.foregroundColor: NSColor.Theme.Syntax.symbol], range: match.range(at: 3)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.number], range: match.range(at: 4)) + [.foregroundColor: NSColor.Theme.Syntax.number], range: match.range(at: 4)) } matches = blockerRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.option], range: match.range(at: 1)) + [.foregroundColor: NSColor.Theme.Syntax.option], range: match.range(at: 1)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.vertex], range: match.range(at: 2)) + [.foregroundColor: NSColor.Theme.Syntax.vertex], range: match.range(at: 2)) } matches = noteRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.option], range: match.range(at: 1)) + [.foregroundColor: NSColor.Theme.Syntax.option], range: match.range(at: 1)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.number], range: match.range(at: 2)) + [.foregroundColor: NSColor.Theme.Syntax.number], range: match.range(at: 2)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.number], range: match.range(at: 3)) + [.foregroundColor: NSColor.Theme.Syntax.number], range: match.range(at: 3)) } matches = stageRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.option], range: match.range(at: 1)) + [.foregroundColor: NSColor.Theme.Syntax.option], range: match.range(at: 1)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.number], range: match.range(at: 2)) + [.foregroundColor: NSColor.Theme.Syntax.number], range: match.range(at: 2)) } matches = groupRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.option], range: match.range(at: 1)) + [.foregroundColor: NSColor.Theme.Syntax.option], range: match.range(at: 1)) textStorage.addAttributes( - [.foregroundColor: NSColor.Syntax.vertex], range: match.range(at: 2)) + [.foregroundColor: NSColor.Theme.Syntax.vertex], range: match.range(at: 2)) } } } diff --git a/Map/Presentation/MapEditor.swift b/Map/Presentation/MapEditor.swift index 1e25ce8..5dc1adb 100644 --- a/Map/Presentation/MapEditor.swift +++ b/Map/Presentation/MapEditor.swift @@ -92,11 +92,12 @@ struct MapEditor: View { adaptiveStack { ZStack(alignment: .topLeading) { MapTextEditor(document: $document, highlightRanges: results, selectedRange: selectedTerm) - .background(Color.UI.background) - .foregroundColor(Color.UI.foreground) + .background(Color.Theme.UI.background) + .foregroundColor(Color.Theme.UI.foreground) .frame(minHeight: 96.0) - }.padding(.top, 8.0).padding(.leading, 8.0).background(Color.UI.background).cornerRadius( - 5.0) + } + .background(Color.Theme.UI.background) + .cornerRadius(5.0) GeometryReader { geometry in ScrollView([.horizontal, .vertical]) { MapRenderView( @@ -104,7 +105,7 @@ struct MapEditor: View { ).scaleEffect(zoom, anchor: .center).frame( width: (Dimensions.Map.size.width + 2 * Dimensions.Map.padding) * zoom, height: (Dimensions.Map.size.height + 2 * Dimensions.Map.padding) * zoom) - }.background(Color.UI.background) + }.background(Color.Theme.UI.background) .gesture( MagnificationGesture() .onChanged { value in @@ -140,11 +141,12 @@ struct MapEditor: View { ).frame(width: 200).padding(.trailing, 10.0) }.padding(4.0) }.toolbar { - HStack { + ToolbarItem(placement: .primaryAction) { EvolutionPicker(selectedEvolution: $selectedEvolution) } - }.focusedSceneValue(\.isSearching, $isSearching) - .focusedSceneValue(\.selectedEvolution, $selectedEvolution) + } + .focusedSceneValue(\.isSearching, $isSearching) + .focusedSceneValue(\.selectedEvolution, $selectedEvolution) } @ViewBuilder @@ -173,5 +175,5 @@ struct MapEditor: View { } #Preview { - MapEditor(document: .constant(MapDocument()), url: URL(filePath: "test.png")!) + MapEditor(document: .constant(MapDocument()), url: URL(filePath: "test.wmap")!) } diff --git a/Map/Presentation/Theme/Color+theme.swift b/Map/Presentation/Theme/Color+theme.swift index ee80e82..22dc18b 100644 --- a/Map/Presentation/Theme/Color+theme.swift +++ b/Map/Presentation/Theme/Color+theme.swift @@ -29,31 +29,32 @@ extension Color { static let lightNeutralGray = Color("Light Neutral Gray") static let darkNeutralGray = Color("Dark Neutral Gray") static let darkerNeutralGray = Color("Darker Neutral Gray") - } - // MARK: - General + // MARK: - General - struct UI { - static let foreground = Color("Foreground") - static let background = Color("Background") - } + struct UI { + static let foreground = Color("Foreground") + static let background = Color("Background") + static let accent = Color.Theme.jasperRed + } - // MARK: - The Map + // MARK: - The Map - struct Map { - static let labelColor = Color.Theme.darkSlate - static let axisColor = Color.Theme.darkSlate - static let vertexColor = Color.Theme.darkSlate - static let blockerColor = Color.Theme.jasperRed - static let opportunityColor = Color.Theme.olympicBlue - static let stageForeground = Color.Theme.lightNeutralGray - static let stageBackground = Color.white - static let groupColors = [ - Color.Theme.olympicBlue, - Color.Theme.jasperRed, - Color.Theme.lightPorcelainGreen, - Color.Theme.naplesYellow, - Color.Theme.hermosaPink, - ] + struct Map { + static let labelColor = Color.Theme.darkSlate + static let axisColor = Color.Theme.darkSlate + static let vertexColor = Color.Theme.darkSlate + static let blockerColor = Color.Theme.jasperRed + static let opportunityColor = Color.Theme.olympicBlue + static let stageForeground = Color.Theme.lightNeutralGray + static let stageBackground = Color.white + static let groupColors = [ + Color.Theme.olympicBlue, + Color.Theme.jasperRed, + Color.Theme.lightPorcelainGreen, + Color.Theme.naplesYellow, + Color.Theme.hermosaPink, + ] + } } } diff --git a/Map/Presentation/Theme/Dimensions.swift b/Map/Presentation/Theme/Dimensions.swift index 2e1fd69..7df3f1a 100644 --- a/Map/Presentation/Theme/Dimensions.swift +++ b/Map/Presentation/Theme/Dimensions.swift @@ -19,10 +19,10 @@ struct Dimensions { // MARK: - Fonts struct FontSize { - static let body: CGFloat = 16 + static let body: CGFloat = 15 static let title: CGFloat = 32 - static let caption: CGFloat = 14 - static let smallControl: CGFloat = 9 + static let caption: CGFloat = 13 + static let smallControl: CGFloat = 11 struct Map { static let note: CGFloat = 12 @@ -55,8 +55,16 @@ struct Dimensions { } // MARK: - The Map + struct Map { static let size = CGSize(width: 1300.0, height: 1000.0) static let padding: CGFloat = 42.0 } + + // MARK: - Assorted Controls + struct EvolutionPicker { + static let radius = 8.0 + static let controlSize = 8.0 + static let controlSpacing = 3.0 + } } diff --git a/Map/Presentation/Theme/Font+theme.swift b/Map/Presentation/Theme/Font+theme.swift index 2fb56f7..cc80fc4 100644 --- a/Map/Presentation/Theme/Font+theme.swift +++ b/Map/Presentation/Theme/Font+theme.swift @@ -24,17 +24,8 @@ extension Font { return .custom("Ronzino", size: size) } - static func ronzinoMedium(size: CGFloat) -> Font { - return .custom("RonzinoMedium", size: size) - } - public struct Theme { - // Map - static let note = Font.system(size: 12, design: .serif) - static let axisLabel = Font.system(size: 14, design: .serif) - static let vertexLabel = Font.system(size: 12, design: .serif) - struct Body { static let regular = Font.ronzino(size: Dimensions.FontSize.body).weight(.regular) static let emphasized = Font.ronzino(size: Dimensions.FontSize.body).weight(.medium) @@ -51,6 +42,7 @@ extension Font { struct SmallControl { static let regular = Font.ronzino(size: Dimensions.FontSize.smallControl).weight(.regular) + static let emphasized = Font.ronzino(size: Dimensions.FontSize.smallControl).weight(.medium) } struct Map { diff --git a/Map/Presentation/Theme/LibertinusSerif-Regular.otf b/Map/Presentation/Theme/Fonts/LibertinusSerif-Regular.otf Binary files differindex 508f3c0..508f3c0 100644 --- a/Map/Presentation/Theme/LibertinusSerif-Regular.otf +++ b/Map/Presentation/Theme/Fonts/LibertinusSerif-Regular.otf diff --git a/Map/Presentation/Theme/Ronzino-Medium.otf b/Map/Presentation/Theme/Fonts/Ronzino-Medium.otf Binary files differindex 0be8dd5..0be8dd5 100644 --- a/Map/Presentation/Theme/Ronzino-Medium.otf +++ b/Map/Presentation/Theme/Fonts/Ronzino-Medium.otf diff --git a/Map/Presentation/Theme/Ronzino-Regular.otf b/Map/Presentation/Theme/Fonts/Ronzino-Regular.otf Binary files differindex 8b70471..8b70471 100644 --- a/Map/Presentation/Theme/Ronzino-Regular.otf +++ b/Map/Presentation/Theme/Fonts/Ronzino-Regular.otf diff --git a/Map/Presentation/Theme/NSColor+theme.swift b/Map/Presentation/Theme/NSColor+theme.swift index 61b5498..874764d 100644 --- a/Map/Presentation/Theme/NSColor+theme.swift +++ b/Map/Presentation/Theme/NSColor+theme.swift @@ -15,17 +15,21 @@ import AppKit extension NSColor { - struct Syntax { - static let vertex = NSColor(named: "Vertex") ?? .textColor - static let number = NSColor(named: "Number") ?? .textColor - static let option = NSColor(named: "Option") ?? .textColor - static let symbol = NSColor(named: "Symbol") ?? .textColor - static let match = (NSColor(named: "Light Neutral Gray") ?? .textColor).withAlphaComponent(0.3) - static let highlightMatch = (NSColor(named: "Naples Yellow") ?? .textColor).withAlphaComponent( - 0.3) - } + struct Theme { + struct Syntax { + static let vertex = NSColor(named: "Vertex") ?? .textColor + static let number = NSColor(named: "Number") ?? .textColor + static let option = NSColor(named: "Option") ?? .textColor + static let symbol = NSColor(named: "Symbol") ?? .textColor + static let match = (NSColor(named: "Light Neutral Gray") ?? .textColor).withAlphaComponent( + 0.3) + static let highlightMatch = (NSColor(named: "Naples Yellow") ?? .textColor) + .withAlphaComponent( + 0.3) + } - struct UI { - static let background = NSColor(named: "Background") ?? .windowBackgroundColor + struct UI { + static let background = NSColor(named: "Background") ?? .windowBackgroundColor + } } } |