@@ -185,155 +185,178 @@ extension PinLayoutImpl {
185185 }
186186
187187 private func computeSize( ) -> Size {
188- var width = computeWidth ( )
189- var height = computeHeight ( )
190-
191188 #if os(macOS)
192189 assert ( !legacyFitSize && fitType == nil )
193190 #endif
194191
195- if legacyFitSize {
196- return computeLegacyFitSize ( width: width, height: height)
197- } else if let fitType = fitType {
198- var fitWidth = CGFloat . greatestFiniteMagnitude
199- var fitHeight = CGFloat . greatestFiniteMagnitude
200-
201- // Apply min/max width/height before calling sizeThatFits() ... and reapply them after.
202- switch fitType {
203- case . width, . widthFlexible:
204- if let width = applyMinMax ( toWidth: width) {
205- fitWidth = width
206- } else {
207- fitWidth = view. bounds. width
208- }
209- case . height, . heightFlexible:
210- if let height = applyMinMax ( toHeight: height) {
211- fitHeight = height
212- } else {
213- fitHeight = view. bounds. height
214- }
215- }
216-
217- #if os(iOS) || os(tvOS)
218- let sizeThatFits = view. sizeThatFits ( CGSize ( width: fitWidth, height: fitHeight) )
219- #else
220- let sizeThatFits : CGSize
221- if #available( OSX 10 . 10 , * ) {
222- if let control = view as? NSControl {
223- sizeThatFits = control. sizeThatFits ( CGSize ( width: fitWidth, height: fitHeight) )
224- } else {
225- sizeThatFits = view. intrinsicContentSize
226- }
227- } else {
228- sizeThatFits = view. intrinsicContentSize
229- }
230- #endif
192+ var size = resolveSize ( )
231193
232- if fitWidth != . greatestFiniteMagnitude {
233- width = fitType. isFlexible ? sizeThatFits. width : fitWidth
234- } else {
235- width = sizeThatFits. width
236- }
237-
238- if fitHeight != . greatestFiniteMagnitude {
239- height = fitType. isFlexible ? sizeThatFits. height : fitHeight
240- } else {
241- height = sizeThatFits. height
242- }
243- } else if let aspectRatio = _aspectRatio {
244- if width == nil && height == nil {
245- warn ( " aspectRatio won't be applied, neither the width nor the height can be determined. " )
246- } else {
247- if width != nil && height != nil {
248- // warn, both are specified
249- warn ( " aspectRatio won't be applied, the width and the height are already defined by other PinLayout's properties. " )
250- } else if let width = width, let adjWidth = applyMinMax ( toWidth: width) {
251- height = adjWidth / aspectRatio
252- } else if let height = height, let adjHeight = applyMinMax ( toHeight: height) {
253- width = adjHeight * aspectRatio
254- }
194+ if let adjustSizeType = adjustSizeType {
195+ switch adjustSizeType {
196+ case . fitTypeWidth, . fitTypeHeight, . fitTypeWidthFlexible, . fitTypeHeightFlexible:
197+ size = computeSizeToFit ( adjustSizeType: adjustSizeType, size: size)
198+ case . fitSizeLegacy:
199+ size = computeLegacyFitSize ( size: size)
200+ case . aspectRatio( let ratio) :
201+ size = computeAspectRatio ( ratio, size: size)
255202 }
256203 }
257204
258- width = applyMinMax ( toWidth: width)
259- height = applyMinMax ( toHeight: height)
260-
261- if !validateComputedWidth( width) {
262- width = nil
205+ return validateAndApplyMinMax ( toSize: size)
206+ }
207+
208+ private func resolveSize( ) -> Size {
209+ var size = Size ( )
210+
211+ // Width
212+ if let width = width {
213+ size. width = width
214+ } else if let left = _left, let right = _right {
215+ size. width = right - left - _marginLeft - _marginRight
216+ } else if shouldKeepViewDimension {
217+ // No width has been specified (and won't be computed by a sizeToFit) => use the current view's width
218+ size. width = Coordinates . getViewRect ( view, keepTransform: keepTransform) . width
263219 }
264-
265- if !validateComputedHeight( height) {
266- height = nil
220+
221+ // Height
222+ if let height = height {
223+ size. height = height
224+ } else if let top = _top, let bottom = _bottom {
225+ size. height = bottom - top - _marginTop - _marginBottom
226+ } else if shouldKeepViewDimension {
227+ size. height = Coordinates . getViewRect ( view, keepTransform: keepTransform) . height
267228 }
268-
269- return ( width, height)
270- }
271229
272- private func computeLegacyFitSize( width: CGFloat ? , height: CGFloat ? ) -> Size {
273- var width = width
274- var height = height
230+ return size
231+ }
275232
276- if width == nil && height == nil {
233+ private func computeLegacyFitSize( size: Size ) -> Size {
234+ guard size. width != nil || size. height != nil else {
277235 warn ( " fitSize() won't be applied, neither the width nor the height can be determined. " )
236+ return size
237+ }
238+
239+ var size = size
240+ var fitWidth = CGFloat . greatestFiniteMagnitude
241+ var fitHeight = CGFloat . greatestFiniteMagnitude
242+
243+ if let width = applyMinMax ( toWidth: size. width) {
244+ fitWidth = width
245+ }
246+ if let height = applyMinMax ( toHeight: size. height) {
247+ fitHeight = height
248+ }
249+
250+ #if os(iOS) || os(tvOS)
251+ let sizeThatFits = view. sizeThatFits ( CGSize ( width: fitWidth, height: fitHeight) )
252+ #else
253+ let sizeThatFits = view. intrinsicContentSize
254+ #endif
255+
256+ if fitWidth != . greatestFiniteMagnitude && ( sizeThatFits. width > fitWidth) {
257+ size. width = fitWidth
258+ } else {
259+ size. width = sizeThatFits. width
260+ }
261+
262+ if fitHeight != . greatestFiniteMagnitude && ( sizeThatFits. height > fitHeight) {
263+ size. height = fitHeight
278264 } else {
279- var fitWidth = CGFloat . greatestFiniteMagnitude
280- var fitHeight = CGFloat . greatestFiniteMagnitude
265+ size. height = sizeThatFits. height
266+ }
267+
268+ return size
269+ }
270+
271+ private func computeSizeToFit( adjustSizeType: AdjustSizeType , size: Size ) -> Size {
272+ var fitWidth = CGFloat . greatestFiniteMagnitude
273+ var fitHeight = CGFloat . greatestFiniteMagnitude
274+ var size = size
281275
282- if let width = applyMinMax ( toWidth: width) {
276+ // Apply min/max width/height before calling sizeThatFits() ... and reapply them after.
277+ switch adjustSizeType {
278+ case . fitTypeWidth, . fitTypeWidthFlexible:
279+ if let width = applyMinMax ( toWidth: size. width) {
283280 fitWidth = width
281+ } else {
282+ fitWidth = view. bounds. width
284283 }
285- if let height = applyMinMax ( toHeight: height) {
284+ case . fitTypeHeight, . fitTypeHeightFlexible:
285+ if let height = applyMinMax ( toHeight: size. height) {
286286 fitHeight = height
287- }
288-
289- #if os(iOS) || os(tvOS)
290- let sizeThatFits = view. sizeThatFits ( CGSize ( width: fitWidth, height: fitHeight) )
291- #else
292- let sizeThatFits = view. intrinsicContentSize
293- #endif
294-
295- if fitWidth != . greatestFiniteMagnitude && ( sizeThatFits. width > fitWidth) {
296- width = fitWidth
297287 } else {
298- width = sizeThatFits . width
288+ fitHeight = view . bounds . height
299289 }
290+ default :
291+ assertionFailure ( " Should not occured " )
292+ }
300293
301- if fitHeight != . greatestFiniteMagnitude && ( sizeThatFits. height > fitHeight) {
302- height = fitHeight
294+ #if os(iOS) || os(tvOS)
295+ let sizeThatFits = view. sizeThatFits ( CGSize ( width: fitWidth, height: fitHeight) )
296+ #else
297+ let sizeThatFits : CGSize
298+ if #available( OSX 10 . 10 , * ) {
299+ if let control = view as? NSControl {
300+ sizeThatFits = control. sizeThatFits ( CGSize ( width: fitWidth, height: fitHeight) )
303301 } else {
304- height = sizeThatFits . height
302+ sizeThatFits = view . intrinsicContentSize
305303 }
304+ } else {
305+ sizeThatFits = view. intrinsicContentSize
306+ }
307+ #endif
306308
307- width = applyMinMax ( toWidth: width)
308- height = applyMinMax ( toHeight: height)
309+ if fitWidth != . greatestFiniteMagnitude {
310+ size. width = adjustSizeType. isFlexible ? sizeThatFits. width : fitWidth
311+ } else {
312+ size. width = sizeThatFits. width
313+ }
309314
310- if !validateComputedWidth( width) {
311- width = nil
312- }
315+ if fitHeight != . greatestFiniteMagnitude {
316+ size. height = adjustSizeType. isFlexible ? sizeThatFits. height : fitHeight
317+ } else {
318+ size. height = sizeThatFits. height
319+ }
313320
314- if !validateComputedHeight( height) {
315- height = nil
316- }
321+ return size
322+ }
323+
324+ private func computeAspectRatio( _ aspectRatio: CGFloat , size: Size ) -> Size {
325+ guard size. width != nil || size. height != nil else {
326+ warn ( " aspectRatio won't be applied, neither the width nor the height can be determined. " )
327+ return size
328+ }
329+ guard size. width == nil || size. height == nil else {
330+ warn ( " aspectRatio won't be applied, the width and the height are already defined by other PinLayout's properties. " )
331+ return size
317332 }
318333
319- return ( width, height)
334+ if let width = size. width, let adjustedWidth = applyMinMax ( toWidth: width) {
335+ return Size ( width: adjustedWidth, height: adjustedWidth / aspectRatio)
336+ } else if let height = size. height, let adjustedHeight = applyMinMax ( toHeight: height) {
337+ return Size ( width: adjustedHeight * aspectRatio, height: adjustedHeight)
338+ } else {
339+ assertionFailure ( " Should not occurs, all cases should be handled by guards above " )
340+ return size
341+ }
320342 }
321-
322- private func computeWidth( ) -> CGFloat ? {
323- var newWidth : CGFloat ?
324-
325- if let width = width {
326- newWidth = width
327- } else if let left = _left, let right = _right {
328- newWidth = right - left - _marginLeft - _marginRight
329- } else if shouldKeepViewDimension {
330- // No width has been specified (and won't be computed by a sizeToFit) => use the current view's width
331- newWidth = view. bounds. width
343+
344+ private func validateAndApplyMinMax( toSize size: Size ) -> Size {
345+ var size = size
346+ size. width = applyMinMax ( toWidth: size. width)
347+ size. height = applyMinMax ( toHeight: size. height)
348+
349+ if !validateComputedWidth( size. width) {
350+ size. width = nil
332351 }
333-
334- return newWidth
352+
353+ if !validateComputedHeight( size. height) {
354+ size. height = nil
355+ }
356+
357+ return size
335358 }
336-
359+
337360 private func applyMinMax( toWidth width: CGFloat ? ) -> CGFloat ? {
338361 var result = width
339362
@@ -386,20 +409,6 @@ extension PinLayoutImpl {
386409 return rect
387410 }
388411
389- private func computeHeight( ) -> CGFloat ? {
390- var newHeight : CGFloat ?
391-
392- if let height = height {
393- newHeight = height
394- } else if let top = _top, let bottom = _bottom {
395- newHeight = bottom - top - _marginTop - _marginBottom
396- } else if shouldKeepViewDimension {
397- newHeight = view. bounds. height
398- }
399-
400- return newHeight
401- }
402-
403412 private func applyMinMax( toHeight height: CGFloat ? ) -> CGFloat ? {
404413 var result = height
405414
0 commit comments