コード例 #1
0
        public void Draw()
        {
            var darkTitleRect = new Rectangle(MenuRect.X + DbgMenuTopLeftButtonRect.Width, MenuRect.Y, MenuRect.Width - DbgMenuTopLeftButtonRect.Width, DbgMenuTopLeftButtonRect.Height);


            GFX.SpriteBatchBeginForText();

            var clickMeSize = DBG.DEBUG_FONT_SMALL.MeasureString("MENU");

            GFX.SpriteBatch.Draw(Main.WHITE_TEXTURE, DbgMenuTopLeftButtonRect, Color.Black * 0.85f);

            GFX.SpriteBatch.DrawString(DBG.DEBUG_FONT_SMALL, "MENU", DbgMenuTopLeftButtonRect.Center(), Color.White, 0, clickMeSize / 2, 1, SpriteEffects.None, 0);

            if (MenuOpenState == DbgMenuOpenState.Closed)
            {
                GFX.SpriteBatchEnd();
                return;
            }

            UpdateUI();

            float menuBackgroundOpacityMult = MenuOpenState == DbgMenuOpenState.Open ? 1.0f : 0f;

            // Draw menu background rect

            //---- Full Background
            GFX.SpriteBatch.Draw(Main.WHITE_TEXTURE, SubMenuRect, Color.Black * 0.5f * menuBackgroundOpacityMult);
            //---- Slightly Darker Part On Top
            GFX.SpriteBatch.Draw(Main.WHITE_TEXTURE, darkTitleRect,
                                 Color.Black * 0.75f * menuBackgroundOpacityMult);

            if (MenuOpenState == DbgMenuOpenState.Open)
            {
                var renderPauseStr      = $"Render Pause:{(IsPauseRendering ? "Active" : "Inactive")}\n(Click RS / Press Pause Key)";
                var renderPauseStrScale = DBG.DEBUG_FONT.MeasureString(renderPauseStr);
                var renderPauseStrColor = !IsPauseRendering ? Color.White : Color.Yellow;

                DBG.DrawOutlinedText(renderPauseStr,
                                     new Vector2(8, GFX.Device.Viewport.Height - 20),
                                     renderPauseStrColor, DBG.DEBUG_FONT, scaleOrigin: new Vector2(0, renderPauseStrScale.Y),
                                     //scale: IsPauseRendering ? 1f : 0.75f,
                                     startAndEndSpriteBatchForMe: false);
            }

            // Draw name on top
            var sb = new StringBuilder();

            //---- If in submenu, append the stack of menues preceding this one
            if (DbgMenuStack.Count > 0)
            {
                bool first = true;
                foreach (var chain in DbgMenuStack.Reverse())
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        sb.Append(" > ");
                    }
                    sb.Append($"{chain.Text}{(chain.Items.Count > 0 ? $" ({chain.Items.Count})" : "")}");
                }
                sb.Append(" > ");
            }
            //---- Append the current menu name.
            sb.Append($"{Text}{(Items.Count > 0 ? $" ({Items.Count})" : "")}");

            //---- Draw full menu name
            DBG.DrawOutlinedText(sb.ToString(), darkTitleRect.TopLeftCorner() + new Vector2(8, 4),
                                 CustomColorFunction?.Invoke() ?? Color.White, DBG.DEBUG_FONT, startAndEndSpriteBatchForMe: false);

            if (Items.Count != 0)
            {
                if (SelectedIndex < 0)
                {
                    SelectedIndex = 0;
                }
                else if (SelectedIndex >= Items.Count)
                {
                    SelectedIndex = Items.Count - 1;
                }

                var selectedItemRect = GetItemDisplayRect(SelectedIndex, SubMenuRect);

                if (Items.Count != prevFrameItemCount)
                {
                    menuHeight = GetEntireMenuHeight();
                }

                // Only need to calculate scroll stuff if there's text that reaches past the bottom.
                if (menuHeight > SubMenuRect.Height)
                {
                    // Scroll selected into view.

                    //---- If item is ABOVE view
                    if (selectedItemRect.Top < SubMenuRect.Top)
                    {
                        int distanceNeededToScroll = SubMenuRect.Top - selectedItemRect.Top;
                        Scroll -= distanceNeededToScroll;
                    }
                    //---- If item is BELOW view
                    if (selectedItemRect.Bottom > SubMenuRect.Bottom)
                    {
                        int distanceNeededToScroll = selectedItemRect.Bottom - SubMenuRect.Bottom;
                        Scroll += distanceNeededToScroll;
                    }
                }

                // Clamp scroll

                MaxScroll = Math.Max(GetEntireMenuHeight() - SubMenuRect.Height, 0);
                if (Scroll > MaxScroll)
                {
                    Scroll = MaxScroll;
                }
                else if (Scroll < 0)
                {
                    Scroll = 0;
                }

                // Debug display of menu item rectangles:
                //for (int i = 0; i < Items.Count; i++)
                //{
                //    var TEST_DebugDrawItemRect = GetItemDisplayRect(i, SubMenuRect);

                //    GFX.SpriteBatch.Begin();
                //    GFX.SpriteBatch.Draw(MODEL_VIEWER_MAIN.DEFAULT_TEXTURE_DIFFUSE, TEST_DebugDrawItemRect, Color.Yellow);
                //    GFX.SpriteBatch.End();
                //}

                // ONLY draw the menu items that are in-frame

                int roughStartDrawIndex = (int)((Scroll / menuHeight) * (Items.Count - 1)) - 1;
                int roughEndDrawIndex   = (int)(((Scroll + MenuRect.Height) / menuHeight) * (Items.Count - 1)) + 1;

                if (roughStartDrawIndex < 0)
                {
                    roughStartDrawIndex = 0;
                }
                else if (roughStartDrawIndex >= Items.Count)
                {
                    roughStartDrawIndex = Items.Count - 1;
                }

                if (roughEndDrawIndex < 0)
                {
                    roughEndDrawIndex = 0;
                }
                else if (roughEndDrawIndex >= Items.Count)
                {
                    roughEndDrawIndex = Items.Count - 1;
                }

                GFX.SpriteBatchEnd();

                // Store current viewport, then switch viewport to JUST the menu rect
                var oldViewport = GFX.Device.Viewport;
                GFX.Device.Viewport = new Viewport(
                    oldViewport.X + SubMenuRect.X,
                    oldViewport.Y + SubMenuRect.Y,
                    SubMenuRect.Width,
                    SubMenuRect.Height);

                GFX.SpriteBatchBegin();
                // ---- These braces manually force a smaller scope so we
                //      don't forget to return to the old viewport immediately afterward.
                {
                    // Draw Items

                    var selectionPrefixTextSize = Vector2.Zero;// FONT.MeasureString($"  {UICursorBlinkString} ");

                    for (int i = roughStartDrawIndex; i <= roughEndDrawIndex; i++)
                    {
                        Items[i].UpdateUI();
                        var entryText = GetActualItemDisplayText(i);

                        var itemRect = GetItemDisplayRect(i, SubMenuRect);

                        // Check if this item is inside the actual menu rectangle.
                        if (SubMenuRect.Intersects(itemRect))
                        {
                            var itemTextColor = Items[i].CustomColorFunction?.Invoke() ?? ((SelectedIndex == i &&
                                                                                            MenuOpenState == DbgMenuOpenState.Open)
                                ? Color.LightGreen : Color.White);

                            if (SelectedIndex == i && MenuOpenState == DbgMenuOpenState.Open)
                            {
                                var underlineRect = new Rectangle(
                                    itemRect.X - SubMenuRect.X + (int)selectionPrefixTextSize.X - 4,
                                    itemRect.Y - SubMenuRect.Y - 1,
                                    MenuRect.Width - (int)(selectionPrefixTextSize.X) + 4,
                                    itemRect.Height + 2);


                                if (menuHeight > SubMenuRect.Height)
                                {
                                    underlineRect = new Rectangle(underlineRect.X + 12, underlineRect.Y, underlineRect.Width - 4, underlineRect.Height);
                                }

                                GFX.SpriteBatch.Draw(Main.WHITE_TEXTURE, underlineRect,
                                                     Color.Black);
                            }


                            // We have to SUBTRACT the menu top/left coord because the string
                            // drawing is relative to the VIEWPORT, which takes up just the actual menu rect
                            DBG.DrawOutlinedText(entryText,
                                                 new Vector2(itemRect.X - SubMenuRect.X, itemRect.Y - SubMenuRect.Y),
                                                 itemTextColor, FONT, startAndEndSpriteBatchForMe: false);
                        }
                    }

                    // Draw Scrollbar
                    // Only if there's stuff that passes the bottom of the menu.
                    if (menuHeight > SubMenuRect.Height)
                    {
                        //---- Draw Scrollbar Background
                        GFX.SpriteBatch.Draw(Main.WHITE_TEXTURE,
                                             new Rectangle(0, 0, 8, SubMenuRect.Height), Color.White * 0.5f * menuBackgroundOpacityMult);

                        float curScrollRectTop    = (Scroll / menuHeight) * SubMenuRect.Height;
                        float curScrollRectHeight = (SubMenuRect.Height / menuHeight) * SubMenuRect.Height;

                        //---- Scroll Scrollbar current scroll
                        GFX.SpriteBatch.Draw(Main.WHITE_TEXTURE,
                                             new Rectangle(0, (int)curScrollRectTop, 8, (int)curScrollRectHeight),
                                             Color.White * 0.75f * menuBackgroundOpacityMult);
                    }
                }
                //---- Return to old viewport
                GFX.SpriteBatchEnd();
                GFX.Device.Viewport = oldViewport;



                prevFrameItemCount = Items.Count;
            }
        }