Skip to content

Layoutable and SizeCalculable protocols - #148

Merged
lucdion merged 11 commits into
layoutBox:masterfrom
antoinelamy:refactor/layoutable
Jun 15, 2018
Merged

lucdion merged 11 commits into
layoutBox:masterfrom
antoinelamy:refactor/layoutable

Conversation

@antoinelamy

Copy link
Copy Markdown
Contributor

Refactoring to avoid having to deal directly with view types making it easier to extend layouting to other APIs (ie: CALayer).

I avoided moving/adding files for now to avoid potential conflicts but I feel like some things should be renamed/moved. For exemple, getRect / setRect / isLTR() functions should probably be moved where protocol conformance is declared.

Comment thread Sources/PinLayout.swift
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/*

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporarily commented out, should be removed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably copy/paste comments before deleting the file 🤔

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the file for now, we could do that in another PR

Comment thread Sources/Impl/View+LTR.swift Outdated
@@ -23,7 +23,7 @@ import Foundation
import UIKit

extension UIView {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be moved in the extension where protocol conformance is declared

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this should be moved in UIView+PinLayout.swift and NSView+PinLayout.swift


@available(OSX 10.10, *)
private func computeLegacyFitSize(size: Size) -> Size {
guard let sizeCalculableView = view as? SizeCalculable else {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to check if the View implement SizeCalculable in the method setAdjustSizeType() for types .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible and .fitSizeLegacy. And here we should simply asserts in the guard, since it should never occurs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


@available(OSX 10.10, *)
private func computeSizeToFit(adjustSizeType: AdjustSizeType, size: Size) -> Size {
guard let sizeCalculableView = view as? SizeCalculable else {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// Currently we only support 1 and 2 levels.
} else {
return referenceSuperview.convert(point, to: layoutSuperview)
return referenceSuperview.convert(point, toView: layoutSuperview as! View.View)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be layoutSuperview as? View.View.
Also, View.View is a little bit weird 🙂, in my branch I was using TLayoutable instead of View for the generic type name. What do you think?


displayText += ", Tag: \(view.tag))\n"
// Removed, layoutable tag should probably not be exposed
//displayText += ", Tag: \(view.tag))\n"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the Layoutable should expose a property warningContext, that would expose a String returning this block content:

var hierarchy: [String] = []
....
displayText += ", Tag: \(view.tag))\n"

The idea here is to give as much info as possible of the View being layouted

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would probably feel weird to have it directly in Layoutable as it have nothing to do with layout. If the goal is to print as much info as possible, why not use the built-in CustomDebugStringConvertible protocol that already serve that purpose and print the tag if any and many more properties. We could add it as a requirement to Layoutable, what do you think?

protocol Layoutable: AnyObject, Equatable, CustomDebugStringConvertible

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know this one, excellent idea.


import Foundation

extension Layoutable {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, really nice to add this as an extension of the Layoutable protocol 👍

}

@available(OSX 10.10, *)
extension NSControl: SizeCalculable {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment thread Sources/SizeCalculable.swift Outdated

import Foundation

@available(OSX 10.10, *)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @available is not really required in the protocol declaration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment thread Sources/UIView+PinLayout.swift Outdated
extension UIView: Layoutable, SizeCalculable {
public typealias View = UIView

public func convert(_ point: CGPoint, toView view: UIView) -> CGPoint {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure to understand why does this method is required? Why not simply use directly the method convert(:CGPoint, to: UIView?) 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially thought it was a collision with the function taking UISpaceCoordinates as a parameter but after investigation, it was because the view parameter is optional. Fixed.

Comment thread Sources/View+Rect.swift Outdated

extension UIView {
func getRect(keepTransform: Bool) -> CGRect {
public func getRect(keepTransform: Bool) -> CGRect {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be cleaner, I would move immediately getRect and setRect in UIView+PinLayout.swift

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread Sources/View+Rect.swift Outdated

extension NSView {
func getRect(keepTransform: Bool) -> CGRect {
public func getRect(keepTransform: Bool) -> CGRect {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I would move immediately getRect and setRect in NSView+PinLayout.swift

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

displayText += ", Tag: \(view.tag))\n"
displayText += ", Debug description: \(view.debugDescription))\n"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact @antoinelamy, I would have put everything in the debugDescription property, anyway we will need to do that for other Layoutable.

I would include all this:

    var hierarchy: [String] = []
    ...
     if hierarchy.count > 0 {	  
             
     }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucdion not sure about that one, debugDescription is already implemented on NSView/UIView and it's already pretty verbose. Furthermore, we cannot override an existing function from an extension so I would leave the responsibility to the caller with special debugging needs to override debugDescription in their subclasses. What do you think @lucdion ?

@antoinelamy
antoinelamy force-pushed the refactor/layoutable branch from 90754c4 to f4f55f7 Compare June 14, 2018 12:45
@lucdion
lucdion merged commit 230e533 into layoutBox:master Jun 15, 2018
@lucdion

lucdion commented Jun 15, 2018

Copy link
Copy Markdown
Member

Thanks @antoinelamy for this amazing PR 👍 😄

@antoinelamy
antoinelamy deleted the refactor/layoutable branch June 27, 2018 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants