/************************************************************************* * ModernUO * * Copyright 2019-2026 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GridSizeSpec.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ using System; using System.Runtime.CompilerServices; namespace Server.Gumps; /// /// Specifies how a grid column or row should be sized. /// Supports absolute pixels, percentage, and star (proportional) sizing. /// public readonly struct GridSizeSpec { /// /// The sizing type. /// public readonly GridSizeType Type; /// /// The value - meaning depends on Type: /// - Absolute: pixel size /// - Percent: percentage of total size (1-100) /// - Star: proportional weight (1 = equal share) /// public readonly int Value; [MethodImpl(MethodImplOptions.AggressiveInlining)] private GridSizeSpec(GridSizeType type, int value) { Type = type; Value = value; } /// /// Creates an absolute pixel size specification. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static GridSizeSpec Absolute(int pixels) => new(GridSizeType.Absolute, pixels); /// /// Creates a star (proportional) size specification. /// Star-sized tracks share the remaining space equally (after absolute/percent are allocated). /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static GridSizeSpec Star() => new(GridSizeType.Star, 1); /// /// Creates a percentage size specification. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static GridSizeSpec Percent(int percent) => new(GridSizeType.Percent, percent); /// /// Parses a single size specification token. /// Formats: /// - "*" = star (equal share of remaining space) /// - "10*" = 10% of total size /// - "100" = 100 pixels absolute /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static GridSizeSpec Parse(ReadOnlySpan token) { token = token.Trim(); if (token.IsEmpty) { return Star(); } // Check for star notation var starIndex = token.IndexOf('*'); if (starIndex == -1) { // No star - absolute pixel value return int.TryParse(token, out var pixels) ? Absolute(pixels) : Star(); } if (starIndex == 0 && token.Length == 1) { // Just "*" - equal share star return Star(); } // "N*" format - percentage var percentPart = token[..starIndex]; return int.TryParse(percentPart, out var percent) ? Percent(percent) : Star(); } /// /// Parses a space-separated size specification string into a span of GridSizeSpec values. /// Returns the number of specs parsed. /// public static int ParseAll(ReadOnlySpan sizeSpec, Span destination) { var count = 0; var remaining = sizeSpec; while (!remaining.IsEmpty && count < destination.Length) { // Skip leading whitespace remaining = remaining.TrimStart(); if (remaining.IsEmpty) { break; } // Find end of current token var spaceIndex = remaining.IndexOf(' '); ReadOnlySpan token; if (spaceIndex < 0) { token = remaining; remaining = default; } else { token = remaining[..spaceIndex]; remaining = remaining[(spaceIndex + 1)..]; } destination[count++] = Parse(token); } return count; } } /// /// Specifies the type of grid size specification. /// public enum GridSizeType : byte { /// /// Fixed pixel size. /// Absolute, /// /// Star sizing - shares remaining space equally with other star-sized tracks. /// Star, /// /// Percentage of total available size. /// Percent }