mirror of
https://github.com/cyanfish/naps2.git
synced 2024-10-26 17:11:21 +03:00
Implement layout alignment and fixed dimensions
This commit is contained in:
parent
14b1af5deb
commit
d94658d970
@ -14,7 +14,8 @@ public class ControlWithLayoutAttributes : LayoutElement
|
||||
|
||||
public ControlWithLayoutAttributes(
|
||||
ControlWithLayoutAttributes control, bool? center = null, bool? xScale = null, bool? yScale = null,
|
||||
bool? autoSize = null, Padding? padding = null, int? width = null, int? height = null)
|
||||
bool? autoSize = null, Padding? padding = null, int? width = null, int? height = null,
|
||||
LayoutAlignment? alignment = null)
|
||||
{
|
||||
Control = control.Control;
|
||||
Center = center ?? control.Center;
|
||||
@ -24,6 +25,7 @@ public class ControlWithLayoutAttributes : LayoutElement
|
||||
Padding = padding ?? control.Padding;
|
||||
Width = width ?? control.Width;
|
||||
Height = height ?? control.Height;
|
||||
Alignment = alignment ?? control.Alignment;
|
||||
}
|
||||
|
||||
public static implicit operator ControlWithLayoutAttributes(Control control) =>
|
||||
@ -72,6 +74,7 @@ public class ControlWithLayoutAttributes : LayoutElement
|
||||
var text = Control is TextControl txt ? $"\"{txt.Text}\" " : "";
|
||||
Debug.WriteLine($"{new string(' ', context.Depth)}{text} layout with bounds {bounds}");
|
||||
}
|
||||
bounds.Size = UpdateFixedDimensions(bounds.Size);
|
||||
if (Control != null)
|
||||
{
|
||||
var location = new PointF(bounds.X + Padding.Left, bounds.Y + Padding.Right);
|
||||
@ -90,9 +93,23 @@ public class ControlWithLayoutAttributes : LayoutElement
|
||||
EnsureIsAdded(context);
|
||||
size = EtoPlatform.Current.GetPreferredSize(Control, parentBounds.Size);
|
||||
}
|
||||
size = UpdateFixedDimensions(size);
|
||||
return new SizeF(size.Width + Padding.Horizontal, size.Height + Padding.Vertical);
|
||||
}
|
||||
|
||||
private SizeF UpdateFixedDimensions(SizeF size)
|
||||
{
|
||||
if (Width != null)
|
||||
{
|
||||
size.Width = Width.Value;
|
||||
}
|
||||
if (Height != null)
|
||||
{
|
||||
size.Height = Height.Value;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private void EnsureIsAdded(LayoutContext context)
|
||||
{
|
||||
if (context.IsFirstLayout && !_isAdded)
|
||||
|
@ -64,6 +64,12 @@ public static class EtoLayoutExtensions
|
||||
new ControlWithLayoutAttributes(control, xScale: true);
|
||||
public static ControlWithLayoutAttributes YScale(this Control control) =>
|
||||
new ControlWithLayoutAttributes(control, yScale: true);
|
||||
public static ControlWithLayoutAttributes AlignCenter(this Control control) =>
|
||||
new ControlWithLayoutAttributes(control, alignment: LayoutAlignment.Center);
|
||||
public static ControlWithLayoutAttributes AlignLeading(this Control control) =>
|
||||
new ControlWithLayoutAttributes(control, alignment: LayoutAlignment.Leading);
|
||||
public static ControlWithLayoutAttributes AlignTrailing(this Control control) =>
|
||||
new ControlWithLayoutAttributes(control, alignment: LayoutAlignment.Trailing);
|
||||
public static ControlWithLayoutAttributes AutoSize(this Control control) =>
|
||||
new ControlWithLayoutAttributes(control, autoSize: true);
|
||||
public static ControlWithLayoutAttributes Padding(this Control control, Padding padding) =>
|
||||
@ -85,6 +91,12 @@ public static class EtoLayoutExtensions
|
||||
new ControlWithLayoutAttributes(control, xScale: true);
|
||||
public static ControlWithLayoutAttributes YScale(this ControlWithLayoutAttributes control) =>
|
||||
new ControlWithLayoutAttributes(control, yScale: true);
|
||||
public static ControlWithLayoutAttributes AlignCenter(this ControlWithLayoutAttributes control) =>
|
||||
new ControlWithLayoutAttributes(control, alignment: LayoutAlignment.Center);
|
||||
public static ControlWithLayoutAttributes AlignLeading(this ControlWithLayoutAttributes control) =>
|
||||
new ControlWithLayoutAttributes(control, alignment: LayoutAlignment.Leading);
|
||||
public static ControlWithLayoutAttributes AlignTrailing(this ControlWithLayoutAttributes control) =>
|
||||
new ControlWithLayoutAttributes(control, alignment: LayoutAlignment.Trailing);
|
||||
public static ControlWithLayoutAttributes AutoSize(this ControlWithLayoutAttributes control) =>
|
||||
new ControlWithLayoutAttributes(control, autoSize: true);
|
||||
public static ControlWithLayoutAttributes Padding(this ControlWithLayoutAttributes control, Padding padding) =>
|
||||
|
9
NAPS2.Lib/EtoForms/Layout/LayoutAlignment.cs
Normal file
9
NAPS2.Lib/EtoForms/Layout/LayoutAlignment.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace NAPS2.EtoForms.Layout;
|
||||
|
||||
public enum LayoutAlignment
|
||||
{
|
||||
Fill,
|
||||
Leading,
|
||||
Center,
|
||||
Trailing
|
||||
}
|
@ -40,6 +40,12 @@ public class LayoutColumn : LayoutLine<LayoutRow>
|
||||
return position;
|
||||
}
|
||||
|
||||
protected override PointF UpdateOrthogonalPosition(PointF position, float delta)
|
||||
{
|
||||
position.X += delta;
|
||||
return position;
|
||||
}
|
||||
|
||||
protected override SizeF UpdateTotalSize(SizeF size, SizeF childSize, int spacing)
|
||||
{
|
||||
size.Height += childSize.Height + spacing;
|
||||
|
@ -9,6 +9,7 @@ public abstract class LayoutElement
|
||||
|
||||
protected internal bool XScale { get; set; }
|
||||
protected internal bool YScale { get; set; }
|
||||
protected internal LayoutAlignment Alignment { get; set; }
|
||||
|
||||
public abstract void AddTo(DynamicLayout layout);
|
||||
|
||||
|
@ -13,6 +13,8 @@ public abstract class LayoutLine<TOrthogonal> : LayoutContainer
|
||||
|
||||
protected abstract PointF UpdatePosition(PointF position, float delta);
|
||||
|
||||
protected abstract PointF UpdateOrthogonalPosition(PointF position, float delta);
|
||||
|
||||
protected abstract SizeF UpdateTotalSize(SizeF size, SizeF childSize, int spacing);
|
||||
|
||||
public override void DoLayout(LayoutContext context, RectangleF bounds)
|
||||
@ -27,15 +29,40 @@ public abstract class LayoutLine<TOrthogonal> : LayoutContainer
|
||||
var spacing = Spacing ?? context.DefaultSpacing;
|
||||
UpdateCellLengthsForAvailableSpace(cellLengths, cellScaling, bounds, spacing);
|
||||
|
||||
// The "cell" size and origin define the space the control can fit in, while the "child" size and origin define
|
||||
// the actual space the control fills. The child always fills the cell length-wise, but breadth-wise it depends
|
||||
// on the control alignment.
|
||||
var cellOrigin = bounds.Location;
|
||||
for (int i = 0; i < Children.Length; i++)
|
||||
{
|
||||
var child = Children[i];
|
||||
var cellSize = GetSize(cellLengths[i], GetBreadth(bounds.Size));
|
||||
Children[i].DoLayout(childContext, new RectangleF(cellOrigin, cellSize));
|
||||
cellOrigin = UpdatePosition(cellOrigin, GetLength(cellSize) + spacing);
|
||||
GetChildSizeAndOrigin(child, childContext, cellSize, cellOrigin,
|
||||
out var childSize, out var childOrigin);
|
||||
child.DoLayout(childContext, new RectangleF(childOrigin, childSize));
|
||||
cellOrigin = UpdatePosition(cellOrigin, GetLength(childSize) + spacing);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetChildSizeAndOrigin(LayoutElement child, LayoutContext childContext,
|
||||
SizeF cellSize, PointF cellOrigin, out SizeF childSize, out PointF childOrigin)
|
||||
{
|
||||
var breadth = GetBreadth(
|
||||
child.Alignment == LayoutAlignment.Fill
|
||||
? cellSize
|
||||
: child.GetPreferredSize(childContext, new RectangleF(cellOrigin, cellSize)));
|
||||
var remainingBreadth = GetBreadth(cellSize) - breadth;
|
||||
var alignmentOffset = child.Alignment switch
|
||||
{
|
||||
LayoutAlignment.Leading => 0,
|
||||
LayoutAlignment.Center => remainingBreadth / 2,
|
||||
LayoutAlignment.Trailing => remainingBreadth,
|
||||
_ => 0
|
||||
};
|
||||
childSize = GetSize(GetLength(cellSize), breadth);
|
||||
childOrigin = UpdateOrthogonalPosition(cellOrigin, alignmentOffset);
|
||||
}
|
||||
|
||||
public override SizeF GetPreferredSize(LayoutContext context, RectangleF parentBounds)
|
||||
{
|
||||
var childContext = GetChildContext(context, parentBounds);
|
||||
|
@ -46,6 +46,12 @@ public class LayoutRow : LayoutLine<LayoutColumn>
|
||||
return position;
|
||||
}
|
||||
|
||||
protected override PointF UpdateOrthogonalPosition(PointF position, float delta)
|
||||
{
|
||||
position.Y += delta;
|
||||
return position;
|
||||
}
|
||||
|
||||
protected override SizeF UpdateTotalSize(SizeF size, SizeF childSize, int spacing)
|
||||
{
|
||||
size.Width += childSize.Width + spacing;
|
||||
|
@ -131,7 +131,7 @@ public class EditProfileForm : EtoDialogBase
|
||||
C.Label(UiStrings.BrightnessLabel),
|
||||
L.Row(
|
||||
_brightnessSlider.XScale(),
|
||||
_brightnessText.Width(40)
|
||||
_brightnessText.Width(50).AlignCenter()
|
||||
)
|
||||
).XScale(),
|
||||
L.Column(
|
||||
@ -144,7 +144,7 @@ public class EditProfileForm : EtoDialogBase
|
||||
C.Label(UiStrings.ContrastLabel),
|
||||
L.Row(
|
||||
_contrastSlider.XScale(),
|
||||
_contrastText.Width(40)
|
||||
_contrastText.Width(50).AlignCenter()
|
||||
)
|
||||
).XScale()
|
||||
),
|
||||
@ -166,10 +166,9 @@ public class EditProfileForm : EtoDialogBase
|
||||
var buffer = new Size(130, 0);
|
||||
FormStateController.MinimumClientSize = naturalSize;
|
||||
FormStateController.DefaultClientSize = naturalSize + buffer;
|
||||
FormStateController.RestoreFormState = false;
|
||||
FormStateController.RestoreFormState = true;
|
||||
}
|
||||
|
||||
|
||||
public bool Result => _result;
|
||||
|
||||
public ScanProfile ScanProfile
|
||||
|
@ -131,7 +131,7 @@ public class ProfilesForm : EtoDialogBase
|
||||
L.Row(
|
||||
_listView.Control.XScale(),
|
||||
C.Button(_scanCommand, Icons.control_play_blue.ToEtoImage(), ButtonImagePosition.Above).AutoSize()
|
||||
.Height(100)
|
||||
.Height(80)
|
||||
).Aligned().YScale(),
|
||||
L.Row(
|
||||
L.Column(
|
||||
|
Loading…
Reference in New Issue
Block a user