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); } } }