bug: fix color picker clipped by frame

This commit is contained in:
dscyrescotti
2024-11-26 02:47:30 +07:00
parent ba684a3459
commit b5287c0552
2 changed files with 90 additions and 12 deletions

View File

@@ -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<Color>) {
init(color: Binding<Color>, 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)

View File

@@ -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<Color>, 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()