< Summary

Class:Imagini.WindowSettings
Assembly:Imagini.Core
File(s):/home/razer/vscode-projects/project-grove/imagini/Imagini.Core/WindowSettings.cs
Covered lines:49
Uncovered lines:36
Coverable lines:85
Total lines:231
Line coverage:57.6% (49 of 85)
Covered branches:26
Total branches:44
Branch coverage:59% (26 of 44)

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
GetWindowMode(...)10075%70%
GetFlags()100100%70%
Apply(...)1075%100%
ChangeVideoMode(...)20040.62%60%
MoveToDisplay(...)100%100%
HasFlag(...)10100%100%
Clone()10100%100%
.cctor()10100%100%

File(s)

/home/razer/vscode-projects/project-grove/imagini/Imagini.Core/WindowSettings.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4
 5using static Imagini.ErrorHandler;
 6using static SDL2.SDL_hints;
 7using static SDL2.SDL_video;
 8
 9namespace Imagini
 10{
 11    /// <summary>
 12    /// Defines window display mode.
 13    /// </summary>
 14    public enum WindowMode
 15    {
 16        Windowed,
 17        Borderless,
 18        Fullscreen,
 19        BorderlessFullscreen
 20    }
 21
 22    /// <summary>
 23    /// Defines app window settings.
 24    /// </summary>
 25    public class WindowSettings : ICloneable
 26    {
 27        /// <summary>
 28        /// Width of the window in pixels.
 29        /// </summary>
 30        /// <remarks>Default is 800.</remarks>
 29831        public int WindowWidth { get; set; } = 800;
 32        /// <summary>
 33        /// Height of the window in pixels.
 34        /// </summary>
 35        /// <remarks>Default is 600.</remarks>
 29836        public int WindowHeight { get; set; } = 600;
 37        /// <summary>
 38        /// Flag indicating if the window should be fullscreen.
 39        /// </summary>
 40        /// <remarks>Default is false.</remarks>
 23441        public bool IsFullscreen { get; set; } = false;
 42        /// <summary>
 43        /// Indicates if the vertical sync should be enabled (if supported).
 44        /// </summary>
 45        /// <remarks>Default is true.</remarks>
 23346        public bool VSync { get; set; } = true;
 47        /// <summary>
 48        /// Flag indicating if the window should be visible.
 49        /// </summary>
 50        /// <remarks>
 51        /// Used only on window creation, to change window visibility after
 52        /// creation use <see cref="Window.Show" /> and <see cref="Window.Hide" />.
 53        /// Default is true.
 54        /// </remarks>
 22155        public bool IsVisible { get; set; } = true;
 56        /// <summary>
 57        /// Flag indicating if the window should be borderless.
 58        /// </summary>
 59        /// <remarks>Default is false.</remarks>
 23160        public bool IsBorderless { get; set; } = false;
 61        /// <summary>
 62        /// Flag indicating if the window should be resizable.
 63        /// </summary>
 64        /// <remarks>
 65        /// Should be specified at window creation, cannot be changed later.
 66        /// Default is false.
 67        /// </remarks>
 13968        public bool IsResizable { get; set; } = false;
 69        /// <summary>
 70        /// Flag indicating if the OS should treat the window as high-DPI aware.
 71        /// </summary>
 72        /// <remarks>
 73        /// Should be specified at window creation, cannot be changed later.
 74        /// Default is false.
 75        /// </remarks>
 7676        public bool AllowHighDpi { get; set; } = false;
 77
 78        /// <summary>
 79        /// Specifies a display index on which the window should be positioned.
 80        /// </summary>
 81        /// <remarks>Default is 0 (primary display).</remarks>
 22982        public int DisplayIndex { get; set; } = 0;
 83        /// <summary>
 84        /// Specifies the window title.
 85        /// </summary>
 86        /// <remarks>
 87        /// Used only on window creation, to change window title after
 88        /// creation use <see cref="Window.Title" />.
 89        /// </remarks>
 30590        public string Title { get; set; } = "Imagini";
 91
 92        /// <summary>
 93        /// Gets or sets the window mode.
 94        /// </summary>
 95        public WindowMode WindowMode
 96        {
 15597            get => GetWindowMode(IsFullscreen, IsBorderless);
 98            set
 99            {
 0100                IsFullscreen =
 0101                    value == WindowMode.Fullscreen ||
 0102                    value == WindowMode.BorderlessFullscreen;
 0103                IsBorderless =
 0104                    value == WindowMode.Borderless ||
 0105                    value == WindowMode.BorderlessFullscreen;
 0106            }
 107        }
 108
 109        /// <summary>
 110        /// Gets or sets the display mode used when the app is fullscreen.
 111        /// </summary>
 78112        public DisplayMode FullscreenDisplayMode { get; set; } = DisplayMode.GetCurrent(0);
 113
 114        private WindowMode GetWindowMode(bool isFullscreen, bool isBorderless)
 115        {
 462116            if (!isFullscreen && !isBorderless) return WindowMode.Windowed;
 2117            else if (!isFullscreen && isBorderless) return WindowMode.Borderless;
 4118            else if (isFullscreen && !isBorderless) return WindowMode.Fullscreen;
 0119            else return WindowMode.BorderlessFullscreen;
 120        }
 121
 122        /// <summary>
 123        /// Returns SDL window creation flags.
 124        /// </summary>
 125        public uint GetFlags()
 126        {
 76127            var result = 0u;
 128            // result |= SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayIndex);
 76129            if (IsFullscreen) result |= (uint)SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
 76130            if (IsVisible)
 56131                result |= (uint)SDL_WindowFlags.SDL_WINDOW_SHOWN;
 132            else
 20133                result |= (uint)SDL_WindowFlags.SDL_WINDOW_HIDDEN;
 76134            if (IsBorderless) result |= (uint)SDL_WindowFlags.SDL_WINDOW_BORDERLESS;
 139135            if (IsResizable) result |= (uint)SDL_WindowFlags.SDL_WINDOW_RESIZABLE;
 76136            if (AllowHighDpi) result |= (uint)SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI;
 76137            return result;
 138        }
 139
 140        internal void Apply(IntPtr window)
 141        {
 77142            var flags = SDL_GetWindowFlags(window);
 77143            bool alreadyFullscreen = HasFlag(flags, SDL_WindowFlags.SDL_WINDOW_FULLSCREEN);
 77144            bool alreadyBorderless = HasFlag(flags, SDL_WindowFlags.SDL_WINDOW_BORDERLESS);
 145
 77146            var curMode = GetWindowMode(alreadyFullscreen, alreadyBorderless);
 77147            var curIndex = Display.GetCurrentDisplayIndexForWindow(window);
 77148            var targetMode = WindowMode;
 77149            var targetIndex = DisplayIndex;
 150
 151            // If the WindowMode or target display have changed, do some preparation
 77152            ChangeVideoMode(window, curMode, targetMode, curIndex, targetIndex);
 0153            Check(() => SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,
 0154                VSync ? "1" : "0", SDL_HintPriority.SDL_HINT_OVERRIDE),
 0155                "SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC, OVERRIDE)");
 77156        }
 157
 158        private void ChangeVideoMode(IntPtr window, WindowMode curMode, WindowMode targetMode,
 159            int curIndex, int targetIndex)
 160        {
 161            // Set target window size for Windowed and Borderless modes
 77162            SDL_SetWindowSize(window, WindowWidth, WindowHeight);
 77163            var flags = SDL_GetWindowFlags(window);
 0164            var shouldBeFullscreen =
 0165                (targetMode == WindowMode.Fullscreen) ||
 0166                (targetMode == WindowMode.BorderlessFullscreen);
 167
 168            // switch to windowed mode and move to corresponding display
 169            // if the target display for fullscreen mode have changed
 77170            if (curIndex != targetIndex && shouldBeFullscreen)
 171            {
 0172                Try(() => SDL_SetWindowFullscreen(window, 0), "SDL_SetWindowFullscreen");
 0173                MoveToDisplay(window, targetIndex);
 0174                curMode = HasFlag(flags, SDL_WindowFlags.SDL_WINDOW_BORDERLESS) ?
 0175                    WindowMode.Borderless : WindowMode.Windowed;
 0176                curIndex = targetIndex;
 177            }
 0178            var alreadyFullscreen =
 0179                (curMode == WindowMode.Fullscreen) ||
 0180                (curMode == WindowMode.BorderlessFullscreen);
 181            // Set the target params for the Fullscreen mode
 77182            if (shouldBeFullscreen)
 183            {
 1184                var targetDM = FullscreenDisplayMode;
 0185                Try(() =>
 1186                    SDL_SetWindowDisplayMode(window, ref targetDM._mode),
 0187                    "SDL_SetWindowDisplayMode");
 188            }
 153189            if (curMode == targetMode) return;
 190            // Set the fullscreen mode flag
 1191            var fullscreenOpt = 0u;
 192            switch (targetMode)
 193            {
 194                case WindowMode.BorderlessFullscreen:
 0195                    fullscreenOpt = (uint)SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
 0196                    break;
 197                case WindowMode.Fullscreen:
 1198                    fullscreenOpt = (uint)SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
 199                    break;
 200            }
 0201            Try(() =>
 1202                SDL_SetWindowFullscreen(window, fullscreenOpt),
 0203                "SDL_SetWindowFullscreen");
 204            // Set the window border flag if it doesn't occupy the whole screen
 205            // because SDL_WINDOW_FULLSCREEN_DESKTOP sets it automatically
 1206            if (targetMode == WindowMode.Borderless)
 0207                SDL_SetWindowBordered(window, 0);
 1208            else if (targetMode == WindowMode.Windowed)
 0209                SDL_SetWindowBordered(window, 1);
 1210        }
 211
 212        private void MoveToDisplay(IntPtr window, int displayIndex, int x = 0, int y = 0)
 213        {
 0214            var display = Display.All[displayIndex];
 0215            var bounds = display.Bounds;
 0216            var targetX = bounds.x + x;
 0217            var targetY = bounds.y + y;
 0218            SDL_SetWindowPosition(window, targetX, targetY);
 0219        }
 220
 221        private bool HasFlag(uint flags, SDL_WindowFlags flag) =>
 154222            (flags & (uint)flag) == (uint)flag;
 223
 224        /// <summary>
 225        /// Creates a shallow copy of this object.
 226        /// </summary>
 77227        public object Clone() => this.MemberwiseClone();
 228
 1229        static WindowSettings() => Lifecycle.TryInitialize();
 230    }
 231}