New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DSL for PlasticView Anchors and Values #76
Conversation
Add an `offset` property to `Anchor`, in order to be able to set anchors at a certain offset from the receiving view's anchor
This commit adds the `+=`, `-`, `-=`, `*=` and `/=` operators to Value
…oatLiteral This allows `Value` instances to be initialized by integer and floating point literals, having the scalable part equal to the numeric literal, and the fixed part equal to 0.
…as a convenient way to instantiate `Value` instances
I'll review it this evening.
|
I have a huge doubt about this. Another thing I don't like is that you changed the Third and last one, can you make a complete list of things you are adding? I saw several operator overloads and I'd like to have a list (e.g, to create the changelog of the bump) of things added/removed |
@bolismauro thanks for your thoughts on the PR! Let me address them:
The fact is: I'm not sure that I agree with this. I do agree that having to renounce to the ability to have a nice way to instantiate sizes and edge insets – i.e. by using In fact, I wouldn't remove them! I see the extensions to As for your concern regarding multiple ways to do the same thing: I'm not convinced it's intrinsically bad, as long as we're talking about things that differ just slightly in syntax and do not have any other bigger implication that one should be aware of. So, I'd rather give people a bit more flexibility to adapt to different needs/contexts, and leave to each project's guidelines to set the rules for this kind of details. That said, no big deal if people feel we're better off without them :)
I think it's the only solution to achieve something like I kind of agree that But, if you think of an
Sure thing! |
If we are going to add the offset property directly to Anchors, I suggest to follow one single approach and entirely remove all the set*(anchor:, offset:) and the other convenience methods that use the offsets and just keep the top/bottom/left/right properties. Neither I am 100% convinced but for sure this approach would:
Another thing that I've noticed is that this new Anchor's |
It's not on purpose. Thanks for making me notice it. Adding |
can you elaborate? |
There are ways to do it without additional views but I get your point. Ok so, let's add this concept of offset for the anchors. I think we should solve the issue with size/edgeinsets and then we can proceed with the implementation of everything. |
I've updated my PR to:
As for the debated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also make sure that
- all the examples work
- the documentation is updated
- the readme is updated
- you have added relevant tests, if needed
Plus (I can't do it myself since you forked the repo) I'd remove the following methods
public init(_ width: CGFloat, _ height: CGFloat)
(Size)public init(scalableWidth: CGFloat, fixedWidth: CGFloat, scalableHeight: CGFloat, fixedHeight: CGFloat) {
(Size)
public init(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) {
(Insets)public init(scalableTop: CGFloat, fixedTop: CGFloat, scalableLeft: CGFloat, fixedLeft: CGFloat, scalableBottom: CGFloat, fixedBottom: CGFloat, scalableRight: CGFloat, fixedRight: CGFloat)
(Insets)
|
||
} | ||
|
||
coord += view.scaleValue(offset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd change this in return coord + view.scaleValue(offset)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
This allows `Value` instances to be initialized by integer and floating point literals, | ||
having the scalable part equal to the numeric literal, and the fixed part equal to 0. | ||
*/ | ||
extension Value: ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove this?
We can define the +
operator also for Anchor/Int and Anchor/Double.
I don't really like these protocols to be honest
@smaramba @lucaquerella opinions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion it's better to have Value
conforming to ExpressibleByIntegerLiteral
and ExpressibleByFloatLiteral
, since they exist for this purpose: they make it clear to users of Value
why using integer/float literals in operations expecting Value
s works.
Defining an overload of the +
operator for Anchor/Int and Anchor/Double would be more confusing IMHO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they make it clear to users of Value why using integer/float literals in operations expecting Values works.
to me, they don't make it clear. You have to discover that you have implemented that protocol somewhere to understand the code, otherwise you don't get why it works.
If you define the proper + operator, if is oblivious the reason why it works.
In general we decided to don't use them multiple times because they can create confusing situations..
For instance (not tested, but it should work)
init(width: Value, height: Value) -> Size
// you can do
Size(width: 5, height: 7)
You are basically propagating this ability to use double instead of values everywhere and to me this is not good (consistency & clarity first, type less characters then)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this discussion would go the same way the discussion on .scalable/.fixed
went 😄
Should I proceed and remove all these additions from the PR, or would you prefer to learn @lucaquerella's and @smaramba's opinions first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I asked opinions to both. As always I will be happy with the decision of the majority of us.
I really don't get why I'm the only once concerned about losing clarity. With that additions you can swap numbers/Values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm kinda neutral, you are strongly against, so it's a no go to me. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I absolutely agree that automatic type conversions/promotions make understanding what's going on less clear than having explicit inizializers.
But I also believe that, to the user new to Katana that has never used Plastic, reading code filled with .scalable(...)
, Value(scalable: ..., fixed: ...)
would be quite puzzling. And, in general, it adds boilerplate, slowing down both the reading and writing of the code (not in a major way of course, but still).
So what I'm trying to convey is: since Value
s are an implementation detail I'd rather not be concerned about wherever possible, what if I'm just told "Plastic scales dimensions for you in order to make your views lay out consistently across different screen sizes. If you don't want something to be scaled, just use .fixed
". And I use ints and floats as I've always done since the beginning of time when doing UI work on any platform.
BUT I understand this is my point of view, and may not be anyone else's 🙃.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I also believe that, to the user new to Katana that has never used Plastic, reading code filled with .scalable(...), Value(scalable: ..., fixed: ...) would be quite puzzling.
You can't use a library without knowing the basic concepts. Value is a basic concept of Plastic. Because of this I don't buy the puzzling argument. I agree with the boilerplate and in fact I agree with the layout DSL. I just don't want to extend this DSL everywhere
"Plastic scales dimensions for you in order to make your views lay out consistently across different screen sizes. If you don't want something to be scaled, just use .fixed"
in plastic you have to use fixed also when things are scaled. I can give you infinite examples of this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed offline with @bolismauro I do agree that going with the most conservative implementation (overloading of +
) in this specific case should be the right option, avoiding to leak out the bridge Int<->Value to other parts of the framework/application
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 let's limit it to this specific use case as you propose then, it's probably the safest and more useful thing to do.
Besides adding the +
and -
operators with Int
and CGFloat
/Double
versions, do you prefer we keep also the ones accepting Value
s (in case I already have a Value
instance I want to use as a offset – which would be rare) or we remove them?
} | ||
} | ||
|
||
extension CGFloat { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove these from this PR and move this discussion in another issue/PR
Everything on the list should be good (no readme changes nor new tests needed).
Done. |
… methods `scalable` and `fixed`
…loat as right-hand side argument
I've
|
This PR adds a small DSL intended to improve readability and speed of development when laying out
PlasticView
s, i.e. settingAnchor
s with offsets.The current way to set an anchor to a
PlasticView
with an offset is something like:With this DSL, the above example would turn into:
The contents of this PR are (see each commit message for more details):
Add
offset
property toAnchor
Add ability to add an offset to an anchor through
+
and-
operatorsMake
Value
conform toExpressibleByIntegerLiteral
andExpressibleByFloatLiteral
Add
scaled
andfixed
properties toCGFloat
,Double
andInt
as a convenient way to instantiateValue
instances