Files
2026-07-13 12:26:32 +08:00

111 lines
3.9 KiB
C#

// Copyright 2025 Takuto Nakamura
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace RunCat365
{
internal class CustomToolStripMenuItem : ToolStripMenuItem
{
private static readonly Font MenuFont = new(
SupportedLanguageExtension.GetCurrentLanguage().GetFontName(),
9F,
FontStyle.Regular
);
internal CustomToolStripMenuItem() : base()
{
Font = MenuFont;
}
internal CustomToolStripMenuItem(string? text) : base(text)
{
Font = MenuFont;
}
private CustomToolStripMenuItem(string? text, Image? image, object? tag, bool isChecked, EventHandler? onClick) : base(text, image, onClick)
{
Tag = tag;
Checked = isChecked;
Font = MenuFont;
}
private readonly TextFormatFlags multiLineTextFlags =
TextFormatFlags.LeftAndRightPadding |
TextFormatFlags.VerticalCenter |
TextFormatFlags.WordBreak |
TextFormatFlags.TextBoxControl;
private readonly TextFormatFlags singleLineTextFlags =
TextFormatFlags.LeftAndRightPadding |
TextFormatFlags.VerticalCenter |
TextFormatFlags.EndEllipsis;
public override Size GetPreferredSize(Size constrainingSize)
{
Size baseSize = base.GetPreferredSize(constrainingSize);
if (string.IsNullOrEmpty(Text))
{
return new Size(baseSize.Width, 22);
}
var textRenderWidth = Math.Max(constrainingSize.Width - 20, 1);
SizeF measuredSize = TextRenderer.MeasureText(
Text,
Font,
new Size(textRenderWidth, int.MaxValue),
Flags()
);
var calculatedHeight = (int)Math.Ceiling(measuredSize.Height) + 4;
var height = IsSingleLine() ? calculatedHeight : Math.Max(baseSize.Height, calculatedHeight);
return new Size(baseSize.Width, height);
}
internal bool IsSingleLine()
{
return string.IsNullOrEmpty(Text) || !Text.Contains('\n');
}
internal TextFormatFlags Flags()
{
return IsSingleLine() ? singleLineTextFlags : multiLineTextFlags;
}
internal void SetupSubMenusFromEnum<T>(
Func<T, string> getTitle,
Action<CustomToolStripMenuItem, object?, EventArgs> onClick,
Func<T, bool> isChecked,
Func<Runner, Bitmap?> getRunnerThumbnailBitmap,
Func<T, bool>? isVisible = null
) where T : Enum
{
isVisible ??= _ => true;
var items = new List<CustomToolStripMenuItem>();
foreach (T value in Enum.GetValues(typeof(T)))
{
if (!isVisible(value)) continue;
var entityName = getTitle(value);
var iconImage = value is Runner runner ? getRunnerThumbnailBitmap(runner) : null;
var item = new CustomToolStripMenuItem(
entityName,
iconImage,
value,
isChecked(value),
(sender, e) => onClick(this, sender, e)
);
items.Add(item);
}
DropDownItems.AddRange([.. items]);
}
}
}