Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 80 additions & 19 deletions Colorful/Classes/ColorPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@ public final class ColorPicker: UIControl {
return hsvColor.uiColor
}
}

public var isBrightnessSliderHidden: Bool {
set(hidden) {
setBrightness(hidden ? brightnessLevel : brightnessSlider.brightness)
brightnessSlider.isHidden = hidden
brightnessCursor.isHidden = hidden
layoutSubviews(withBrightnessSlider: !hidden)
layoutIfNeeded()
}
get {
return brightnessSlider.isHidden
}
}

public var brightnessLevel: CGFloat {
set(level) {
setBrightness(level)
}
get {
return hsvColor.brightness
}
}

private let brightnessCursor = BrightnessCursor()
private let brightnessSlider = BrightnessSlider()
Expand All @@ -27,6 +49,9 @@ public final class ColorPicker: UIControl {

private let feedbackGenerator = UISelectionFeedbackGenerator()

private var layoutWithBrightness: [NSLayoutConstraint] = []
private var layoutWithoutBrightness: [NSLayoutConstraint] = []

public override init(frame: CGRect) {
super.init(frame: frame)
setup()
Expand All @@ -42,6 +67,8 @@ public final class ColorPicker: UIControl {
addSubview(brightnessSlider)
addSubview(brightnessCursor)
addSubview(colorMapCursor)

setupConstraints()

let colorMapPan = UIPanGestureRecognizer(target: self, action: #selector(self.handleColorMapPan(pan:)))
colorMapPan.delegate = self
Expand All @@ -55,6 +82,40 @@ public final class ColorPicker: UIControl {

feedbackGenerator.prepare()
}

private func setupConstraints() {
colorMap.translatesAutoresizingMaskIntoConstraints = false
brightnessCursor.translatesAutoresizingMaskIntoConstraints = false
brightnessSlider.translatesAutoresizingMaskIntoConstraints = false

let margin: CGFloat = 12
let brightnessWidth: CGFloat = 72
let cursorHeight:CGFloat = 28

layoutWithBrightness = [
colorMap.topAnchor.constraint(equalTo: topAnchor, constant: margin),
colorMap.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -margin),
colorMap.leftAnchor.constraint(equalTo: leftAnchor, constant: margin),
colorMap.rightAnchor.constraint(equalTo: brightnessSlider.leftAnchor, constant: -margin),

brightnessSlider.widthAnchor.constraint(equalToConstant: brightnessWidth),
brightnessSlider.topAnchor.constraint(equalTo: topAnchor),
brightnessSlider.bottomAnchor.constraint(equalTo: bottomAnchor),
brightnessSlider.rightAnchor.constraint(equalTo: rightAnchor, constant: -margin),

brightnessCursor.centerYAnchor.constraint(equalTo: brightnessSlider.centerYAnchor),
brightnessCursor.centerXAnchor.constraint(equalTo: brightnessSlider.centerXAnchor),
brightnessCursor.heightAnchor.constraint(equalToConstant: cursorHeight),
brightnessCursor.widthAnchor.constraint(equalToConstant: brightnessWidth),
]

layoutWithoutBrightness = [
colorMap.topAnchor.constraint(equalTo: topAnchor, constant: margin),
colorMap.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -margin),
colorMap.leftAnchor.constraint(equalTo: leftAnchor, constant: margin),
colorMap.rightAnchor.constraint(equalTo: rightAnchor, constant: -margin),
]
}

public func set(color: UIColor, colorSpace: HRColorSpace) {
self.colorSpace = colorSpace
Expand All @@ -66,25 +127,21 @@ public final class ColorPicker: UIControl {
}

public override func layoutSubviews() {
self.layoutSubviews(withBrightnessSlider: !self.brightnessSlider.isHidden)
super.layoutSubviews()

let margin: CGFloat = 12
let brightnessSliderWidth: CGFloat = 72
let colorMapSize = min(bounds.width - brightnessSliderWidth - margin * 3, bounds.height - 2 * margin)

let colorMapX = (bounds.width - (colorMapSize + margin * 2 + brightnessSliderWidth)) / 2

colorMap.frame = CGRect(x: colorMapX, y: (bounds.height - colorMapSize)/2, width: colorMapSize + margin * 2, height: colorMapSize)
brightnessSlider.frame = CGRect(x: colorMap.frame.maxX, y: (bounds.height - colorMapSize)/2,
width: brightnessSliderWidth, height: colorMapSize)

let brightnessCursorSize = CGSize(width: brightnessSliderWidth, height: 28)
brightnessCursor.frame = CGRect(x: colorMap.frame.maxX,
y: (bounds.height - brightnessCursorSize.height)/2,
width: brightnessCursorSize.width, height: brightnessCursorSize.height)
mapColorToView(initialize: true)
}

private func layoutSubviews(withBrightnessSlider: Bool) {
if withBrightnessSlider {
NSLayoutConstraint.deactivate(layoutWithoutBrightness)
NSLayoutConstraint.activate(layoutWithBrightness)
} else {
NSLayoutConstraint.deactivate(layoutWithBrightness)
NSLayoutConstraint.activate(layoutWithoutBrightness)
}
}

private func mapColorToView(initialize: Bool = false) {
brightnessCursor.set(hsv: hsvColor)
colorMap.set(brightness: hsvColor.brightness)
Expand All @@ -96,6 +153,13 @@ public final class ColorPicker: UIControl {
}
}

private func setBrightness(_ brightness: CGFloat) {
hsvColor = hsvColor.hueAndSaturation.with(brightness: brightness)
mapColorToView()
feedbackIfNeeds()
sendActionIfNeeds()
}

@objc
private func handleColorMapPan(pan: UIPanGestureRecognizer) {
switch pan.state {
Expand Down Expand Up @@ -151,9 +215,6 @@ extension ColorPicker: UIGestureRecognizerDelegate {

extension ColorPicker: BrightnessSliderDelegate {
func handleBrightnessChanged(slider: BrightnessSlider) {
hsvColor = hsvColor.hueAndSaturation.with(brightness: slider.brightness)
mapColorToView()
feedbackIfNeeds()
sendActionIfNeeds()
setBrightness(slider.brightness)
}
}
Loading