Terminal.Gui
Terminal.Gui copied to clipboard
Finish `Dim.Auto` - `DimAutoStyle.Content` is half-baked
This feature has been partially implemented. DimAutoStyle.Text works great and fully replaced View.AutoSize. However, DimAutoStyle.Computed is still a WIP. We'll close this issue once it's fully implemented and tested.
Background
See #2431 for some context.
Multiple times I've wanted to have a view dynamically be sized based on it's subviews. Also we have AutoSize which sorta does this for Text.
I'd like to propose the following for v2:
- A new feature for ComputedLayout that adds
Dim.Auto () - Replace
AutoSizewith something that builds onDim.Auto ()
I think this should be possible, but haven't thought THAT much about it.
view.Height = Dim.Auto (); // Height will be Margin.Height+Padding.Height+Border.Height+(height required for all Subviews to fit).
I love this idea. But I wonder if Fit sounds too close to Fill? We need to reinforce that (unlike other Dims) this is about the size of its children (not the available bounds of parent). Maybe something like Grow? I.e. its size grows based on its content? Or Dim.AutoSize() or just Dim.Auto()?
You could have it take a maximum:
Dim.Grow(25)resizes based on children to a max of 25 units
Maybe if its possible we could even give the max as a Dim (although that may be too far)
Dim.Grow(Dim.Percent(50))would grow based on size of children up to 50% of width available.
Yes, I think it's a good idea. It's ideal for calculating content size to fit all views with the total of horizontal and vertical size. This size could be used on scroll bars to navigate through all the views. Some recursive method that will filter the sum of views size.
I love this idea. But I wonder if
Fitsounds too close toFill? We need to reinforce that (unlike other Dims) this is about the size of its children (not the available bounds of parent). Maybe something likeGrow? I.e. its size grows based on its content? OrDim.AutoSize()or justDim.Auto()?You could have it take a maximum:
Dim.Grow(25)resizes based on children to a max of 25 unitsMaybe if its possible we could even give the max as a
Dim(although that may be too far)
Dim.Grow(Dim.Percent(50))would grow based on size of children up to 50% of width available.
Def worth thinking about more!
I still like the simplicity of "Make the dimension just big enough to fit the subviews."
I just realized that with the new View design, my example above of view.Width = Dim.Fit(1); could be achieved with:
view.Padding.Thickness = new Thickness (1,1,1,1);
view.Width = Dim.Fit ();
So, using the parameter for "Make the dimension just big enough to fit the subviews, plus a little more" isn't necessary. This does open up the possibility of a Max (and Min) parameter as you suggest.
Instead of:
view.Padding.Thickness = new Thickness (1,1,1,1);
you can use:
view.Padding.Thickness = new Thickness (1);
because the constructor will fill all the sides with the same size, at least the struct on the Border does.
Instead of:
view.Padding.Thickness = new Thickness (1,1,1,1);you can use:view.Padding.Thickness = new Thickness (1);because the constructor will fill all the sides with the same size, at least the struct on theBorderdoes.
I knew that, but wanted to make it clear to people who aren't familiar with Thickness that it has 4 dimensions.
In my View prototype I've added Vertical and Horizontal properties too:
public int Vertical {
get {
return Top + Bottom;
}
set {
Top = Bottom = value / 2;
}
}
public int Horizontal {
get {
return Left + Right;
}
set {
Left = Right = value / 2;
}
}
@tig do you agree that absolute Pos/Dim values must always have the same location and dimension values of the Frame no matter is layout style is Absolute or Computed. e.g. With a Frame=Rect(1, 2, 10, 20), will result on a Pos/Dim (X=1, Y=2, Width=10, Height=20).
Edit:
Forget this please. Of course it can't, because with AutoSize we manipulate the frame but keep the Pos/Dim.
I now think Dim.AutoSize () might be the right name for this.
Implementing was ridiculously easy (I've done very little testing, so something is probably broken).
var textField = new TextField { Text = "Type here", X = 1, Y = 0, Width = 20, Height = 1 };
var label = new Label {
X = Pos.Left (textField),
Y = Pos.Bottom (textField),
AutoSize = true,
};
textField.TextChanged += (s, e) => {
label.Text = textField.Text;
};
var button = new Button () { Text = "Press to make button move down.",
X = Pos.Center(),
Y = Pos.Bottom (label),
};
button.Clicked += (s, e) => {
button.Y = button.Frame.Y + 1;
};
var view = new FrameView () {
Title = "Type in the TextField to make it grow.",
X = 3,
Y = 3,
Width = Dim.AutoSize (),
Height = Dim.AutoSize ()
};
view.Add (textField, label, button);
Auto wins.
Dim.Auto and not Dim.Auot 😃
DimAutoStyle.Text is now complete and merged in #3416.
Now we need to address:
- [ ] Fully implement/test
DimAutoStyle.Content - [ ] Implemement
Dim.AutoSize (max: dim) - [ ] Use
DialogandMessageBoxas test cases - This will require moving the dialog buttons toPaddingas adornments. - [ ] Dive deep into all other PosDim objects and get clarity on behavior relative to
Dim.Auto- Improve unit tests to validate- [x]
Dim.Absolute - [ ]
Dim.Auto - [ ]
Dim.Fill - [ ]
Dim.Function - [ ]
Dim.Width/Height - [x]
Pos.Absolute/At - [ ]
Pos.AnchorEnd - [ ]
Pos.Function - [ ]
Pos.Anchor - [ ]
Pos.Percent - [ ]
Pos.Center - [ ]
Pos.X/Yetc...
- [x]