using Amphora;
using Annulus;
using Azimuth;
using Clave;
using System.Collections.Generic;
using Prism;
namespace Glass.Testbed.TestCases.Controls
{
///
/// Overlapping Windows to drag, resize, raise and close, one with a menu bar, with a button bringing back
/// whatever was closed. The active window's title bar is blue, the others' grey.
///
public class WindowTestCase : TestCase
{
private const int StageHeight = 360;
private static readonly WindowMaterial Frame = new WindowMaterial
{
Background = UiPacksheetMaterials.Panel,
TitleBar = UiPacksheetMaterials.BlueFlatPanel,
Caption = Material.Invisible,
Content = Material.Invisible,
CloseButton = Widgets.CloseButton,
};
// The pack's grey twin of the blue title bar stands in for desaturating it, which tinting can't do. Tinted
// darker, since the white title text is unreadable on it as drawn.
private static readonly WindowMaterial InactiveFrame = Frame with
{
TitleBar = UiPacksheetMaterials.FlatPanel with { TintColor = Colors.Gray },
};
private static readonly string[] FileMenuItems = { "Close" };
private readonly List windows = new List();
private static void AddContentSizeReadout(Window window, ControlContainer into)
{
var readout = new Label(Widgets.FieldTextStyle, "")
{
DebugName = "content size readout",
Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(160, 40)),
};
into.Add(readout);
void ShowContentSize(Vector contentSize)
{
readout.Text = $"{contentSize.X:F0} x {contentSize.Y:F0}";
}
ShowContentSize(window.ContentSize);
window.OnContentResized += ShowContentSize;
}
private Window AddWindow(string title, Window window, Rect bounds)
{
window.DebugName = title;
void ShowActive(bool active)
{
window.WindowMaterial = active ? Frame : InactiveFrame;
}
ShowActive(window.FocusScope.Active);
window.FocusScope.OnActiveChanged += ShowActive;
window.ResizeCursors = ResizeCursorMaterials.ByZone;
window.MoveCursor = CursorExtraMaterials.Move;
window.Caption.Material = Material.Invisible;
window.TitleStyle = Widgets.WindowTitleStyle;
window.Title = title;
window.Bounds = bounds;
new Label(Widgets.CloseButtonLabelStyle, "x").FillParent(window.CloseButton);
Add(window);
windows.Add(window);
return window;
}
private static Label NewMenuLabel(StringView text)
{
return new Label(Widgets.MenuLabelStyle, text, Constraints.Unbounded);
}
///
/// Returns the size of a header that fits `label` in either of its states.
///
private static Vector MenuHeaderSizeFor(Label label)
{
return Vector.Max(
Widgets.MenuHeader.BoundsSizeFor(label.Bounds.Size),
Widgets.OpenMenuHeader.BoundsSizeFor(label.Bounds.Size));
}
private static MenuButton NewFileMenu(Window window, MenuBar menuBar, Label label)
{
var header = new MenuButton(ButtonBehavior.Default)
{
DebugName = "file menu",
Group = menuBar.Group,
UncheckedMaterial = Widgets.MenuHeader,
CheckedMaterial = Widgets.OpenMenuHeader,
Bounds = Rect.FromPositionAndSize(Vector.Zero, MenuHeaderSizeFor(label)),
};
label.FillParent(header);
header.Popup.DropdownPopupMaterial = Widgets.PopupList;
header.Rebuild(FileMenuItems, item => NewMenuLabel(item));
header.OnItemClicked += _ => window.Close();
return header;
}
protected override void Populate()
{
AddCaption("Drag a title bar to move, an edge or corner to resize; x or File > Close closes a window");
Button reopen = new Label(Widgets.ButtonLabelStyle, "Reopen closed windows", Constraints.Unbounded)
.WrapIn(UiPacksheetMaterials.Button, ButtonBehavior.Default);
reopen.DebugName = "reopen button";
reopen.OnActivate += delegate (ButtonBase _, in KeyboardSnapshot __, KeyboardManager ___)
{
foreach (Window window in windows)
{
window.Visible = true;
}
};
reopen.Bounds = Rect.FromPositionAndSize(
ContentAggregator.NewRow(reopen.Bounds.Height).TopLeft, reopen.Bounds.Size);
Add(reopen);
Rect stage = ContentAggregator.NewRow(StageHeight);
Window resizable = AddWindow("Resizable window", new Window(),
Rect.FromPositionAndSize(stage.TopLeft + new Vector(20, 20), new Vector(260, 180)));
AddContentSizeReadout(resizable, resizable.CanvasChildren);
AddWindow("Fixed size, no close button", new Window { Resizable = false, ShowCloseButton = false },
Rect.FromPositionAndSize(stage.TopLeft + new Vector(160, 110), new Vector(260, 140)));
Label fileLabel = NewMenuLabel("File");
Window withMenu = AddWindow("With a menu bar", new Window(),
Rect.FromPositionAndSize(stage.TopLeft + new Vector(460, 30), new Vector(280, 200)));
(MenuBar menuBar, Panel body) = Widgets.AddMenuBar(withMenu, MenuHeaderSizeFor(fileLabel).Y);
menuBar.CanvasChildren.Add(NewFileMenu(withMenu, menuBar, fileLabel));
AddContentSizeReadout(withMenu, body.CanvasChildren);
}
}
}