public void OnGUI() { Event evt = Event.current; Vector2 mpos = evt.mousePosition; // if icon mode and no actions are found, that probably means icons failed to load. revert to text mode. int menuActionsCount = 0; for (int i = 0; i < m_Actions.Count; i++) { if (IsActionValid(m_Actions[i])) { menuActionsCount++; } } if (isIconMode && menuActionsCount < 1) { isIconMode = false; ProBuilderEditor.s_IsIconGui.value = isIconMode; CalculateMaxIconSize(); Debug.LogWarning("ProBuilder: Toolbar icons failed to load, reverting to text mode. Please ensure that the ProBuilder folder contents are unmodified. If the menu is still not visible, try closing and re-opening the Editor Window."); return; } int availableWidth = windowWidth; int availableHeight = windowHeight; bool isHorizontal = windowWidth > windowHeight * 2; if (m_IsHorizontalMenu != isHorizontal || m_Rows < 1 || m_Columns < 1) { CalculateMaxIconSize(); } if (evt.type == EventType.Layout) { if (isHorizontal) { m_Rows = ((windowHeight - 4) / m_ContentHeight); m_Columns = System.Math.Max(windowWidth / m_ContentWidth, (menuActionsCount / m_Rows) + (menuActionsCount % m_Rows != 0 ? 1 : 0)); } else { m_Columns = System.Math.Max((windowWidth - 4) / m_ContentWidth, 1); m_Rows = (menuActionsCount / m_Columns) + (menuActionsCount % m_Columns != 0 ? 1 : 0); } } // happens when maximizing/unmaximizing the window if (m_Rows < 1 || m_Columns < 1) { return; } int contentWidth = (menuActionsCount / m_Rows) * m_ContentWidth + 4; int contentHeight = m_Rows * m_ContentHeight + 4; bool showScrollButtons = isHorizontal ? contentWidth > availableWidth : contentHeight > availableHeight; if (showScrollButtons) { availableHeight -= SCROLL_BTN_SIZE * 2; availableWidth -= SCROLL_BTN_SIZE * 2; } if (isHorizontal && evt.type == EventType.ScrollWheel && evt.delta.sqrMagnitude > .001f) { m_Scroll.value = new Vector2(m_Scroll.value.x + evt.delta.y * 10f, m_Scroll.value.y); ScheduleRepaint(); } // the math for matching layout group width for icons is easy enough, but text // is a lot more complex. so for horizontal text toolbars always show the horizontal // scroll buttons. int maxHorizontalScroll = !isIconMode ? 10000 : contentWidth - availableWidth; int maxVerticalScroll = contentHeight - availableHeight; // only change before a layout event if (m_ShowScrollButtons != showScrollButtons && evt.type == EventType.Layout) { m_ShowScrollButtons = showScrollButtons; } if (m_ShowScrollButtons) { if (isHorizontal) { GUILayout.BeginHorizontal(); GUI.enabled = ((Vector2)m_Scroll).x > 0; if (GUILayout.Button(scrollIconLeft, UI.EditorGUIUtility.ButtonNoBackgroundSmallMarginStyle, GUILayout.ExpandHeight(true))) { StartScrollAnimation(Mathf.Max(((Vector2)m_Scroll).x - availableWidth, 0f), 0f); } GUI.enabled = true; } else { GUI.enabled = ((Vector2)m_Scroll).y > 0; if (GUILayout.Button(scrollIconUp, UI.EditorGUIUtility.ButtonNoBackgroundSmallMarginStyle)) { StartScrollAnimation(0f, Mathf.Max(((Vector2)m_Scroll).y - availableHeight, 0f)); } GUI.enabled = true; } } m_Scroll.value = GUILayout.BeginScrollView(m_Scroll.value, false, false, GUIStyle.none, GUIStyle.none, GUIStyle.none); bool tooltipShown = false, hovering = false; Rect optionRect = new Rect(0f, 0f, 0f, 0f); GUILayout.BeginHorizontal(); bool windowContainsMouse = (window == EditorWindow.mouseOverWindow || TooltipEditor.IsFocused()); int columnCount = 0; for (int actionIndex = 0; actionIndex < m_ActionsLength; actionIndex++) { var action = m_Actions[actionIndex]; if (!IsActionValid(action)) { continue; } if (isIconMode) { if (action.DoButton(isHorizontal, evt.alt, ref optionRect, GUILayout.MaxHeight(m_ContentHeight + 12)) && !evt.shift) { // test for alt click / hover optionRect.x -= m_Scroll.value.x; optionRect.y -= m_Scroll.value.y; if (windowContainsMouse && evt.type != EventType.Layout && optionRect.Contains(evt.mousePosition)) { hoveringTooltipName = action.tooltip.title + "_alt"; tooltipTimerRefresh = .5f; hovering = true; if (showTooltipTimer) { tooltipShown = true; ShowTooltip(optionRect, "Alt + Click for Options ", m_Scroll); } } } } else { if (m_Columns < 2) { action.DoButton(isHorizontal, evt.alt, ref optionRect); } else { action.DoButton(isHorizontal, evt.alt, ref optionRect, GUILayout.MinWidth(m_ContentWidth)); } } Rect buttonRect = GUILayoutUtility.GetLastRect(); if (windowContainsMouse && evt.type != EventType.Layout && !hovering && buttonRect.Contains(evt.mousePosition)) { hoveringTooltipName = action.tooltip.title; tooltipTimerRefresh = 1f; if (evt.shift || showTooltipTimer) { tooltipShown = true; ShowTooltip(buttonRect, action.tooltip, m_Scroll); } hovering = true; } if (++columnCount >= m_Columns) { columnCount = 0; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); } } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndScrollView(); if (m_ShowScrollButtons) { if (isHorizontal) { GUI.enabled = m_Scroll.value.x < maxHorizontalScroll - 2; if (GUILayout.Button(scrollIconRight, UI.EditorGUIUtility.ButtonNoBackgroundSmallMarginStyle, GUILayout.ExpandHeight(true))) { StartScrollAnimation(Mathf.Min(m_Scroll.value.x + availableWidth + 2, maxHorizontalScroll), 0f); } GUI.enabled = true; GUILayout.EndHorizontal(); } else { GUI.enabled = m_Scroll.value.y < maxVerticalScroll - 2; if (GUILayout.Button(scrollIconDown, UI.EditorGUIUtility.ButtonNoBackgroundSmallMarginStyle)) { StartScrollAnimation(0f, Mathf.Min(m_Scroll.value.y + availableHeight + 2, maxVerticalScroll)); } GUI.enabled = true; } } if ((evt.type == EventType.Repaint || evt.type == EventType.MouseMove) && !tooltipShown) { TooltipEditor.Hide(); } if (evt.type != EventType.Layout && !hovering) { tooltipTimer.item1 = ""; } m_WantsRepaint |= EditorWindow.mouseOverWindow == window && evt.type == EventType.MouseMove; if (m_WantsRepaint) { window.Repaint(); } m_WantsRepaint = false; }