public static int ListBox <T>(string label, IReadOnlyList <T> items, int selectedIndex) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(selectedIndex); } int id = window.GetID(label); PushID("ListboxField" + id); var style = GUIStyle.Basic; BeginHorizontal("Field"); BeginVertical("Items", GUILayout.ExpandWidth(true)); { style.Save(); style.ApplySkin(GUIControlName.ListBox); style.PushStretchFactor(false, 1); style.PushCellSpacing(true, 0); for (var i = 0; i < items.Count; i++) { var item = items[i]; string itemText = item.ToString(); var itemId = window.GetID(string.Format("Item_{0}_{1}", i, itemText)); var textSize = style.CalcSize(itemText, GUIState.Normal); var itemRect = window.GetRect(itemId, textSize); bool hovered; bool on = GUIBehavior.ToggleBehavior(itemRect, id, selectedIndex == i, out hovered); if (on) { selectedIndex = i; } var d = window.DrawList; var state = on ? GUIState.Active : GUIState.Normal; d.DrawBoxModel(itemRect, itemText, style, state); } style.Restore(); } EndVertical(); GUILayout.Space("FieldSpacing", GUISkin.Current.FieldSpacing); GUILayout.Label(label, GUILayout.Width((int)GUISkin.Current.LabelWidth)); EndHorizontal(); PopID(); return(selectedIndex); }
public static bool RadioButton(string label, bool active) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(false); } GUIContext g = GetCurrentContext(); int id = window.GetID(label); // style var style = GUIStyle.Basic; Size label_size = style.CalcSize(label, GUIState.Normal); Rect check_bb = window.GetRect(window.GetID(label + "_check")); Rect text_bb = window.GetRect(id); Rect total_bb = Rect.Union(check_bb, text_bb); Point center = check_bb.Center; center.x = (int)center.x + 0.5f; center.y = (int)center.y + 0.5f; var radius = check_bb.Height * 0.5f; bool hovered, held; bool pressed = GUIBehavior.ButtonBehavior(total_bb, id, out hovered, out held); var d = window.DrawList; var state = ((held && hovered) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal); d.AddCircleFilled(center, (float)radius, ((held && hovered) ? Color.FrameBgActive : hovered ? Color.FrameBgHovered : Color.FrameBg), 16); if (active) { var check_sz = Math.Min(check_bb.Width, check_bb.Height); var pad = Math.Max(1.0f, (int)(check_sz / 6.0f)); d.AddCircleFilled(center, radius - pad, Color.CheckMark, 16); } if (label_size.Width > 0.0f) { d.AddText(text_bb, label, style, state); } return(pressed); }
/// <summary> /// Create a label with a little bullet. /// </summary> public static void BulletText(string text) { Window window = GetCurrentWindow(); if (window.SkipItems) { return; } GUIContext g = GetCurrentContext(); int id = window.GetID(text); // style var style = GUIStyle.Basic; // rect Size contentSize = style.CalcSize(text, GUIState.Normal); var lineHeight = style.GetLineHeight(); Rect rect = window.GetRect(id); // Render var d = window.DrawList; var bulletPosition = rect.TopLeft + new Vector(0, lineHeight * 0.5f); d.RenderBullet(bulletPosition, lineHeight, style.FontColor); rect.Offset(lineHeight, 0); d.AddText(rect, text, style, GUIState.Normal); }
public static string Textbox(Rect rect, string label, string text) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(text); } var id = window.GetID(label); // style var style = GUIStyle.Basic; style.Save(); style.ApplySkin(GUIControlName.TextBox); // rect rect = window.GetRect(rect); // interact InputTextContext context; text = GUIBehavior.TextBoxBehavior(id, rect, text, out bool hovered, out bool active, out context); // render var state = active ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal; GUIAppearance.DrawTextBox(rect, id, text, context, state); style.Restore(); return(text); }
/// <summary> /// Create an auto-layout button that acts like a toggle. /// </summary> /// <param name="text">text to display on the button</param> /// <param name="selected">whether this selectable is selected</param> /// <param name="options">layout options that specify layouting properties. See also <see cref="GUILayout.Width"/>, <see cref="GUILayout.Height"/>, <see cref="GUILayout.ExpandWidth"/>, <see cref="GUILayout.ExpandHeight"/>, <see cref="GUILayout.StretchWidth"/>, <see cref="GUILayout.StretchHeight"/></param> /// <returns>new value of the toggle-button</returns> public static bool Selectable(string text, bool selected, LayoutOptions?options) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(false); } int id = window.GetID(text); // style var style = GUIStyle.Basic; style.ApplySkin(GUIControlName.Selectable); style.ApplyOption(options); // rect Size size = style.CalcSize(text, GUIState.Normal); Rect rect = window.GetRect(id, size); // interact selected = GUIBehavior.SelectableBehavior(rect, id, selected, out bool hovered, out bool held); // render DrawList d = window.DrawList; var state = (selected || (hovered && held)) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal; d.DrawBoxModel(rect, text, style, state); style.Restore(); return(selected); }
/// <summary> /// Create an auto-layout label. /// </summary> /// <param name="text">text to display</param> /// <param name="options"></param> public static void Label(string text, LayoutOptions?options) { Window window = GetCurrentWindow(); if (window.SkipItems) { return; } //get or create the root node int id = window.GetID(text); var container = window.RenderTree.CurrentContainer; Node node = container.GetNodeById(id); text = Utility.FindRenderedText(text); if (node == null) { node = new Node(id, $"Label<{text}>"); node.UseBoxModel = true; node.RuleSet.Replace(GUISkin.Current[GUIControlName.Label]); var size = node.RuleSet.CalcSize(text, GUIState.Normal); node.AttachLayoutEntry(size); container.AppendChild(node); node.Geometry = new TextGeometry(text); } node.ActiveSelf = true; node.RuleSet.ApplyOptions(options); // rect node.Rect = window.GetRect(id); }
/// <summary> /// Create a label. /// </summary> /// <param name="rect">position and size</param> /// <param name="text">text to display</param> public static void Label(Rect rect, string text) { Window window = GetCurrentWindow(); if (window.SkipItems) { return; } //get or create the root node int id = window.GetID(text); var container = window.AbsoluteVisualList; Node node = (Node)container.Find(visual => visual.Id == id); text = Utility.FindRenderedText(text); if (node == null) { node = new Node(id, $"Label<{text}>"); container.Add(node); node.UseBoxModel = true; node.RuleSet.Replace(GUISkin.Current[GUIControlName.Label]); node.Geometry = new TextGeometry(text); } node.ActiveSelf = true; var textPrimitive = node.Geometry as TextGeometry; Debug.Assert(textPrimitive != null); textPrimitive.Text = text; // rect node.Rect = window.GetRect(rect); }
/// <summary> /// Create a label. /// </summary> /// <param name="rect">position and size</param> /// <param name="text">text to display</param> public static void Label(Rect rect, string text) { Window window = GetCurrentWindow(); if (window.SkipItems) { return; } //get or create the root node int id = window.GetID(text); var container = window.NodeTreeRoot; Node node = container.GetNodeById(id); text = Utility.FindRenderedText(text); if (node == null) { node = new Node(id, $"Label<{text}>"); container.AppendChild(node); node.UseBoxModel = true; node.RuleSet.Replace(GUISkin.Current[GUIControlName.Label]); node.Primitive = new TextPrimitive(text); } var textPrimitive = node.Primitive as TextPrimitive; Debug.Assert(textPrimitive != null); textPrimitive.Text = text; // rect node.Rect = window.GetRect(rect); }
/// <summary> /// Create an auto-layout horizontal separating line. /// </summary> public static void Separator(string str_id) { GUIContext g = GetCurrentContext(); Window window = GetCurrentWindow(); if (window.SkipItems) { return; } int id = window.GetID(str_id); // style var style = GUIStyle.Basic; style.PushStretchFactor(false, 1);//+1 // rect var rect = window.GetRect(id); // render var d = window.DrawList; var offset = new Vector(rect.Width / 2, 0); var start = rect.Center - offset; var end = rect.Center + offset; d.AddLine(start, end, style.StrokeColor); style.PopStyle();//-1 }
/// <summary> /// Create an auto-layout image. /// </summary> /// <param name="filePath">file path of the image to display. The path should be relative to current dir or absolute.</param> public static void Image(string filePath) { GUIContext g = GetCurrentContext(); Window window = GetCurrentWindow(); if (window.SkipItems) { return; } var id = window.GetID(filePath); // style var style = GUIStyle.Basic; style.PushBorder(1.0); // rect var texture = TextureUtil.GetTexture(filePath); Size size = style.CalcSize(texture, GUIState.Normal); var rect = window.GetRect(id); // render DrawList d = window.DrawList; style.PushBorderColor(Color.Black);//+4 d.DrawBoxModel(rect, texture, style); style.PopStyle(4 + 4); }
public static double ProgressBar(string str_id, double percent, Size size, string overlayText = null) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(percent); } GUIContext g = GetCurrentContext(); int id = window.GetID(str_id); // style var style = GUIStyle.Basic; // rect var rect = window.GetRect(id, size); percent = MathEx.Clamp01(percent); // render DrawList d = window.DrawList; GUIAppearance.DrawProgressBar(rect, percent); if (overlayText != null) { style.PushTextAlignment(TextAlignment.Center); d.DrawBoxModel(rect, overlayText, style); style.PopStyle(); } return(percent); }
/// <summary> /// Create an auto-layout horizontal slider that user can drag to select a value. /// </summary> /// <param name="label">label of the slider</param> /// <param name="value">The value the slider shows.</param> /// <param name="minValue">The value at the left end of the slider.</param> /// <param name="maxValue">The value at the right end of the slider.</param> /// <returns>The value set by the user.</returns> /// <remarks>minValue <= value <= maxValue</remarks> public static double Slider(string label, double value, double minValue, double maxValue) { GUIContext g = GetCurrentContext(); Window window = GetCurrentWindow(); if (window.SkipItems) { return(value); } var id = window.GetID(label); // style apply var style = GUIStyle.Basic; // rect Size size = style.CalcSize(label, GUIState.Normal); style.PushStretchFactor(false, 1);//+1 { var minSilderWidth = 200; size.Width += minSilderWidth; size.Height = 20; } var rect = window.GetRect(id); // interact var spacing = GUISkin.Instance.InternalStyle.Get <double>(GUIStyleName._ControlLabelSpacing); var labelWidth = GUISkin.Instance.InternalStyle.Get <double>(GUIStyleName._LabelWidth); var sliderWidth = rect.Width - spacing - labelWidth; if (sliderWidth <= 0) { sliderWidth = 1; } var sliderRect = new Rect(rect.X, rect.Y, sliderWidth, rect.Height); bool hovered, held; value = GUIBehavior.SliderBehavior(sliderRect, id, true, value, minValue, maxValue, out hovered, out held); // render var state = GUIState.Normal; if (hovered) { state = GUIState.Hover; } if (g.ActiveId == id && Mouse.Instance.LeftButtonState == KeyState.Down) { state = GUIState.Active; } GUIAppearance.DrawSlider(rect, label, value, minValue, maxValue, state, sliderRect, labelWidth); // style restore style.PopStyle();//-1 return(value); }
/// <summary> /// Create a bullet. /// </summary> public static void Bullet(string str_id) { Window window = GetCurrentWindow(); if (window.SkipItems) { return; } GUIContext g = GetCurrentContext(); int id = window.GetID(str_id); // style var style = GUIStyle.Basic; // rect var lineHeight = style.GetLineHeight(); Rect rect = window.GetRect(id); // Render var d = window.DrawList; var bulletPosition = rect.TopLeft + new Vector(0, lineHeight * 0.5f); d.RenderBullet(bulletPosition, lineHeight, style.FontColor); }
/// <summary> /// Create a toggle (check-box) with a label. /// </summary> /// <param name="rect">position and size of the control</param> /// <param name="label">label</param> /// <param name="value">Is this toggle checked or unchecked?</param> /// <returns>new value of the toggle</returns> public static bool Toggle(Rect rect, string label, bool value) { GUIContext g = GetCurrentContext(); Window window = GetCurrentWindow(); if (window.SkipItems) { return(false); } int id = window.GetID(label); // rect rect = window.GetRect(rect); // interact bool hovered; value = GUIBehavior.ToggleBehavior(rect, id, value, out hovered); // render var state = GUIState.Normal; if (hovered) { state = GUIState.Hover; } if (g.ActiveId == id && Mouse.Instance.LeftButtonState == KeyState.Down) { state = GUIState.Active; } GUIAppearance.DrawToggle(rect, label, value, state); return(value); }
/// <summary> /// Create an auto-layout label. /// </summary> /// <param name="text">text to display</param> public static void Label(string text, LayoutOptions?options) { GUIContext g = GetCurrentContext(); Window window = GetCurrentWindow(); if (window.SkipItems) { return; } int id = window.GetID(text); // style var style = GUIStyle.Basic; style.Save(); style.ApplyOption(options); // rect Size contentSize = style.CalcSize(text, GUIState.Normal); Rect rect = window.GetRect(id); // rendering DrawList d = window.DrawList; d.DrawBoxModel(rect, text, style); style.Restore(); }
/// <summary> /// Create a button. When the user click it, something will happen immediately. /// </summary> /// <param name="rect">position and size of the control</param> /// <param name="text">text to display on the button</param> /// <returns>true when the users clicks the button.</returns> public static bool Button(Rect rect, string text) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(false); } int id = window.GetID(text); // style apply var style = GUIStyle.Basic; style.Save(); style.ApplySkin(GUIControlName.Button); // rect rect = window.GetRect(rect); // interact bool hovered, held; bool pressed = GUIBehavior.ButtonBehavior(rect, id, out hovered, out held, 0); // render var d = window.DrawList; var state = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal; d.DrawBoxModel(rect, text, style, state); style.Restore(); return(pressed); }
public static void BeginHorizontal(string str_id, LayoutOptions?options) { Window window = GetCurrentWindow(); int id = window.GetID(str_id); PushID(id); window.RenderTree.BeginLayoutGroup(id, false, options, str_id); }
public static bool TreeNode(string text, ref bool open) { Window window = GetCurrentWindow(); int id = window.GetID(text); DoTreeNode(id, text, ref open); return(open); }
private static bool DoHoverButton(string text, GUIStyle style, params LayoutOption[] options) { Window window = GetCurrentWindow(); var id = window.GetID(text); Size size = style.CalcSize(text, GUIState.Normal); var rect = window.GetRect(id); return(GUI.HoverButton(rect, text)); }
public static void BeginVertical(string str_id, LayoutOptions?options) { Window window = GetCurrentWindow(); int id = window.GetID(str_id); PushID(id); window.StackLayout.BeginLayoutGroup(id, true, options, str_id); }
/// <summary> /// Create an auto-layout collapsing header. /// </summary> /// <param name="text">header text</param> /// <param name="open">opened</param> /// <param name="options">style options</param> /// <returns>true when opened</returns> /// <remarks> It is always horizontally stretched (factor 1).</remarks> public static bool CollapsingHeader(string text, ref bool open, LayoutOptions?options) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(false); } //get or create the root node int id = window.GetID(text); var container = window.RenderTree.CurrentContainer; Node node = container.GetNodeById(id); text = Utility.FindRenderedText(text); if (node == null) { //create nodes node = new Node(id, $"CollapsingHeader<{text}>"); node.AttachLayoutEntry(); node.UseBoxModel = true; node.RuleSet.Replace(GUISkin.Current[GUIControlName.CollapsingHeader]); } node.RuleSet.ApplyOptions(options); node.RuleSet.ApplyOptions(Height(node.RuleSet.GetLineHeight())); node.ActiveSelf = true; container.AppendChild(node); // rect Rect rect = window.GetRect(id); // interact var pressed = GUIBehavior.ButtonBehavior(rect, id, out var hovered, out var held, ButtonFlags.PressedOnClick); node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal; if (pressed) { open = !open; } // last item state window.TempData.LastItemState = node.State; using (var dc = node.RenderOpen()) { dc.DrawBoxModel(node); dc.DrawGlyphRun(node.RuleSet, text, node.ContentRect.TopLeft + new Vector(node.Rect.Height + node.PaddingLeft, 0)); dc.RenderArrow(node.Rect.Min + new Vector(node.PaddingLeft, 0), node.Height, node.RuleSet.FontColor, open ? Direcion.Down : Direcion.Right, 1.0); } return(open); }
public static bool TreeNode(string text) { Window window = GetCurrentWindow(); int id = window.GetID(text); Storage storage = window.StateStorage; var open = storage.GetBool(id); DoTreeNode(id, text, ref open); storage.SetBool(id, open); return(open); }
public static bool TreeNode <T>(T obj, string text) where T : class { Window window = GetCurrentWindow(); int id = window.GetID(obj); Storage storage = window.StateStorage; var open = storage.GetBool(id); DoTreeNode(id, text, ref open); storage.SetBool(id, open); return(open); }
/// <summary> /// Create a single-line text box. /// </summary> /// <param name="label">label</param> /// <param name="width">width</param> /// <param name="text">text</param> /// <param name="flags">filter flags</param> /// <param name="checker">custom checker per char</param> /// <returns>(modified) text</returns> public static string TextBox(string label, double width, string text, InputTextFlags flags, Func <char, bool> checker, LayoutOptions?options) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(text); } var id = window.GetID(label); var container = window.RenderTree.CurrentContainer; Node node = container.GetNodeById(id); label = Utility.FindRenderedText(label); if (node == null) { //create node node = new Node(id, $"{nameof(TextBox)}<{label}>"); node.UseBoxModel = true; node.RuleSet.Replace(GUISkin.Current[GUIControlName.TextBox]); var size = node.RuleSet.CalcContentBoxSize(text, GUIState.Normal); node.AttachLayoutEntry(size); } container.AppendChild(node); node.RuleSet.ApplyOptions(options); node.ActiveSelf = true; // rect Rect rect = window.GetRect(id); // interact InputTextContext context; text = GUIBehavior.TextBoxBehavior(id, rect, text, out bool hovered, out bool active, out context, flags, checker); var state = active ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal; // last item state window.TempData.LastItemState = state; // render if (flags.HaveFlag(InputTextFlags.Password)) { var dotText = new string('*', text.Length);//FIXME bad performance GUIAppearance.DrawTextBox(node, id, dotText, context, state); } else { GUIAppearance.DrawTextBox(node, id, text, context, state); } return(text); }
private static bool DoPolygonButton(IReadOnlyList <Point> points, Rect textRect, string text, GUIStyle style, params LayoutOption[] options) { Window window = GetCurrentWindow(); var id = window.GetID(text); var rect = new Rect(); for (int i = 0; i < points.Count; i++) { var point = points[i]; rect.Union(point); } rect = window.GetRect(id); return(GUI.PolygonButton(rect, points, textRect, text)); }
/// <summary> /// Create an auto-layout collapsing header. /// </summary> /// <param name="text">header text</param> /// <param name="open">opened</param> /// <param name="options">style options</param> /// <returns>true when opened</returns> /// <remarks> It is always horizontally stretched (factor 1).</remarks> public static bool CollapsingHeader(string text, ref bool open, LayoutOptions?options) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(false); } //get or create the root node int id = window.GetID(text); var container = window.RenderTree.CurrentContainer; Node node = container.GetNodeById(id); text = Utility.FindRenderedText(text); var displayText = (open ? "-" : "+") + text; if (node == null) { //create nodes node = new Node(id, $"CollapsingHeader<{text}>"); node.AttachLayoutEntry(); container.AppendChild(node); node.UseBoxModel = true; node.RuleSet.Replace(GUISkin.Current[GUIControlName.CollapsingHeader]); node.Geometry = new TextGeometry(displayText); } node.RuleSet.ApplyOptions(options); node.RuleSet.ApplyOptions(Height(node.RuleSet.GetLineHeight())); node.ActiveSelf = true; var textPrimitive = node.Geometry as TextGeometry; Debug.Assert(textPrimitive != null); textPrimitive.Text = displayText; // rect Rect rect = window.GetRect(id); // interact var pressed = GUIBehavior.ButtonBehavior(rect, id, out var hovered, out var held, ButtonFlags.PressedOnClick); if (pressed) { open = !open; node.State = open ? GUIState.Active : GUIState.Normal; } return(open); }
public static bool DoHoverButton(Rect rect, string text) { Form form = Form.current; GUIContext g = form.uiContext; Window window = g.WindowManager.CurrentWindow; DrawList d = window.DrawList; int id = window.GetID(text); var mousePos = Mouse.Instance.Position; var result = false; var hovered = rect.Contains(mousePos); //control logic var uiState = Form.current.uiContext; uiState.KeepAliveID(id); if (hovered) { uiState.SetHoverID(id); if (uiState.ActiveId == GUIContext.None) { uiState.SetActiveID(id); result = true; } } else { if (uiState.ActiveId == id) { uiState.SetActiveID(GUIContext.None); } result = false; } // ui representation var state = GUI.Normal; if (uiState.ActiveId == id) { state = GUI.Active; } // ui painting { d.DrawBoxModel(rect, text, GUISkin.Instance[GUIControlName.Button], state); } return(result); }
public static bool ImageButton(string filePath, Size size, Point uv0, Point uv1) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(false); } var id = window.GetID(filePath); // style var style = GUIStyle.Basic; style.Save(); style.ApplySkin(GUIControlName.Button); // rect var texture = TextureUtil.GetTexture(filePath); if (size == Size.Empty) { size = style.CalcSize(texture, GUIState.Normal); } var rect = window.GetRect(id); if (rect == Layout.StackLayout.DummyRect) { style.Restore(); return(false); } // interact bool hovered, held; bool pressed = GUIBehavior.ButtonBehavior(rect, id, out hovered, out held, 0); // render style.PushUV(uv0, uv1); var d = window.DrawList; var state = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal; d.DrawBoxModel(rect, texture, style, state); style.Restore(); return(pressed); }
/// <summary> /// Create a single-line text box. /// </summary> /// <param name="label">label</param> /// <param name="width">width</param> /// <param name="text">text</param> /// <param name="flags">filter flags</param> /// <param name="checker">custom checker per char</param> /// <returns>(modified) text</returns> public static string TextBox(string label, double width, string text, InputTextFlags flags, Func <char, bool> checker, LayoutOptions?options) { Window window = GetCurrentWindow(); if (window.SkipItems) { return(text); } int id = window.GetID(label); // style apply var style = GUIStyle.Basic; style.Save(); style.ApplySkin(GUIControlName.TextBox); style.ApplyOption(options); // rect var height = style.GetLineHeight(); var size = new Size(width, height); Rect rect = window.GetRect(id, size); // interact InputTextContext context; text = GUIBehavior.TextBoxBehavior(id, rect, text, out bool hovered, out bool active, out context, flags, checker); // render var d = window.DrawList; var state = active ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal; if (flags.HaveFlag(InputTextFlags.Password)) { var dotText = new string('*', text.Length);//FIXME bad performance GUIAppearance.DrawTextBox(rect, id, dotText, context, state); } else { GUIAppearance.DrawTextBox(rect, id, text, context, state); } style.Restore(); return(text); }
/// <summary> /// Create a fixed size space. /// </summary> public static void Space(string str_id, double size) { GUIContext g = GetCurrentContext(); Window window = GetCurrentWindow(); if (window.SkipItems) { return; } int id = window.GetID(str_id); // rect var layout = window.StackLayout; layout.GetRect(id, window.RenderTree.CurrentContainer.IsVertical ? new Size(0, size) : new Size(size, 0)); }