diff --git a/Memola/Components/Views/ColorPicker/ColorPicker.swift b/Memola/Components/Views/ColorPicker/ColorPicker.swift index 5346e61..0011e76 100644 --- a/Memola/Components/Views/ColorPicker/ColorPicker.swift +++ b/Memola/Components/Views/ColorPicker/ColorPicker.swift @@ -9,6 +9,8 @@ import SwiftUI import Foundation struct ColorPicker: View { + @Environment(\.horizontalSizeClass) private var horizontalSizeClass + @State private var hue: Double = 1 @State private var saturation: Double = 0 @State private var brightness: Double = 1 @@ -16,16 +18,32 @@ struct ColorPicker: View { @Binding private var color: Color - private let size: CGFloat = 20 + private let isCompact: Bool + private let boundSize: CGFloat + private let size: CGFloat = 25 - init(color: Binding) { + init(color: Binding, boundSize: CGFloat, isCompact: Bool = false) { self._color = color + self.isCompact = isCompact + self.boundSize = boundSize } var body: some View { - VStack(spacing: 10) { + #if os(macOS) + colorPicker + #else + if horizontalSizeClass == .regular { colorPicker - .frame(width: 200, height: 200) + } else { + compactColorPicker + } + #endif + } + + private var colorPicker: some View { + VStack(spacing: 10) { + colorPalette + .frame(width: boundSize, height: boundSize) HStack(spacing: 10) { hueSlider alphaSlider @@ -47,7 +65,29 @@ struct ColorPicker: View { } @ViewBuilder - private var colorPicker: some View { + private var compactColorPicker: some View { + let padding: CGFloat = 30 + (isCompact ? size * 2 + 10 : 0) + VStack(spacing: 10) { + colorPalette + .frame(width: boundSize - padding, height: boundSize - padding) + HStack(spacing: 10) { + hueSlider + alphaSlider + } + } + .padding(15) + .padding(.top, 10) + .onAppear { + let hsba = color.hsba + hue = hsba.hue + saturation = hsba.saturation + brightness = hsba.brightness + alpha = hsba.alpha * 1.43 - 0.43 + } + } + + @ViewBuilder + private var colorPalette: some View { GeometryReader { proxy in ZStack { Color(hue: hue, saturation: 1, brightness: 1) diff --git a/Memola/Features/Memo/PenDock/PenDock.swift b/Memola/Features/Memo/PenDock/PenDock.swift index 3079abe..4ba4bbd 100644 --- a/Memola/Features/Memo/PenDock/PenDock.swift +++ b/Memola/Features/Memo/PenDock/PenDock.swift @@ -67,7 +67,7 @@ struct PenDock: View { compactPenItemList .fixedSize(horizontal: false, vertical: true) HStack(spacing: 0) { - compactPenPropertyTool + compactPenPropertyTool(bounds: proxy.frame(in: .global).size) Divider() .padding(.vertical, 4) .frame(height: size) @@ -360,9 +360,10 @@ struct PenDock: View { @ViewBuilder private var penPropertyTool: some View { if let pen = tool.selectedPen { + let size: CGFloat = 250 VStack(spacing: 5) { if pen.strokeStyle == .marker { - penColorPicker(pen) + penColorPicker(pen, bounds: .init(width: size, height: size)) } penThicknessPicker(pen) } @@ -379,14 +380,14 @@ struct PenDock: View { } @ViewBuilder - private var compactPenPropertyTool: some View { + private func compactPenPropertyTool(bounds: CGSize) -> some View { if let pen = tool.selectedPen { HStack(spacing: 8) { penThicknessPicker(pen) .frame(width: penPropertySize) .rotationEffect(.degrees(-90)) if pen.strokeStyle == .marker { - penColorPicker(pen) + penColorPicker(pen, bounds: bounds) .frame(width: penPropertySize) .transition(.move(edge: .trailing).combined(with: .opacity)) } @@ -395,7 +396,7 @@ struct PenDock: View { } } - private func penColorPicker(_ pen: Pen) -> some View { + private func penColorPicker(_ pen: Pen, bounds: CGSize) -> some View { Button { opensColorPicker = true } label: { @@ -437,8 +438,45 @@ struct PenDock: View { tool.objectWillChange.send() } ) - ColorPicker(color: color) - .presentationCompactAdaptation(.popover) + #if os(macOS) + ColorPicker(color: color, boundSize: min(bounds.height, bounds.width)) + .onDisappear { + withPersistence(\.viewContext) { context in + try context.saveIfNeeded() + } + } + #else + if horizontalSizeClass == .regular { + ColorPicker(color: color, boundSize: min(bounds.height, bounds.width)) + .onDisappear { + withPersistence(\.viewContext) { context in + try context.saveIfNeeded() + } + } + } else { + compactColorPicker(color: color, bounds: bounds) + } + #endif + } + } + + @ViewBuilder + func compactColorPicker(color: Binding, bounds: CGSize) -> some View { + let size = min(bounds.height, bounds.width) + if bounds.height > bounds.width { + ColorPicker(color: color, boundSize: size) + .presentationDetents([.height(size + 40)]) + .presentationDragIndicator(.visible) + .onDisappear { + withPersistence(\.viewContext) { context in + try context.saveIfNeeded() + } + } + } else { + ColorPicker(color: color, boundSize: size, isCompact: true) + .presentationCompactAdaptation(.sheet) + .presentationDetents([.large]) + .presentationDragIndicator(.visible) .onDisappear { withPersistence(\.viewContext) { context in try context.saveIfNeeded()