Prepare v0.4 release and open source docs
This commit is contained in:
180
Sources/IHatePDFs/ReaderAdaptiveLayout.swift
Normal file
180
Sources/IHatePDFs/ReaderAdaptiveLayout.swift
Normal file
@@ -0,0 +1,180 @@
|
||||
import CoreGraphics
|
||||
|
||||
struct ReaderAdaptiveLayout: Equatable {
|
||||
enum SizeClass: String, CaseIterable {
|
||||
case compact
|
||||
case regular
|
||||
case wide
|
||||
|
||||
init(width: CGFloat) {
|
||||
if width < 960 {
|
||||
self = .compact
|
||||
} else if width < 1280 {
|
||||
self = .regular
|
||||
} else {
|
||||
self = .wide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SidebarWidths: Equatable {
|
||||
var left: CGFloat
|
||||
var right: CGFloat
|
||||
}
|
||||
|
||||
static let minimumWindowWidth: CGFloat = 820
|
||||
static let minimumWindowHeight: CGFloat = 620
|
||||
static let resizeHandleWidth: CGFloat = 16
|
||||
|
||||
let sizeClass: SizeClass
|
||||
|
||||
init(width: CGFloat) {
|
||||
sizeClass = SizeClass(width: width)
|
||||
}
|
||||
|
||||
init(sizeClass: SizeClass) {
|
||||
self.sizeClass = sizeClass
|
||||
}
|
||||
|
||||
var usesCompactToolbar: Bool {
|
||||
sizeClass == .compact
|
||||
}
|
||||
|
||||
var allowsDualSidebars: Bool {
|
||||
sizeClass != .compact
|
||||
}
|
||||
|
||||
var leftSidebarMinWidth: CGFloat {
|
||||
switch sizeClass {
|
||||
case .compact:
|
||||
return 208
|
||||
case .regular:
|
||||
return 196
|
||||
case .wide:
|
||||
return 220
|
||||
}
|
||||
}
|
||||
|
||||
var leftSidebarIdealWidth: CGFloat {
|
||||
switch sizeClass {
|
||||
case .compact:
|
||||
return 236
|
||||
case .regular:
|
||||
return 215
|
||||
case .wide:
|
||||
return 248
|
||||
}
|
||||
}
|
||||
|
||||
var leftSidebarMaxWidth: CGFloat {
|
||||
switch sizeClass {
|
||||
case .compact:
|
||||
return 300
|
||||
case .regular:
|
||||
return 280
|
||||
case .wide:
|
||||
return 340
|
||||
}
|
||||
}
|
||||
|
||||
var rightSidebarMinWidth: CGFloat {
|
||||
switch sizeClass {
|
||||
case .compact:
|
||||
return 280
|
||||
case .regular:
|
||||
return 280
|
||||
case .wide:
|
||||
return 300
|
||||
}
|
||||
}
|
||||
|
||||
var rightSidebarIdealWidth: CGFloat {
|
||||
switch sizeClass {
|
||||
case .compact:
|
||||
return 292
|
||||
case .regular:
|
||||
return 300
|
||||
case .wide:
|
||||
return 340
|
||||
}
|
||||
}
|
||||
|
||||
var rightSidebarMaxWidth: CGFloat {
|
||||
switch sizeClass {
|
||||
case .compact:
|
||||
return 340
|
||||
case .regular:
|
||||
return 360
|
||||
case .wide:
|
||||
return 420
|
||||
}
|
||||
}
|
||||
|
||||
var documentMinWidth: CGFloat {
|
||||
switch sizeClass {
|
||||
case .compact:
|
||||
return 320
|
||||
case .regular:
|
||||
return 420
|
||||
case .wide:
|
||||
return 560
|
||||
}
|
||||
}
|
||||
|
||||
func clampedLeftWidth(_ width: CGFloat) -> CGFloat {
|
||||
clamped(width, lower: leftSidebarMinWidth, upper: leftSidebarMaxWidth)
|
||||
}
|
||||
|
||||
func clampedRightWidth(_ width: CGFloat) -> CGFloat {
|
||||
clamped(width, lower: rightSidebarMinWidth, upper: rightSidebarMaxWidth)
|
||||
}
|
||||
|
||||
func resolvedSidebarWidths(
|
||||
availableWidth: CGFloat,
|
||||
requestedLeft: CGFloat,
|
||||
requestedRight: CGFloat,
|
||||
showLeft: Bool,
|
||||
showRight: Bool
|
||||
) -> SidebarWidths {
|
||||
let leftHandle = showLeft ? Self.resizeHandleWidth : 0
|
||||
let rightHandle = showRight ? Self.resizeHandleWidth : 0
|
||||
let maxSidebarTotal = max(0, availableWidth - documentMinWidth - leftHandle - rightHandle)
|
||||
|
||||
var left = showLeft ? clampedLeftWidth(requestedLeft) : 0
|
||||
var right = showRight ? clampedRightWidth(requestedRight) : 0
|
||||
|
||||
guard left + right > maxSidebarTotal else {
|
||||
return SidebarWidths(left: left, right: right)
|
||||
}
|
||||
|
||||
var overflow = left + right - maxSidebarTotal
|
||||
if showRight {
|
||||
let reduction = min(overflow, max(0, right - rightSidebarMinWidth))
|
||||
right -= reduction
|
||||
overflow -= reduction
|
||||
}
|
||||
|
||||
if showLeft, overflow > 0 {
|
||||
let reduction = min(overflow, max(0, left - leftSidebarMinWidth))
|
||||
left -= reduction
|
||||
}
|
||||
|
||||
return SidebarWidths(left: left, right: right)
|
||||
}
|
||||
|
||||
func visibleContentWidth(
|
||||
availableWidth: CGFloat,
|
||||
leftWidth: CGFloat,
|
||||
rightWidth: CGFloat,
|
||||
showLeft: Bool,
|
||||
showRight: Bool
|
||||
) -> CGFloat {
|
||||
let leftHandle = showLeft ? Self.resizeHandleWidth : 0
|
||||
let rightHandle = showRight ? Self.resizeHandleWidth : 0
|
||||
return availableWidth - leftWidth - rightWidth - leftHandle - rightHandle
|
||||
}
|
||||
|
||||
private func clamped(_ value: CGFloat, lower: CGFloat, upper: CGFloat) -> CGFloat {
|
||||
min(max(value, lower), upper)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user