internal static ComboBoxContext comboBoxContext;//TODO move this to Window.storage public static int ComboBox(Rect rect, string[] texts) { var window = GetCurrentWindow(); if (window.SkipItems) { return(comboBoxContext.SelectedIndex); } //get or create the root node var id = window.GetID(texts); var container = window.AbsoluteVisualList; var node = (Node)container.Find(visual => visual.Id == id); if (node == null) { //create button node node = new Node(id, $"Combobox<{texts[0]}..>"); container.Add(node); node.UseBoxModel = true; node.RuleSet.Replace(GUISkin.Current[GUIControlName.ComboBox]); //set initial states TODO move to shared storage GUI.comboBoxContext = new ComboBoxContext(); GUI.comboBoxContext.Texts = texts; GUI.comboBoxContext.Text = texts[0]; GUI.comboBoxContext.SelectedIndex = 0; } node.RuleSet.ApplyStack(); node.ActiveSelf = true; // rect node.Rect = window.GetRect(rect); // interact var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held); if (pressed) { node.State = GUIState.Active; comboBoxContext.WindowOpened = !comboBoxContext.WindowOpened; } comboBoxContext.Text = comboBoxContext.Texts[comboBoxContext.SelectedIndex]; // last item state window.TempData.LastItemState = node.State; //combo if (comboBoxContext.WindowOpened) { //calculate window rect Rect comboPopupWindowRect; { var maxLength = 0; var maxLengthString = string.Empty; foreach (var s in texts) { if (s.Length <= maxLength) { continue; } maxLength = s.Length; maxLengthString = s; } var size = node.RuleSet.CalcSize(maxLengthString); size.Height *= texts.Length; size += new Vector(100, 100); //TEMP HACK Extend the size a little: otherwise a LayoutException will happen var clientPos = node.Rect.BottomLeft; comboPopupWindowRect = new Rect(clientPos, size); } GUILayout.SetNextWindowPos(comboPopupWindowRect.Location); var clickedIndx = -1; Begin($"##ComboWindow_{node.Name}", comboPopupWindowRect, WindowFlags.Popup | WindowFlags.NoTitleBar | WindowFlags.NoCollapse | WindowFlags.NoMove | WindowFlags.NoResize | WindowFlags.NoScrollbar); { GUILayout.BeginVertical("ComboBox"); for (var i = 0; i < texts.Length; i++) { if (GUILayout.Button(texts[i])) { clickedIndx = i; } } GUILayout.EndVertical(); } End(); if (clickedIndx >= 0) { comboBoxContext.SelectedIndex = clickedIndx; comboBoxContext.WindowOpened = false; node.State = Normal; } } //render using var g = node.RenderOpen(); var ruleSet = node.RuleSet; g.DrawBoxModel(node.RuleSet, node.Rect); g.RenderArrow(node.Rect.Min + new Vector(node.PaddingLeft, 0), node.Height, node.RuleSet.FontColor, Internal.Direcion.Down, 1.0); g.DrawGlyphRun(comboBoxContext.Text, ruleSet.FontSize, ruleSet.FontFamily, ruleSet.FontColor, node.Rect.Min + new Vector(node.Height + ruleSet.PaddingLeft, ruleSet.PaddingTop)); return(comboBoxContext.SelectedIndex); }