Comments (12)
This unit test proves what I meant. In this case, I think that adding and removing a view is not the best option and in this case, let the layout deal with it based on the Visibility
property.
[Fact]
public void Removing_View_Referenced_On_Another_View_Throws_On_LayoutSubviews ()
{
var view1 = new View { Width = 10, Height = 1 };
var view2 = new View { X = Pos.Right (view1), Width = 10, Height = 1 };
var view3 = new View { X = Pos.Right (view2), Width = 10, Height = 1 };
var top = new View { Width = 30, Height = 1 };
top.Add (view1, view2, view3);
top.LayoutSubviews ();
Assert.Equal (new (0, 0, 10, 1), view1.Frame);
Assert.Equal (new (10, 0, 10, 1), view2.Frame);
Assert.Equal (new (20, 0, 10, 1), view3.Frame);
view2.Visible = false;
top.Remove (view2);
Exception exception = Record.Exception (() => top.LayoutSubviews ());
// Throw view was not found
Assert.NotNull (exception);
}
@tig if you proceed with the Visibility
enum I suggest changing HiddenFromLayout
to HiddenWidthFromLayout
and adding HiddenHeightFromLayout
, because there may only be a need to ignore just one of the sizes, both or none of the layout.
from terminal.gui.
This is for Shortcut which has 3 subviews that I'm using Pos.Align. If, say, [...]
This code makes the most sense to me. Nice and un ambigious
[...]
var view2 = new View { X = Pos.Right (view1), Width = 10, Height = 1 };
I don't think adding a 'hide from layout' state improves matters in this scenario.
If view1
is opting out of layout then it doesn't have a position so really you should still be throwing. Hence I feel that 'hidden from layout' is the same as 'not in the view' (i.e. Remove).
I always found SuspendLayout in winforms to be a bit of a hack. Making it a 'per view' state that affects positioning of other siblings (not just children) sounds like recipie for disaster.
I'm all for any helper methods that make things easier. For example I handle this situation in TGD to do things like:
- prevent deleting a View if another has e.g. a Pos.Left dependency on it
- AND that other view is not also being deleted at the same time (e.g. as part of multi select delete)
private bool DependsOnUs(Design other, Design[] everyone)
{
// obviously we cannot depend on ourselves
if (other == this)
{
return false;
}
// if their X depends on us
if (other.View.X.GetPosType(everyone, out _, out _, out var relativeTo, out _, out _))
{
if (relativeTo == this)
{
return true;
}
}
// if their Y depends on us
if (other.View.Y.GetPosType(everyone, out _, out _, out relativeTo, out _, out _))
{
if (relativeTo == this)
{
return true;
}
}
return false;
}
from terminal.gui.
I have come across this same dilemma several times, especially when dealing with layout-related code. I still thought of another option that you didn't mention, which was to let the user worry about this, subscribing to the LayoutStarted
event and then defining the Pos/Dim
depending on whether the subview is visible or not.
Given that I deeply value automation, making life as easy as possible for the user in development, I would opt for suggestion 3.
from terminal.gui.
One challenge with this is dealing with other subviews that reference the view being "hidden".
There will need to be logic that at least lets devs know this is not supported (debug spew or exception).
from terminal.gui.
One challenge with this is dealing with other subviews that reference the view being "hidden".
I understand your point of view. Visibility.HiddenFromLayout
should only affect Dim
and not Pos
, as this will always have the same value. Dim
must return 0 if it is Visibility.HiddenFromLayout
, otherwise the defined value will be calculated. Imagine the following scenario (no tested):
var view1 = new View { Width = 10, Height = 1 };
var view2 = new View { X = Pos.Right(view1), Width = 10, Height = 1, Visibility = Visibility.HiddenFromLayout };
var view3 = new View { X = Pos.Right(view2), Width = 10, Height = 1 };
The position of view3.Frame.X
will be 10 (10 returned from the width of view1 + 0 returned from view2). If view2 has the Visibility
property as Visible
or Hidden
, then the position of view3.Frame.X
will be 20 (10 returned from view1's width + 10 returned from view2).
There will need to be logic that at least lets devs know this is not supported (debug spew or exception).
If it is actually not implemented then developers should know that it is not supported.
from terminal.gui.
from terminal.gui.
There are situations where I'd like to "hide" a subview from layout.
What is the use case? As an API user I think I would just callRemove
on the view for most cases.
It has logic but what will happen if the Pos/Dim
is referenced in another view? Will it throw an exception? Good question for creating a unit test to check what happens.
from terminal.gui.
There are situations where I'd like to "hide" a subview from layout.
What is the use case? As an API user I think I would just callRemove
on the view for most cases.
…
Message ID: @.***>
Hmmm.... Maybe I have been over thinking this! I think you may be right that Remove
/Add
is all I need. Will ponder and report back.
from terminal.gui.
FWIW, for my immediate case, add/remove is working fine. I say we leave this Issue open though.
from terminal.gui.
And MFWIW (Moar For What It's Worth):
This is for Shortcut
which has 3 subviews that I'm using Pos.Align
. If, say, HelpText
is not set, I want to hide the view from layout so it's like it doesn't exist. Here's the current logic. Note I have to ensure the order of Add is consistent so Pos.Align works properly.
RemoveAll ();
if (!string.IsNullOrEmpty (CommandView.Text))
{
Add (CommandView);
}
if (!string.IsNullOrEmpty (HelpView.Text))
{
Add (HelpView);
}
if (Key != Key.Empty)
{
Add (KeyView);
}
from terminal.gui.
I still think that the location is always calculated regardless of whether it is visible or not. Only the dimension will be calculated or not if it is included or excluded from the layout, respectively. The location will always have the correct value calculated, regardless of whether it is visible or not and that value will be used by any view that is referencing it. If the view is invisible and excluded from the layout, the dimension calculation must return 0 (zero). However, if the other view that references the invisible view that is excluded from the layout contains something like X = Pos.Right (view2) + 1
, the value returned will be 0 + 1 = 1
, that is, just the value of Pos.Right (view2)
should return 0 (zero) and the value 1 should remain because it is not relative to view2
.
That's why I think that Pos.Align
doesn't even have to be included in these calculations and removing and adding it will affect performance and can be a bit messy and doesn't solve cases where we just want to exclude one of the sides from the layout.
from terminal.gui.
I don't think adding a 'hide from layout' state improves matters in this scenario.
It doesn't make sense at design time, but only at run time.
If
view1
is opting out of layout then it doesn't have a position so really you should still be throwing. Hence I feel that 'hidden from layout' is the same as 'not in the view' (i.e. Remove).
Yes, you're right, it also threw an exception, but I chose view2 because of the first example.
I always found SuspendLayout in winforms to be a bit of a hack. Making it a 'per view' state that affects positioning of other siblings (not just children) sounds like recipie for disaster.
SuspendLayout
and ResumeLayout
could be of some value especially at design time to prevent TGD from always performing the layout while adding views. It would be great to add them, I think it is activating or deactivating a flag. But of course it has nothing to do with invisible views, it just doesn't perform the layout until ResumeLayout is called.
I'm all for any helper methods that make things easier. For example I handle this situation in TGD to do things like:
- prevent deleting a View if another has e.g. a Pos.Left dependency on it
- AND that other view is not also being deleted at the same time (e.g. as part of multi select delete)
I think that for TGD you will have to deal with these situations, because it is not related to layout but to design, although this check can also be done in TG and would help a lot in cases where it is necessary. In this case the SuspendLayout
and ResumeLayout
methods could be used to prevent the layout from throwing an exception, or take advantage of the exception in a try/catch block to return true or false.
Don't forget that this check will also have to be used for width and height, because Dim may also be referencing a view.
from terminal.gui.
Related Issues (20)
- Make the PowerShell modules arch-agnostic for now HOT 3
- Fail gracefully for impossible hosts HOT 4
- Rename `StateChangedEventArgs<T>` to `CancelEventArgs<T>` HOT 63
- A more reliable means of avoiding errors caused by stdin or stdout redirection
- (Internal) Better regexes for TODO-list items
- Clicking the StatusBar causes the event to be executed more than once. HOT 1
- `Dim.Auto (Content)` is broken if subviews use `Pos.Center` etc... HOT 3
- `StatusBar` should clip, not overwrite, when last item doesn't fit HOT 1
- `TextField` prevents default `Button` from working in some cases HOT 7
- Some more prep for revamped sourcegens and CI HOT 2
- Enabling trim mode breaks program at runtime (v2 only) HOT 16
- v1 - Example.cs does not work HOT 5
- `Button` with `ShadowStyle.Opaque` is broken HOT 5
- `DateField` unit tests fail on `macos.latest` HOT 4
- The exclusion of `.orig` files in `.gitignore` is no longer working
- Color ToString returns "Red" instead of "# HOT 4
- Release v1.17.1 HOT 1
- Localization not working on self-contained single-file. HOT 19
- Post-V2: Rewrite `TextFormatter`
- Feedback: Example HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from terminal.gui.