-
Notifications
You must be signed in to change notification settings - Fork 703
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
Simplify LayoutStyle
- Make it a computed/read-only property ensure correctness
#3127
Comments
If you saw my comment #3019 (comment) you'll understand why. Absolute layout must be respected if frame is provided. When a view is added to another view the |
I'm having a really hard time with your English. It is NOT your fault, but I struggle to parse your writing sometimes and instead of digging in I just give up. This is my bad as I should be more patient. I'm going to try to echo back the above as clearly as I can... (Ignoring
|
Coul LayoutStyle be get only?
I.e.
Return x.isRelative or y.IsRelative or width.IsRelative etc?
…On Fri, 5 Jan 2024, 17:02 Tig, ***@***.***> wrote:
If you saw my comment #3019 (comment)
<#3019 (comment)>
you'll understand why. Absolute layout must be respected if frame is
provided. When a view is added to another view the Pos/Dim properties
must be set even to a view that has LayoutStyle.Absolute to automatically
position with other views. Thus they don't to have run the
SetRelativeLayout method but others views with LayoutStyle.Computed can
access to his Pos/Dim to calculate the right location and dimension. So
LayoutStyte.Computed can have absolute location and dimension, the
diference is in this case SetRelativeLayout can be called and with
LayoutStyte.Absolute can't.
I'm having a really hard time with your English. It is NOT your fault, but
I struggle to parse your writing sometimes and instead of digging in I just
give up. This is my bad as I should be more patient.
I'm going to try to echo back the above as clearly as I can...
(Ignoring AutoSize use-cases)
SetRelativeLayout
You assert that if view.LayoutStyle == LayoutStyle.Absolute the
SetRelativeLayout method should not be called. I disagree. it can and
should work if view.LayoutStyle == LayoutStyle.Absolute *as long as* X, Y,
Width, and Height match Frame and are Dim/PosAbsolute.
In the code right now, when Frame is set, we do NOT set these properties
(even though the API docs say we do):
/// <summary>/// Gets or sets location and size of the view. The frame is relative to the <see cref="SuperView"/>'s/// <see cref="Bounds"/>./// </summary>/// <value>/// The rectangle describing the location and size of the view, in coordinates relative to the/// <see cref="SuperView"/>./// </value>/// <remarks>/// <para>/// Change the Frame when using the <see cref="LayoutStyle.Absolute"/> layout style to move or resize views./// </para>/// <para>/// Altering the Frame will change <see cref="LayoutStyle"/> to <see cref="LayoutStyle.Absolute"/>./// Additionally, <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, and <see cref="Height"/> will be set/// to the values of the Frame (using <see cref="Pos.PosAbsolute"/> and <see cref="Dim.DimAbsolute"/>)./// </para>/// <para>/// Altering the Frame will eventually (when the view is next drawn) cause the/// <see cref="LayoutSubview(View, Rect)"/>/// and <see cref="OnDrawContent(Rect)"/> methods to be called./// </para>/// </remarks>public virtual Rect Frame {
get => _frame;
set {
_frame = new Rect (value.X, value.Y, Math.Max (value.Width, 0), Math.Max (value.Height, 0));
//X = _frame.X;
//Y = _frame.Y;
//Width = _frame.Width;
//Height = _frame.Height;
if (IsInitialized || LayoutStyle == LayoutStyle.Absolute) {
LayoutFrames ();
TextFormatter.Size = GetTextFormatterSizeNeededForTextAndHotKey ();
SetNeedsLayout ();
SetNeedsDisplay ();
}
}}
I think we should uncomment that code, and change the unit tests as needed.
I also think we should change the X, Y, Height, and Width setters to NOT
throw if view.LayoutStyle == LayoutStyle.Computed and they are set to
Pos/DimAbsolute as there is nothing wrong with doing so.
If view.LayoutStyle == LayoutStyle.Absolute and X, Y, Height, or Width
are set to NON-Absolute values, we should either throw an exception or
force view.LayoutStyle to be LayoutStyle.Computed.
Do you agree?
—
Reply to this email directly, view it on GitHub
<#3127 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHO3C5F6R5NOVWJV4PHYGE3YNAW35AVCNFSM6AAAAABBOSSLT6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZYHE4DOOJZGQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Your problem, not mine. I also have to be very patient when I expose my point of view in vain and much time later you sometimes end up to give me raison.
I meant that if
I think there are tons of code like if (view.Frame.X == intValue) and others which probe that the
I absolutely agree. I think that is an absurd.
Yes I agree. This isn't so greave as the opposite by force |
Well I think that can be possible. Remember the v2 is completely a new version and many though can be changed. I only saw your comment now and it could be acceptable, if @tig also agree. In this case we will rely on Pos/Dim which mustn't be null after it's initialized. But if a user set Pos/Dim to null? What the API should do? |
I actually tried that in #2467, but backed it out. Some of the code is still there commented out because I think it may be the right thing to do: public LayoutStyle LayoutStyle {
get => _layoutStyle;
//if ((X == null || X is Pos.PosAbsolute) && (Y == null || Y is Pos.PosAbsolute) &&
//(Width == null || Width is Dim.DimAbsolute) && (Height == null || Height is Dim.DimAbsolute)) {
// return LayoutStyle.Absolute;
//} else {
// return LayoutStyle.Computed;
//}
set {
_layoutStyle = value;
//switch (_layoutStyle) {
//case LayoutStyle.Absolute:
// X = Frame.X;
// Y = Frame.Y;
// Width = Frame.Width;
// Height = Frame.Height;
// break;
//case LayoutStyle.Computed:
// X ??= Frame.X;
// Y ??= Frame.Y;
// Width ??= Frame.Width;
// Height ??= Frame.Height;
// break;
//}
SetNeedsLayout ();
}
} |
I also think it's be better solution, using only the get. If the user set the Pos/Dim to null the |
I think you're asking "if I have considered (and I think I actually implemented but backed it out). Note `// BUGBUG: public Pos X {
get => VerifyIsInitialized (_x, nameof (X));
set {
// BUGBUG: null is the sames a Pos.Absolute(0). Should we be explicit and set it?
if (ValidatePosDim && LayoutStyle == LayoutStyle.Computed) {
CheckAbsolute (nameof (X), _x, value);
}
_x = value;
OnResizeNeeded ();
}
} Proposed version: public Pos X {
get => VerifyIsInitialized (_x, nameof (X));
set {
if (ValidatePosDim && LayoutStyle == LayoutStyle.Computed) {
CheckAbsolute (nameof (X), _x, value);
}
_x = value ?? Pos.At (0);
OnResizeNeeded ();
}
} |
Can you explain this further? My understanding is that if |
Actually, given all of this discussion the new version would be: public Pos X {
get => VerifyIsInitialized (_x, nameof (X));
set {
_x = value ?? Pos.At (0);
OnResizeNeeded ();
}
} |
I think we shouldn't set it as 0. The user may want them as null to force the app use the |
/// <summary>
/// Method invoked when a subview is being added to this view.
/// </summary>
/// <param name="e">Event where <see cref="ViewEventArgs.View"/> is the subview being added.</param>
public virtual void OnAdded (SuperViewChangedEventArgs e)
{
var view = e.Child;
view.IsAdded = true;
view.OnResizeNeeded ();
view._x ??= view._frame.X;
view._y ??= view._frame.Y;
view._width ??= view._frame.Width;
view._height ??= view._frame.Height;
view.Added?.Invoke (this, e);
} If we force /// <summary>
/// Method invoked when a subview is being added to this view.
/// </summary>
/// <param name="e">Event where <see cref="ViewEventArgs.View"/> is the subview being added.</param>
public virtual void OnAdded (SuperViewChangedEventArgs e)
{
var view = e.Child;
view.IsAdded = true;
view.OnResizeNeeded ();
view.Added?.Invoke (this, e);
} Can you expand on this: "allow that other views can use his Pos/Dim (location/dimension)."? |
I do not see where |
Can you explain why someone would want to do this? What is the use-case? |
Ahhh. Right. Note the comment though: If we forced Likewise for the |
A better search: etc... If we made the change, all of these would be needed to be cleaned up, but nothing works differently. E.g. this code in Is already testing for both |
Before were considered the
If forcing is to be used then is better using the
Using your idea, yes. Another thinking I had is the |
No needed. See bellow.
Yes and the Pos/Dim properties should return 0 from the getter if they are null.
This has no sense now since the |
But I never said the |
A PR for this stuff... So far i just fixed the CheckAbsoulte issue. |
I think so. Like this: public LayoutStyle LayoutStyle {
get {
if (X is Pos.PosAbsolute && Y is Pos.PosAbsolute && Width is Dim.DimAbsolute && Height is Dim.DimAbsolute) {
return LayoutStyle.Absolute;
} else {
return LayoutStyle.Computed;
}
}
set {
X = Frame.X;
Y = Frame.Y;
Width = Frame.Width;
Height = Frame.Height;
SetNeedsLayout ();
}
} |
I don't understands the needed of the |
_x ??= _frame.X;
_y ??= _frame.Y;
_width ??= _frame.Width;
_height ??= _frame.Height; This code can also be used at |
How's this? [Fact]
[TestRespondersDisposed]
public void AbsoluteLayout_Constructor ()
{
var frame = Rect.Empty;
var v = new View (frame);
Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
Assert.Equal (frame, v.Frame);
Assert.Equal (new Rect (0, 0, frame.Width, frame.Height), v.Bounds); // With Absolute Bounds *is* deterministic before Layout
Assert.Equal (Pos.At (0), v.X);
Assert.Equal (Pos.At (0), v.Y);
Assert.Equal (Dim.Sized (0), v.Width);
Assert.Equal (Dim.Sized (0), v.Height);
v.Dispose ();
frame = new Rect (1, 2, 3, 4);
v = new View (frame);
Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
Assert.Equal (frame, v.Frame);
Assert.Equal (new Rect (0, 0, frame.Width, frame.Height), v.Bounds); // With Absolute Bounds *is* deterministic before Layout
Assert.Equal (Pos.At (1), v.X);
Assert.Equal (Pos.At (2), v.Y);
Assert.Equal (Dim.Sized (3), v.Width);
Assert.Equal (Dim.Sized (4), v.Height);
v.Dispose ();
v = new View (frame, "v");
Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
Assert.Equal (frame, v.Frame);
Assert.Equal (new Rect (0, 0, frame.Width, frame.Height), v.Bounds); // With Absolute Bounds *is* deterministic before Layout
Assert.Equal (Pos.At (1), v.X);
Assert.Equal (Pos.At (2), v.Y);
Assert.Equal (Dim.Sized (3), v.Width);
Assert.Equal (Dim.Sized (4), v.Height);
v.Dispose ();
v = new View (frame.X, frame.Y, "v");
Assert.True (v.LayoutStyle == LayoutStyle.Absolute);
// BUGBUG: v2 - I think the default size should be 0,0 not 1,1
Assert.Equal (new Rect (frame.X, frame.Y, 1, 1), v.Frame);
Assert.Equal (new Rect (0, 0, 1, 1), v.Bounds); // With Absolute Bounds *is* deterministic before Layout
Assert.Equal (Pos.At (1), v.X);
Assert.Equal (Pos.At (2), v.Y);
Assert.Equal (Dim.Sized (1), v.Width);
Assert.Equal (Dim.Sized (1), v.Height);
v.Dispose ();
} This seems correct to me. You? Related note |
Good point. If But if a) Ignore it. |
Yes it's correct. Also I'll have more headaches to me resolve more merge conflicts.
Well as you know that is the text auto size |
Only handle this on their own properties only when the user change them. The point is I'm not understands why you have a setter on the
If |
@tznind |
I will make it readonly. I'm leaving the getter for now so compiling still works. For now it's: public LayoutStyle LayoutStyle {
get {
if (_x is Pos.PosAbsolute && _y is Pos.PosAbsolute && _width is Dim.DimAbsolute && _height is Dim.DimAbsolute) {
return LayoutStyle.Absolute;
} else {
return LayoutStyle.Computed;
}
}
set {
throw new InvalidOperationException ("LayoutStyle is read-only.");
}
} |
That the way I think i should be, but I'm curious about the @tznind comment 😃 |
I've decided we should throw an exception of someone tries to set This simplifies a ton and I really don't like setters that do automatic stuff. public Pos Y {
get => VerifyIsInitialized (_y, nameof (Y));
set {
_y = value ?? throw new ArgumentNullException (nameof (value), !@$"{nameof (Y)} cannot be null");
OnResizeNeeded ();
}
} |
That was really the only bit I was trying to get across
I guess I was thinking that each Pos/Dim is either absolute or relative. So a view will also have its layout be relative if any of its dimensions is relative. I also think that we should not allow |
But the Pos/Dim already define what is absolute or relative. PosAbsolute and DimAbsolute are absolute and PosView and DimView or other than PosAbsolute or DimAbsolute are relative. Do you really think that is needed?
I agree. |
LayoutStyle
is complex, confusing, and not really "Correct". E.g. View.CheckAbsolute
.
LayoutStyle
is complex, confusing, and not really "Correct". E.g. View.CheckAbsolute
.LayoutStyle
- Make it a computed/read-only property and simplify
LayoutStyle
- Make it a computed/read-only property and simplifyLayoutStyle
- Make it a computed/read-only property ensure correctness
…works. Fixes `AutoSize` etc... (#3130) * Removes CheckAbsoulte and updates unit tests to match * Fixed code that was dependent on ToString behavior vs. direct test for null * Dim/Pos != null WIP * Moved AutoSize specific tests out of Pos/Dim tests * Broke out AutoSize = false tests to new file * Commented test TODOs * New test * Removed unused API and cleaned up code * Removed unused API and cleaned up code * Cleaned up code * Cleaned up code * reorg'd Toplevel tests * Fixed Create and related unit tests * Added test from #3136 * Removed TopLevel.Create * Fixed SetCurrentOverlappedAsTop * Updated pull request template * Updated pull request template * Revert "Updated pull request template" This reverts commit d807190. * reverting * re-reverting * Fixed every thing but autosize scenarios?? * Fixed hexview * Fixed contextmenu * Fixed more minor issues in tests * Fixed more minor issues in tests * Debugging Dialog test failure * Fixed bad Dialog test. Was cleary invalid * Fixed OnResizeNeeded bug * Fixed OnResizeNeeded bug * Fixed UICatalog to not eat exceptions * Fixed TextView * Removed Frame overrides * Made Frame non-virtual * Fixed radioGroup * Fixed TabView * Hcked ScrolLBarView unit tests to pass * All AutoSize tests pass! * All tests pass!!!!!!! * Updated API docs. Cleaned up code. * Fixed ColorPicker * Added 'Bounds =' unit tests * Refactored TextFormatter.Size setting logic * Cleaned up OnResizeNeeded (api docs and usages) * Merges in #3019 changes. Makes OnResizeNeeded non-virtual. If we find a use-case where someone wants to override it we can change this back. * Fixed FileDialog bounds warning * Removed resharper settings from editorconfig * Added Pos.Center test to AllViewsTests.cs. Modernized RadioGroup. Fixed ProgressBar. * Reverted formatting * Reverted formatting * Reverted formatting * Reverted formatting * Reverted formatting * Reverted formatting * Reverted formatting * Code cleanup * Code cleanup * Code cleanup * Code cleanup * Code cleanup * Code cleanup * Code cleanup * Code cleanup * Reverted formatting
I've confused myself (again) around ComputedLayout.
I noticed this morning we throw an exception of Width or Height is absolute and ComputedLayout is set.
Does this actually make sense?
Did I do this?
Why?
Why can't someone force a view to a fixed size even when using ComputedLayout?
Maybe I just need more coffee?
The text was updated successfully, but these errors were encountered: