private void ShowOptions()
        {
            if (def.preview)
            {
                var options = new List <FloatMenuOption_SubCategory>();
                foreach (Designator_SubCategoryItem designator in ValidSubDesignators)
                {
                    // action is handled by FloatMenuOption_SubCategory
                    // note that normally setting action to null would cause the option to be disabled, but
                    // this behaviour is defined in the OnGui method, which we're overriding anyway.
                    options.Add(new FloatMenuOption_SubCategory(designator, null));
                }

                Find.WindowStack.Add(new FloatMenu_SubCategory(options, null, new Vector2(75, 75)));
            }
            else
            {
                // if we don't have to draw preview images, we can re-use the default floatmenu
                var options = new List <FloatMenuOption>();
                foreach (Designator_SubCategoryItem designator in ValidSubDesignators)
                {
                    // TODO: Check if subdesignator is allowed (also check if this check is even needed, as !Visible is already filtered out)
                    options.Add(new FloatMenuOption(designator.LabelCap,
                                                    delegate { Find.DesignatorManager.Select(designator); },
                                                    MenuOptionPriority.Default,
                                                    delegate { DesignatorUtility.DoInfoBox(ArchitectCategoryTab.InfoRect, designator); }));
                }

                Find.WindowStack.Add(new FloatMenu(options, null));
            }
        }
        public override void DoWindowContents(Rect canvas)
        {
            // define our own implementation, mostly copy-pasta with a few edits for option sizes
            // actual drawing is handled in OptionOnGUI.
            UpdateBaseColor();
            GUI.color = baseColor;
            Vector2 listRoot = ListRoot;

            Text.Font = GameFont.Small;
            var row = 0;
            var col = 0;

            if (_options.NullOrEmpty())
            {
                return;
            }

            Text.Font = GameFont.Tiny;

            var sortedOptions = _options.OrderByDescending(op => op.Priority);

            var optionValuesArray = new OptionValues[_options.Count];

            for (int i = 0; i < _options.Count; i++)
            {
                var option = sortedOptions.ElementAt(i);

                float posX = listRoot.x + col * (_optionSize.x + _margin);
                float posY = listRoot.y + row * (_optionSize.y + _margin);

                optionValuesArray[i].DrawArea = new Rect(posX, posY, option.gizmo.GetWidth(TotalWidth), 75f);

                GUI.color = baseColor;
                optionValuesArray[i].mouseIsOver = option.DoGUI_BG(optionValuesArray[i].DrawArea);


                row++;
                if (row >= ColumnMaxOptionCount)
                {
                    row = 0;
                    col++;
                }
            }


            for (int i = 0; i < _options.Count; i++)
            {
                var option = sortedOptions.ElementAt(i);

                GUI.color = baseColor;

                optionValuesArray[i].commandIsTriggered = option.DoGUI_Label(optionValuesArray[i].DrawArea);
            }

            for (int i = 0; i < _options.Count; i++)
            {
                var option = sortedOptions.ElementAt(i);

                var logic = option.DoGUI_Logic(optionValuesArray[i].mouseIsOver,
                                               optionValuesArray[i].commandIsTriggered);
                if (logic.State == GizmoState.Interacted)
                {
                    option.gizmo.ProcessInput(logic.InteractEvent);
                }
                else if (logic.State == GizmoState.Mouseover)
                {
                    DesignatorUtility.DoInfoBox(ArchitectCategoryTab.InfoRect, option.gizmo);
                }

                if (_closeOnSelection && Widgets.ButtonInvisible(optionValuesArray[i].DrawArea))
                {
                    Find.WindowStack.TryRemove(this, true);
                }
            }

            GUI.color = Color.white;
            Text.Font = GameFont.Small;
        }