mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-01-11 11:50:26 +01:00
bug: fix color picker clipped by frame
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user