1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-17 16:07:44 +03:00
Macaw/Source/layout/ContentLayout.swift
2020-07-30 15:48:36 +07:00

94 lines
2.7 KiB
Swift

//
// ContentLayout.swift
// Macaw
//
// Created by Yuri Strot on 5/17/18.
// Copyright © 2018 Exyte. All rights reserved.
//
#if os(iOS)
import UIKit
#elseif os(OSX)
import AppKit
#endif
open class ContentLayout {
public static let none: ContentLayout = NoneLayout()
public static func of(scaling: AspectRatio = .meet, xAlign: Align = .mid, yAlign: Align = .mid) -> ContentLayout {
return ScalingContentLayout(scaling: scaling, xAlign: xAlign, yAlign: yAlign)
}
public static func of(contentMode: MViewContentMode) -> ContentLayout {
switch contentMode {
case .scaleToFill:
return of(scaling: .none)
case .scaleAspectFit:
return of(scaling: .meet)
case .scaleAspectFill:
return of(scaling: .slice)
case .redraw, .center:
return of(scaling: .doNothing)
case .top:
return of(scaling: .doNothing, yAlign: .min)
case .bottom:
return of(scaling: .doNothing, yAlign: .max)
case .left:
return of(scaling: .doNothing, xAlign: .min)
case .right:
return of(scaling: .doNothing, xAlign: .max)
case .topLeft:
return of(scaling: .doNothing, xAlign: .min, yAlign: .min)
case .topRight:
return of(scaling: .doNothing, xAlign: .max, yAlign: .min)
case .bottomLeft:
return of(scaling: .doNothing, xAlign: .min, yAlign: .max)
case .bottomRight:
return of(scaling: .doNothing, xAlign: .max, yAlign: .max)
#if os(iOS)
@unknown default:
return .none
#endif
}
}
public init() {
}
open func layout(size: Size, into sizeToFitIn: Size) -> Transform {
return layout(rect: size.rect(), into: sizeToFitIn)
}
open func layout(rect: Rect, into sizeToFitIn: Size) -> Transform {
return Transform.identity
}
}
class NoneLayout: ContentLayout {
}
class ScalingContentLayout: ContentLayout {
let scaling: AspectRatio
let xAlign: Align
let yAlign: Align
init(scaling: AspectRatio, xAlign: Align, yAlign: Align) {
self.scaling = scaling
self.xAlign = xAlign
self.yAlign = yAlign
}
open override func layout(rect: Rect, into sizeToFitIn: Size) -> Transform {
let newSize = scaling.fit(size: rect.size(), into: sizeToFitIn)
let sx = newSize.w / rect.w
let sy = newSize.h / rect.h
let dx = xAlign.align(outer: sizeToFitIn.w, inner: newSize.w) / sx
let dy = yAlign.align(outer: sizeToFitIn.h, inner: newSize.h) / sy
return Transform.scale(sx: sx, sy: sy).move(dx: dx - rect.x, dy: dy - rect.y)
}
}