Proposal: Extend CG(Rect)Geometry with center methods


(D. Felipe Torres) #1

One of the task that is performed often is center a frame with respect to
it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length
associations.
- Because this code is often found in a layout method, several other rect
variables may be defined in the scope which makes it easier to mistake one
variable with another if their names are close (and you are used to
autocomplete)
- And finally but most importantly, while the equation here is simple, one
must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in respect
to a parent.

I'm pretty sure there are other pretty useful extensions that can be added
to CGGeometry as well but this one I think is basic and pretty important.

···

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me


(Jacob Bandes-Storch) #2

Would it make sense to achieve the same thing by giving midX and midY
setters (they currently only have getters)?

I'm don't think I like the idea of tying down any CGRect extensions to a
"parent" rect, but saying "rect.midX = parent.midX" is pretty simple &
clear.

Jacob

···

On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution < swift-evolution@swift.org> wrote:

One of the task that is performed often is center a frame with respect to
it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length
associations.
- Because this code is often found in a layout method, several other rect
variables may be defined in the scope which makes it easier to mistake one
variable with another if their names are close (and you are used to
autocomplete)
- And finally but most importantly, while the equation here is simple, one
must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in respect
to a parent.

I'm pretty sure there are other pretty useful extensions that can be added
to CGGeometry as well but this one I think is basic and pretty important.

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #3

Hi Diego,

Although the framework overlays (https://github.com/apple/swift/tree/master/stdlib/public/SDK) are currently in the Swift repository, the Swift project doesn't own these APIs; they belong to the respective framework owners. Changes to the Swift APIs of the framework, therefore, need to be proposed to the framework owners. I would do that through bugreport.apple.com <http://bugreport.apple.com/> using component "CoreGraphics / X".

HTH,
Dave

···

On Dec 10, 2015, at 6:17 AM, D. Felipe Torres via swift-evolution <swift-evolution@swift.org> wrote:

One of the task that is performed often is center a frame with respect to it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length associations.
- Because this code is often found in a layout method, several other rect variables may be defined in the scope which makes it easier to mistake one variable with another if their names are close (and you are used to autocomplete)
- And finally but most importantly, while the equation here is simple, one must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in respect to a parent.

I'm pretty sure there are other pretty useful extensions that can be added to CGGeometry as well but this one I think is basic and pretty important.

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me <http://dtorres.me/> _______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(D. Felipe Torres) #4

Using the mid properties wouldn't help much as they are the middle of the
bounds (origin + length/2) and because it's a derived value from two
different structures, its not clear which structure you want to modify.

Either way, after thinking more about it, there is too much ambiguity to
the details of this. The intent is not always clear and looking into the
other functions, they all stand on their own. A CGRect doesn't have any
sense of hierarchy.

It only appears when you have layers/views (and those do have a way of
setting the center because the relationship/hierarchy is well defined).

I don't see any more reason to pursue this proposal.

···

On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Would it make sense to achieve the same thing by giving midX and midY
setters (they currently only have getters)?

I'm don't think I like the idea of tying down any CGRect extensions to a
"parent" rect, but saying "rect.midX = parent.midX" is pretty simple &
clear.

Jacob

On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution < > swift-evolution@swift.org> wrote:

One of the task that is performed often is center a frame with respect to
it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length
associations.
- Because this code is often found in a layout method, several other rect
variables may be defined in the scope which makes it easier to mistake one
variable with another if their names are close (and you are used to
autocomplete)
- And finally but most importantly, while the equation here is simple,
one must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in respect
to a parent.

I'm pretty sure there are other pretty useful extensions that can be
added to CGGeometry as well but this one I think is basic and pretty
important.

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
++++++++++++++++++++++++++
Diego Torres.
Phone (Mobile Germany): +49 157 30070985
Phone (Landline Chile): +56 2 29790978
Web: dtorres.me


(Jacob Bandes-Storch) #5

I still think it might be valuable to pursue setters for all of the
currently-read-only convenience properties (minX, midX, maxX, minY, midY,
maxY).

Jacob

···

On Fri, Dec 11, 2015 at 1:17 PM, D. Felipe Torres <warorface@gmail.com> wrote:

Using the mid properties wouldn't help much as they are the middle of the
bounds (origin + length/2) and because it's a derived value from two
different structures, its not clear which structure you want to modify.

Either way, after thinking more about it, there is too much ambiguity to
the details of this. The intent is not always clear and looking into the
other functions, they all stand on their own. A CGRect doesn't have any
sense of hierarchy.

It only appears when you have layers/views (and those do have a way of
setting the center because the relationship/hierarchy is well defined).

I don't see any more reason to pursue this proposal.

On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

Would it make sense to achieve the same thing by giving midX and midY
setters (they currently only have getters)?

I'm don't think I like the idea of tying down any CGRect extensions to a
"parent" rect, but saying "rect.midX = parent.midX" is pretty simple &
clear.

Jacob

On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution < >> swift-evolution@swift.org> wrote:

One of the task that is performed often is center a frame with respect
to it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length
associations.
- Because this code is often found in a layout method, several other
rect variables may be defined in the scope which makes it easier to mistake
one variable with another if their names are close (and you are used to
autocomplete)
- And finally but most importantly, while the equation here is simple,
one must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in
respect to a parent.

I'm pretty sure there are other pretty useful extensions that can be
added to CGGeometry as well but this one I think is basic and pretty
important.

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
++++++++++++++++++++++++++
Diego Torres.
Phone (Mobile Germany): +49 157 30070985
Phone (Landline Chile): +56 2 29790978
Web: dtorres.me


(Marc Knaup) #6

I'm fine with them having no setters.
I'm not fine with that we cannot add them through extensions.

For example I'd love to add a setter for the properties .width and .height.
But for now Swift does not allow adding a setter to an existing read-only
property through extension.

We can shadow the whole property be redefining it in an extension.
Unfortunately this breaks when using the (public) extension from another
module due to ambiguity. Swift doesn't know what property it should use:
the original one or the one from the extension.
https://github.com/fluidsonic/JetPack/blob/a3c321770854e35e886f1e06915ae86f782164b9/Sources/extensions/CoreGraphics/CGRect.swift#L215

···

On Sun, Dec 13, 2015 at 10:55 PM, Jacob Bandes-Storch via swift-evolution < swift-evolution@swift.org> wrote:

I still think it might be valuable to pursue setters for all of the
currently-read-only convenience properties (minX, midX, maxX, minY, midY,
maxY).

Jacob

On Fri, Dec 11, 2015 at 1:17 PM, D. Felipe Torres <warorface@gmail.com> > wrote:

Using the mid properties wouldn't help much as they are the middle of the
bounds (origin + length/2) and because it's a derived value from two
different structures, its not clear which structure you want to modify.

Either way, after thinking more about it, there is too much ambiguity to
the details of this. The intent is not always clear and looking into the
other functions, they all stand on their own. A CGRect doesn't have any
sense of hierarchy.

It only appears when you have layers/views (and those do have a way of
setting the center because the relationship/hierarchy is well defined).

I don't see any more reason to pursue this proposal.

On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch <jtbandes@gmail.com> >> wrote:

Would it make sense to achieve the same thing by giving midX and midY
setters (they currently only have getters)?

I'm don't think I like the idea of tying down any CGRect extensions to a
"parent" rect, but saying "rect.midX = parent.midX" is pretty simple &
clear.

Jacob

On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution < >>> swift-evolution@swift.org> wrote:

One of the task that is performed often is center a frame with respect
to it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length
associations.
- Because this code is often found in a layout method, several other
rect variables may be defined in the scope which makes it easier to mistake
one variable with another if their names are close (and you are used to
autocomplete)
- And finally but most importantly, while the equation here is simple,
one must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in
respect to a parent.

I'm pretty sure there are other pretty useful extensions that can be
added to CGGeometry as well but this one I think is basic and pretty
important.

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
++++++++++++++++++++++++++
Diego Torres.
Phone (Mobile Germany): +49 157 30070985
Phone (Landline Chile): +56 2 29790978
Web: dtorres.me

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(D. Felipe Torres) #7

The problem with making those settable is the ambiguity of it.

Say you increase the value at maxY, should the length or origin.y be
increased? should they share the modification and increase both buy half?

It is not clear the intention here.

And then, as David said, this is CoreGraphics API which has to be suggested
through Radars and we all know how likely our chances are there.

···

On Sun, Dec 13, 2015 at 10:55 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

I still think it might be valuable to pursue setters for all of the
currently-read-only convenience properties (minX, midX, maxX, minY, midY,
maxY).

Jacob

On Fri, Dec 11, 2015 at 1:17 PM, D. Felipe Torres <warorface@gmail.com> > wrote:

Using the mid properties wouldn't help much as they are the middle of the
bounds (origin + length/2) and because it's a derived value from two
different structures, its not clear which structure you want to modify.

Either way, after thinking more about it, there is too much ambiguity to
the details of this. The intent is not always clear and looking into the
other functions, they all stand on their own. A CGRect doesn't have any
sense of hierarchy.

It only appears when you have layers/views (and those do have a way of
setting the center because the relationship/hierarchy is well defined).

I don't see any more reason to pursue this proposal.

On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch <jtbandes@gmail.com> >> wrote:

Would it make sense to achieve the same thing by giving midX and midY
setters (they currently only have getters)?

I'm don't think I like the idea of tying down any CGRect extensions to a
"parent" rect, but saying "rect.midX = parent.midX" is pretty simple &
clear.

Jacob

On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution < >>> swift-evolution@swift.org> wrote:

One of the task that is performed often is center a frame with respect
to it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length
associations.
- Because this code is often found in a layout method, several other
rect variables may be defined in the scope which makes it easier to mistake
one variable with another if their names are close (and you are used to
autocomplete)
- And finally but most importantly, while the equation here is simple,
one must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in
respect to a parent.

I'm pretty sure there are other pretty useful extensions that can be
added to CGGeometry as well but this one I think is basic and pretty
important.

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
++++++++++++++++++++++++++
Diego Torres.
Phone (Mobile Germany): +49 157 30070985
Phone (Landline Chile): +56 2 29790978
Web: dtorres.me

--
++++++++++++++++++++++++++
Diego Torres.
Phone (Mobile Germany): +49 157 30070985
Phone (Landline Chile): +56 2 29790978
Web: dtorres.me


(Kenny Leung) #8

I also think that keeping with non-mutable versions of these methods is a lot better at keeping you out of trouble. Here’s the set that I’ve been using for a while:

extension CGRect {
    public var aspect :CGFloat {get{return width/height}}
    public var isPortrait :Bool {get{return aspect < 1}}
    public var isLandscape :Bool {get{return aspect > 1}}
    public var isSquare :Bool {get{return aspect == 1}}
    public var center :CGPoint {get{return CGPointMake(midX,midY)}}
    
    public init(size s:CGSize) {self=CGRectMake(0,0,s.width,s.height)}
    public init(size s:CGSize, centeredOn p:CGPoint) {self=CGRect(size:s).centerOn(p)}
    public init(square s:CGFloat, centeredOn p:CGPoint) {self=CGRectMake(p.x-s/2,p.y-s/2,s,s)}
    
    public func centerOn(p :CGPoint) -> CGRect {return CGRectMake(p.x-width/2,p.y-height/2,width,height)}
    public func centerOn(r :CGRect) -> CGRect {return centerOn(r.center)}
    public func scale(s :CGFloat) -> CGRect {return CGRectMake(origin.x,origin.y,width*s,height*s)}
    public func scaleAround(r :CGRect) -> CGFloat {return r.aspect<=self.aspect ? r.height/height : r.width/width}
    public func scaleAndCenterAround(r :CGRect) -> CGRect {return self.scale(self.scaleAround(r)).centerOn(r)}
    public func scaleIn(r :CGRect) -> CGFloat {return r.aspect<=self.aspect ? r.width/width : r.height/height}
    public func scaleAndCenterIn(r :CGRect) -> CGRect {return self.scale(self.scaleIn(r)).centerOn(r)}
}

-Kenny

···

On Dec 15, 2015, at 3:11 AM, D. Felipe Torres via swift-evolution <swift-evolution@swift.org> wrote:

The problem with making those settable is the ambiguity of it.

Say you increase the value at maxY, should the length or origin.y be increased? should they share the modification and increase both buy half?

It is not clear the intention here.

And then, as David said, this is CoreGraphics API which has to be suggested through Radars and we all know how likely our chances are there.

On Sun, Dec 13, 2015 at 10:55 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:
I still think it might be valuable to pursue setters for all of the currently-read-only convenience properties (minX, midX, maxX, minY, midY, maxY).

Jacob

On Fri, Dec 11, 2015 at 1:17 PM, D. Felipe Torres <warorface@gmail.com> wrote:
Using the mid properties wouldn't help much as they are the middle of the bounds (origin + length/2) and because it's a derived value from two different structures, its not clear which structure you want to modify.

Either way, after thinking more about it, there is too much ambiguity to the details of this. The intent is not always clear and looking into the other functions, they all stand on their own. A CGRect doesn't have any sense of hierarchy.

It only appears when you have layers/views (and those do have a way of setting the center because the relationship/hierarchy is well defined).

I don't see any more reason to pursue this proposal.

On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:
Would it make sense to achieve the same thing by giving midX and midY setters (they currently only have getters)?

I'm don't think I like the idea of tying down any CGRect extensions to a "parent" rect, but saying "rect.midX = parent.midX" is pretty simple & clear.

Jacob

On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution <swift-evolution@swift.org> wrote:
One of the task that is performed often is center a frame with respect to it's parent.
The code for this is short and simple:

rect.origin.x = (rect.width-parent.width)/2 // or...
rect.origin.y = (rect.height-parent.height)/2

## Current Problems

- It is very easy to get it wrong and confuse X or Y and their length associations.
- Because this code is often found in a layout method, several other rect variables may be defined in the scope which makes it easier to mistake one variable with another if their names are close (and you are used to autocomplete)
- And finally but most importantly, while the equation here is simple, one must parse it and understand it and is not a very swifty approach.

##Proposed Additions

2 (actually 4) extensions in CGGeometry to CGRect:

extension CGRect {
      public func centerX(parentRect: CGRect) -> CGRect
      public mutating func centerXInPlace(parentRect: CGRect)
      public fun centerY(parentRect: CGRect) -> CGRect
      public mutating func centerYInPlace(parentRect: CGRect)
}

This extension allows very easily (and verbally) center a rect in respect to a parent.

I'm pretty sure there are other pretty useful extensions that can be added to CGGeometry as well but this one I think is basic and pretty important.

--
++++++++++++++++++++++++++
Diego Torres.
Web: dtorres.me

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
++++++++++++++++++++++++++
Diego Torres.
Phone (Mobile Germany): +49 157 30070985
Phone (Landline Chile): +56 2 29790978
Web: dtorres.me

--
++++++++++++++++++++++++++
Diego Torres.
Phone (Mobile Germany): +49 157 30070985
Phone (Landline Chile): +56 2 29790978
Web: dtorres.me
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(ilya) #9

-1 on scale. Basic scale() is not clear whether center or origin is a fixed
point. Other scale(...) functions presented here seem too complicated.

Ditto centerOn()

aspect is a bad idea as it naturally leads one to comparing floats to each
other. Which is very error prone.

How about we define a getter and setter for center and leave it at that?

···

On Wed, Dec 16, 2015 at 07:28 Kenny Leung via swift-evolution < swift-evolution@swift.org> wrote:

I also think that keeping with non-mutable versions of these methods is a
lot better at keeping you out of trouble. Here’s the set that I’ve been
using for a while:

extension CGRect {
    public var aspect :CGFloat {get{return width/height}}
    public var isPortrait :Bool {get{return aspect < 1}}
    public var isLandscape :Bool {get{return aspect > 1}}
    public var isSquare :Bool {get{return aspect == 1}}
    public var center :CGPoint {get{return CGPointMake(midX,midY)}}

    public init(size s:CGSize) {self=CGRectMake(0,0,s.width,s.height)}
    public init(size s:CGSize, centeredOn p:CGPoint)
{self=CGRect(size:s).centerOn(p)}
    public init(square s:CGFloat, centeredOn p:CGPoint)
{self=CGRectMake(p.x-s/2,p.y-s/2,s,s)}

    public func centerOn(p :CGPoint) -> CGRect {return
CGRectMake(p.x-width/2,p.y-height/2,width,height)}
    public func centerOn(r :CGRect) -> CGRect {return centerOn(r.center)}
    public func scale(s :CGFloat) -> CGRect {return
CGRectMake(origin.x,origin.y,width*s,height*s)}
    public func scaleAround(r :CGRect) -> CGFloat {return
r.aspect<=self.aspect ? r.height/height : r.width/width}
    public func scaleAndCenterAround(r :CGRect) -> CGRect {return
self.scale(self.scaleAround(r)).centerOn(r)}
    public func scaleIn(r :CGRect) -> CGFloat {return
r.aspect<=self.aspect ? r.width/width : r.height/height}
    public func scaleAndCenterIn(r :CGRect) -> CGRect {return
self.scale(self.scaleIn(r)).centerOn(r)}
}

-Kenny

> On Dec 15, 2015, at 3:11 AM, D. Felipe Torres via swift-evolution < > swift-evolution@swift.org> wrote:
>
> The problem with making those settable is the ambiguity of it.
>
> Say you increase the value at maxY, should the length or origin.y be
increased? should they share the modification and increase both buy half?
>
> It is not clear the intention here.
>
> And then, as David said, this is CoreGraphics API which has to be
suggested through Radars and we all know how likely our chances are there.
>
> On Sun, Dec 13, 2015 at 10:55 PM, Jacob Bandes-Storch < > jtbandes@gmail.com> wrote:
> I still think it might be valuable to pursue setters for all of the
currently-read-only convenience properties (minX, midX, maxX, minY, midY,
maxY).
>
> Jacob
>
> On Fri, Dec 11, 2015 at 1:17 PM, D. Felipe Torres <warorface@gmail.com> > wrote:
> Using the mid properties wouldn't help much as they are the middle of
the bounds (origin + length/2) and because it's a derived value from two
different structures, its not clear which structure you want to modify.
>
> Either way, after thinking more about it, there is too much ambiguity to
the details of this. The intent is not always clear and looking into the
other functions, they all stand on their own. A CGRect doesn't have any
sense of hierarchy.
>
> It only appears when you have layers/views (and those do have a way of
setting the center because the relationship/hierarchy is well defined).
>
> I don't see any more reason to pursue this proposal.
>
>
> On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:
> Would it make sense to achieve the same thing by giving midX and midY
setters (they currently only have getters)?
>
> I'm don't think I like the idea of tying down any CGRect extensions to a
"parent" rect, but saying "rect.midX = parent.midX" is pretty simple &
clear.
>
> Jacob
>
> On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution < > swift-evolution@swift.org> wrote:
> One of the task that is performed often is center a frame with respect
to it's parent.
> The code for this is short and simple:
>
> rect.origin.x = (rect.width-parent.width)/2 // or...
> rect.origin.y = (rect.height-parent.height)/2
>
> ## Current Problems
>
> - It is very easy to get it wrong and confuse X or Y and their length
associations.
> - Because this code is often found in a layout method, several other
rect variables may be defined in the scope which makes it easier to mistake
one variable with another if their names are close (and you are used to
autocomplete)
> - And finally but most importantly, while the equation here is simple,
one must parse it and understand it and is not a very swifty approach.
>
> ##Proposed Additions
>
> 2 (actually 4) extensions in CGGeometry to CGRect:
>
> extension CGRect {
> public func centerX(parentRect: CGRect) -> CGRect
> public mutating func centerXInPlace(parentRect: CGRect)
> public fun centerY(parentRect: CGRect) -> CGRect
> public mutating func centerYInPlace(parentRect: CGRect)
> }
>
> This extension allows very easily (and verbally) center a rect in
respect to a parent.
>
> I'm pretty sure there are other pretty useful extensions that can be
added to CGGeometry as well but this one I think is basic and pretty
important.
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Web: dtorres.me
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Phone (Mobile Germany): +49 157 30070985
> Phone (Landline Chile): +56 2 29790978
> Web: dtorres.me
>
>
>
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Phone (Mobile Germany): +49 157 30070985
> Phone (Landline Chile): +56 2 29790978
> Web: dtorres.me
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #10

I don't want to shut down a productive conversation, but since this is all about changing the CoreGraphics framework I think this whole discussion may be out-of-scope for swift-evolution. What does everybody else think?

···

On Dec 16, 2015, at 6:41 AM, ilya via swift-evolution <swift-evolution@swift.org> wrote:

-1 on scale. Basic scale() is not clear whether center or origin is a fixed point. Other scale(...) functions presented here seem too complicated.

Ditto centerOn()

aspect is a bad idea as it naturally leads one to comparing floats to each other. Which is very error prone.

How about we define a getter and setter for center and leave it at that?

On Wed, Dec 16, 2015 at 07:28 Kenny Leung via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
I also think that keeping with non-mutable versions of these methods is a lot better at keeping you out of trouble. Here’s the set that I’ve been using for a while:

extension CGRect {
    public var aspect :CGFloat {get{return width/height}}
    public var isPortrait :Bool {get{return aspect < 1}}
    public var isLandscape :Bool {get{return aspect > 1}}
    public var isSquare :Bool {get{return aspect == 1}}
    public var center :CGPoint {get{return CGPointMake(midX,midY)}}

    public init(size s:CGSize) {self=CGRectMake(0,0,s.width,s.height)}
    public init(size s:CGSize, centeredOn p:CGPoint) {self=CGRect(size:s).centerOn(p)}
    public init(square s:CGFloat, centeredOn p:CGPoint) {self=CGRectMake(p.x-s/2,p.y-s/2,s,s)}

    public func centerOn(p :CGPoint) -> CGRect {return CGRectMake(p.x-width/2,p.y-height/2,width,height)}
    public func centerOn(r :CGRect) -> CGRect {return centerOn(r.center)}
    public func scale(s :CGFloat) -> CGRect {return CGRectMake(origin.x,origin.y,width*s,height*s)}
    public func scaleAround(r :CGRect) -> CGFloat {return r.aspect<=self.aspect ? r.height/height : r.width/width}
    public func scaleAndCenterAround(r :CGRect) -> CGRect {return self.scale(self.scaleAround(r)).centerOn(r)}
    public func scaleIn(r :CGRect) -> CGFloat {return r.aspect<=self.aspect ? r.width/width : r.height/height}
    public func scaleAndCenterIn(r :CGRect) -> CGRect {return self.scale(self.scaleIn(r)).centerOn(r)}
}

-Kenny

> On Dec 15, 2015, at 3:11 AM, D. Felipe Torres via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> The problem with making those settable is the ambiguity of it.
>
> Say you increase the value at maxY, should the length or origin.y be increased? should they share the modification and increase both buy half?
>
> It is not clear the intention here.
>
> And then, as David said, this is CoreGraphics API which has to be suggested through Radars and we all know how likely our chances are there.
>
> On Sun, Dec 13, 2015 at 10:55 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:
> I still think it might be valuable to pursue setters for all of the currently-read-only convenience properties (minX, midX, maxX, minY, midY, maxY).
>
> Jacob
>
> On Fri, Dec 11, 2015 at 1:17 PM, D. Felipe Torres <warorface@gmail.com <mailto:warorface@gmail.com>> wrote:
> Using the mid properties wouldn't help much as they are the middle of the bounds (origin + length/2) and because it's a derived value from two different structures, its not clear which structure you want to modify.
>
> Either way, after thinking more about it, there is too much ambiguity to the details of this. The intent is not always clear and looking into the other functions, they all stand on their own. A CGRect doesn't have any sense of hierarchy.
>
> It only appears when you have layers/views (and those do have a way of setting the center because the relationship/hierarchy is well defined).
>
> I don't see any more reason to pursue this proposal.
>
>
> On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:
> Would it make sense to achieve the same thing by giving midX and midY setters (they currently only have getters)?
>
> I'm don't think I like the idea of tying down any CGRect extensions to a "parent" rect, but saying "rect.midX = parent.midX" is pretty simple & clear.
>
> Jacob
>
> On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> One of the task that is performed often is center a frame with respect to it's parent.
> The code for this is short and simple:
>
> rect.origin.x = (rect.width-parent.width)/2 // or...
> rect.origin.y = (rect.height-parent.height)/2
>
> ## Current Problems
>
> - It is very easy to get it wrong and confuse X or Y and their length associations.
> - Because this code is often found in a layout method, several other rect variables may be defined in the scope which makes it easier to mistake one variable with another if their names are close (and you are used to autocomplete)
> - And finally but most importantly, while the equation here is simple, one must parse it and understand it and is not a very swifty approach.
>
> ##Proposed Additions
>
> 2 (actually 4) extensions in CGGeometry to CGRect:
>
> extension CGRect {
> public func centerX(parentRect: CGRect) -> CGRect
> public mutating func centerXInPlace(parentRect: CGRect)
> public fun centerY(parentRect: CGRect) -> CGRect
> public mutating func centerYInPlace(parentRect: CGRect)
> }
>
> This extension allows very easily (and verbally) center a rect in respect to a parent.
>
> I'm pretty sure there are other pretty useful extensions that can be added to CGGeometry as well but this one I think is basic and pretty important.
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Web: dtorres.me <http://dtorres.me/>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Phone (Mobile Germany): +49 157 30070985
> Phone (Landline Chile): +56 2 29790978
> Web: dtorres.me <http://dtorres.me/>
>
>
>
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Phone (Mobile Germany): +49 157 30070985
> Phone (Landline Chile): +56 2 29790978
> Web: dtorres.me <http://dtorres.me/>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave


(Marc Knaup) #11

I agree.

The limitations of possible workarounds should be discussed instead in
separate threads. Like for example that you aren't able to add a setter to
an existing read-only property by extension which would allow to apply the
desired changes in your own modules instead of in CoreGraphics directly.

···

On Wed, Dec 16, 2015 at 6:31 PM, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

I don't want to shut down a productive conversation, but since this is all
about changing the CoreGraphics framework I think this whole discussion may
be out-of-scope for swift-evolution. What does everybody else think?

On Dec 16, 2015, at 6:41 AM, ilya via swift-evolution < > swift-evolution@swift.org> wrote:

-1 on scale. Basic scale() is not clear whether center or origin is a
fixed point. Other scale(...) functions presented here seem too
complicated.

Ditto centerOn()

aspect is a bad idea as it naturally leads one to comparing floats to each
other. Which is very error prone.

How about we define a getter and setter for center and leave it at that?

On Wed, Dec 16, 2015 at 07:28 Kenny Leung via swift-evolution < > swift-evolution@swift.org> wrote:

I also think that keeping with non-mutable versions of these methods is a
lot better at keeping you out of trouble. Here’s the set that I’ve been
using for a while:

extension CGRect {
    public var aspect :CGFloat {get{return width/height}}
    public var isPortrait :Bool {get{return aspect < 1}}
    public var isLandscape :Bool {get{return aspect > 1}}
    public var isSquare :Bool {get{return aspect == 1}}
    public var center :CGPoint {get{return CGPointMake(midX,midY)}}

    public init(size s:CGSize) {self=CGRectMake(0,0,s.width,s.height)}
    public init(size s:CGSize, centeredOn p:CGPoint)
{self=CGRect(size:s).centerOn(p)}
    public init(square s:CGFloat, centeredOn p:CGPoint)
{self=CGRectMake(p.x-s/2,p.y-s/2,s,s)}

    public func centerOn(p :CGPoint) -> CGRect {return
CGRectMake(p.x-width/2,p.y-height/2,width,height)}
    public func centerOn(r :CGRect) -> CGRect {return centerOn(r.center)}
    public func scale(s :CGFloat) -> CGRect {return
CGRectMake(origin.x,origin.y,width*s,height*s)}
    public func scaleAround(r :CGRect) -> CGFloat {return
r.aspect<=self.aspect ? r.height/height : r.width/width}
    public func scaleAndCenterAround(r :CGRect) -> CGRect {return
self.scale(self.scaleAround(r)).centerOn(r)}
    public func scaleIn(r :CGRect) -> CGFloat {return
r.aspect<=self.aspect ? r.width/width : r.height/height}
    public func scaleAndCenterIn(r :CGRect) -> CGRect {return
self.scale(self.scaleIn(r)).centerOn(r)}
}

-Kenny

> On Dec 15, 2015, at 3:11 AM, D. Felipe Torres via swift-evolution < >> swift-evolution@swift.org> wrote:
>
> The problem with making those settable is the ambiguity of it.
>
> Say you increase the value at maxY, should the length or origin.y be
increased? should they share the modification and increase both buy half?
>
> It is not clear the intention here.
>
> And then, as David said, this is CoreGraphics API which has to be
suggested through Radars and we all know how likely our chances are there.
>
> On Sun, Dec 13, 2015 at 10:55 PM, Jacob Bandes-Storch < >> jtbandes@gmail.com> wrote:
> I still think it might be valuable to pursue setters for all of the
currently-read-only convenience properties (minX, midX, maxX, minY, midY,
maxY).
>
> Jacob
>
> On Fri, Dec 11, 2015 at 1:17 PM, D. Felipe Torres <warorface@gmail.com> >> wrote:
> Using the mid properties wouldn't help much as they are the middle of
the bounds (origin + length/2) and because it's a derived value from two
different structures, its not clear which structure you want to modify.
>
> Either way, after thinking more about it, there is too much ambiguity
to the details of this. The intent is not always clear and looking into the
other functions, they all stand on their own. A CGRect doesn't have any
sense of hierarchy.
>
> It only appears when you have layers/views (and those do have a way of
setting the center because the relationship/hierarchy is well defined).
>
> I don't see any more reason to pursue this proposal.
>
>
> On Fri, Dec 11, 2015 at 7:29 AM, Jacob Bandes-Storch < >> jtbandes@gmail.com> wrote:
> Would it make sense to achieve the same thing by giving midX and midY
setters (they currently only have getters)?
>
> I'm don't think I like the idea of tying down any CGRect extensions to
a "parent" rect, but saying "rect.midX = parent.midX" is pretty simple &
clear.
>
> Jacob
>
> On Thu, Dec 10, 2015 at 6:17 AM, D. Felipe Torres via swift-evolution < >> swift-evolution@swift.org> wrote:
> One of the task that is performed often is center a frame with respect
to it's parent.
> The code for this is short and simple:
>
> rect.origin.x = (rect.width-parent.width)/2 // or...
> rect.origin.y = (rect.height-parent.height)/2
>
> ## Current Problems
>
> - It is very easy to get it wrong and confuse X or Y and their length
associations.
> - Because this code is often found in a layout method, several other
rect variables may be defined in the scope which makes it easier to mistake
one variable with another if their names are close (and you are used to
autocomplete)
> - And finally but most importantly, while the equation here is simple,
one must parse it and understand it and is not a very swifty approach.
>
> ##Proposed Additions
>
> 2 (actually 4) extensions in CGGeometry to CGRect:
>
> extension CGRect {
> public func centerX(parentRect: CGRect) -> CGRect
> public mutating func centerXInPlace(parentRect: CGRect)
> public fun centerY(parentRect: CGRect) -> CGRect
> public mutating func centerYInPlace(parentRect: CGRect)
> }
>
> This extension allows very easily (and verbally) center a rect in
respect to a parent.
>
> I'm pretty sure there are other pretty useful extensions that can be
added to CGGeometry as well but this one I think is basic and pretty
important.
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Web: dtorres.me
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Phone (Mobile Germany): +49 157 30070985
> Phone (Landline Chile): +56 2 29790978
> Web: dtorres.me
>
>
>
>
> --
> ++++++++++++++++++++++++++
> Diego Torres.
> Phone (Mobile Germany): +49 157 30070985
> Phone (Landline Chile): +56 2 29790978
> Web: dtorres.me
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution