Setup() публичный Метод

public Setup ( bool force ) : void
force bool
Результат void
Пример #1
0
        private bool ChangeImage(string fileName)
        {
            Dragging = false;
            Vector2u prevSize            = new Vector2u(Image.Texture.Size.X, Image.Texture.Size.Y);
            float    prevRotation        = Image.Rotation;
            int      prevDefaultRotation = DefaultRotation;

            IntRect bounds = ImageViewerUtils.GetCurrentBounds(Window.Position +
                                                               new Vector2i((int)(Image.Texture.Size.X * CurrentZoom) / 2, (int)(Image.Texture.Size.Y * CurrentZoom) / 2));

            if (AutomaticallyZoomed || FitToMonitorHeightForced)
            {
                // don't keep current zoom value if it wasn't set by user
                AutomaticallyZoomed      = false;
                FitToMonitorHeightForced = false;
                CurrentZoom = 1;
            }

            // Dispose of previous image
            Image.Dispose();
            Image = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

            // Load new image
            if (!LoadImage(fileName))
            {
                return(false);
            }

            SFML.Graphics.View view = new SFML.Graphics.View(Window.DefaultView);
            view.Center = new Vector2f(Image.Texture.Size.X / 2, Image.Texture.Size.Y / 2);
            view.Size   = new Vector2f(Image.Texture.Size.X, Image.Texture.Size.Y);
            Window.SetView(view);

            // Rotation
            RotateImage(prevRotation == prevDefaultRotation ? DefaultRotation : (int)prevRotation, false);
            // Smoothing
            if (Image is AnimatedImage)
            {
                Image.Data.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
            }
            else
            {
                Image.Texture.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
            }

            bool wasFitToMonitorDimension = FitToMonitorHeightForced;

            if (Config.Setting_LimitImagesToMonitor != Config.NONE)
            {
                // Fit to monitor height/width
                int limit = Config.Setting_LimitImagesToMonitor;

                if (limit == Config.AUTO)
                {
                    if (bounds.Height < bounds.Width)
                    {
                        limit = Config.HEIGHT;
                    }
                    else
                    {
                        limit = Config.WIDTH;
                    }
                }

                if (limit == Config.HEIGHT && (FitToMonitorHeight || CurrentImageSize().Y *CurrentZoom > bounds.Height))
                {
                    Zoom(1 + (((float)bounds.Height - CurrentImageSize().Y) / CurrentImageSize().Y), true);

                    bounds = ImageViewerUtils.GetCurrentBounds(NextWindowPos +
                                                               new Vector2i((int)(CurrentImageSize().X *CurrentZoom) / 2, (int)(CurrentImageSize().Y *CurrentZoom) / 2));
                    NextWindowPos = new Vector2i(NextWindowPos.X, bounds.Top);

                    if (!FitToMonitorHeight)
                    {
                        FitToMonitorHeightForced = true;
                    }

                    wasFitToMonitorDimension = true;
                }
                else if (limit == Config.WIDTH && CurrentImageSize().X *CurrentZoom > bounds.Width)
                {
                    Zoom(1 + (((float)bounds.Width - CurrentImageSize().X) / CurrentImageSize().X), true);

                    bounds = ImageViewerUtils.GetCurrentBounds(NextWindowPos +
                                                               new Vector2i((int)(CurrentImageSize().X *CurrentZoom) / 2, (int)(CurrentImageSize().Y *CurrentZoom) / 2));
                    NextWindowPos = new Vector2i(bounds.Left, NextWindowPos.Y);

                    AutomaticallyZoomed      = true;
                    wasFitToMonitorDimension = true;
                }
            }
            if (!wasFitToMonitorDimension)
            {
                if (FitToMonitorHeightForced)
                {
                    Zoom(1, true);
                    FitToMonitorHeightForced = false;
                }
                else if (Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) * CurrentZoom < Config.Setting_MinImageSize)
                {
                    // Reisze images smaller than min size to min size
                    if (Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_MinImageSize)
                    {
                        AutomaticallyZoomed = true;
                        Zoom(Config.Setting_MinImageSize / Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y), true);
                    }
                    else
                    {
                        Zoom(1, true);
                    }
                }
                else
                {
                    Zoom(CurrentZoom, true);
                }
            }

            bounds = ImageViewerUtils.GetCurrentBounds(NextWindowPos +
                                                       new Vector2i((int)(Image.Texture.Size.X * CurrentZoom) / 2, (int)(Image.Texture.Size.Y * CurrentZoom) / 2));

            // Position Window at top-left if the image is wide (ie: a Desktop Wallpaper / Screenshot)
            // Otherwise, if image is hanging off monitor just center it.
            if (Config.Setting_PositionLargeWideImagesInCorner && CurrentImageSize().X > CurrentImageSize().Y&& CurrentImageSize().X *CurrentZoom >= bounds.Width)
            {
                NextWindowPos = new Vector2i(bounds.Left, bounds.Top);
            }
            else if (!prevSize.Equals(Image.Texture.Size) && (NextWindowPos.X + (Image.Texture.Size.X * CurrentZoom) >= bounds.Left + bounds.Width ||
                                                              NextWindowPos.Y + (Image.Texture.Size.Y * CurrentZoom) >= bounds.Top + bounds.Height))
            {
                NextWindowPos = new Vector2i(bounds.Left + (int)((bounds.Width - (Image.Texture.Size.X * CurrentZoom)) / 2), bounds.Top + (int)((bounds.Height - (Image.Texture.Size.Y * CurrentZoom)) / 2));
            }

            // Force Always On Top Mode (so it's above the task bar) - will only happen if height >= window height
            ForceAlwaysOnTopNextTick = true;

            Window.SetTitle(fileName + " - vimage");
            ContextMenu.Setup(false);

            return(true);
        }
Пример #2
0
        private bool ChangeImage(string fileName)
        {
            Image.Dispose();
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

            Dragging = false;
            float prevRotation        = Image.Rotation;
            int   prevDefaultRotation = DefaultRotation;

            if (AutomaticallyZoomed)
            {
                // don't keep current zoom value if it wasn't set by user
                AutomaticallyZoomed = false;
                CurrentZoom         = 1;
            }

            if (!LoadImage(fileName))
            {
                return(false);
            }

            SFML.Graphics.View view = new SFML.Graphics.View(Window.DefaultView);
            view.Center = new Vector2f(Image.Texture.Size.X / 2, Image.Texture.Size.Y / 2);
            view.Size   = new Vector2f(Image.Texture.Size.X, Image.Texture.Size.Y);
            Window.SetView(view);

            // Rotation
            RotateImage(prevRotation == prevDefaultRotation ? DefaultRotation : (int)prevRotation, false);
            // Smoothing
            if (Image is AnimatedImage)
            {
                Image.Data.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
            }
            else
            {
                Image.Texture.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
            }

            IntRect bounds = ImageViewerUtils.GetCurrentBounds(Window.Position);

            if (Config.Setting_LimitImagesToMonitorHeight && (FitToMonitorHeight || (Image.Texture.Size.Y * CurrentZoom >= bounds.Height || (FitToMonitorHeightForced && Image.Texture.Size.Y >= bounds.Height))))
            {
                // Fit to monitor height if it's higher than monitor height (or FitToMonitorHeight is true).
                Zoom(1 + (((float)bounds.Height - Image.Texture.Size.Y) / Image.Texture.Size.Y), true);
                NextWindowPos = new Vector2i(NextWindowPos.X, bounds.Top);
                if (!FitToMonitorHeight)
                {
                    FitToMonitorHeightForced = true;
                }
            }
            else if (FitToMonitorHeightForced)
            {
                Zoom(1, true);
                FitToMonitorHeightForced = false;
            }
            else if (Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) * CurrentZoom < Config.Setting_MinImageSize)
            {
                // Reisze images smaller than min size to min size
                AutomaticallyZoomed = true;
                Zoom(Config.Setting_MinImageSize / Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y), true);
            }
            else
            {
                Zoom(CurrentZoom, true);
            }

            // Position Window at 0,0 if the image is wide (ie: a Desktop Wallpaper / Screenshot)
            if (Config.Setting_PositionLargeWideImagesInCorner && Image.Texture.Size.X > Image.Texture.Size.Y && Image.Texture.Size.X * CurrentZoom >= VideoMode.DesktopMode.Width)
            {
                NextWindowPos = new Vector2i(0, 0);
            }

            // Force Always On Top Mode (so it's above the task bar) - will only happen if height >= window height
            ForceAlwaysOnTopNextTick = true;

            Window.SetTitle(fileName + " - vimage");
            ContextMenu.Setup(false);

            return(true);
        }
Пример #3
0
        public ImageViewer(string file)
        {
            IL.Initialize();
            Graphics.Init();

            // Extension supported?
            if (!ImageViewerUtils.IsValidExtension(file, EXTENSIONS))
            {
                return;
            }

            // Save Mouse Position -> will open image at this position
            Vector2i mousePos = Mouse.GetPosition();

            // Get Image
            LoadImage(file);

            if (Image == null)
            {
                return;
            }

            // Load Config File
            Config = new Config();
            Config.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.txt"));

            if (Config.Setting_ListenForConfigChanges)
            {
                ConfigFileWatcher = new FileSystemWatcher(AppDomain.CurrentDomain.BaseDirectory, "config.txt");
                ConfigFileWatcher.NotifyFilter        = NotifyFilters.LastWrite;
                ConfigFileWatcher.Changed            += new FileSystemEventHandler(OnConfigChanged);
                ConfigFileWatcher.EnableRaisingEvents = true;
            }

            // Create Context Menu
            ContextMenu = new ContextMenu(this);
            ContextMenu.LoadItems(Config.ContextMenu, Config.ContextMenu_Animation, Config.ContextMenu_Animation_InsertAtIndex);
            ContextMenu.Setup(false);

            // Create Window
            Window = new RenderWindow(new VideoMode(Image.Texture.Size.X, Image.Texture.Size.Y), File + " - vimage", Styles.None);
            Window.SetActive();

            // Make Window Transparent (can only tell if image being viewed has transparency)
            DWM_BLURBEHIND bb = new DWM_BLURBEHIND(false);

            bb.dwFlags  = DWM_BB.Enable;
            bb.fEnable  = true;
            bb.hRgnBlur = new IntPtr();
            DWM.DwmEnableBlurBehindWindow(Window.SystemHandle, ref bb);

            bool _forceAlwaysOnTop = false;

            // Get Bounds
            IntRect bounds = ImageViewerUtils.GetCurrentBounds(mousePos);

            // Resize Window
            if (Config.Setting_LimitImagesToMonitor != Config.NONE)
            {
                // Fit to monitor height/width
                int limit = Config.Setting_LimitImagesToMonitor;

                if (limit == Config.AUTO)
                {
                    if (bounds.Height < bounds.Width)
                    {
                        limit = Config.HEIGHT;
                    }
                    else
                    {
                        limit = Config.WIDTH;
                    }
                }

                if (limit == Config.HEIGHT && Image.Texture.Size.Y > bounds.Height)
                {
                    Zoom(1 + (((float)bounds.Height - Image.Texture.Size.Y) / Image.Texture.Size.Y), true);
                    FitToMonitorHeightForced = true;
                }
                else if (limit == Config.WIDTH && Image.Texture.Size.X > bounds.Width)
                {
                    Zoom(1 + (((float)bounds.Width - Image.Texture.Size.X) / Image.Texture.Size.X), true);
                    AutomaticallyZoomed = true;
                }
            }
            if (Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_MinImageSize)
            {
                // Reisze images smaller than min size to min size
                AutomaticallyZoomed = true;
                Zoom(Config.Setting_MinImageSize / Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y), true);
            }
            // Use Texture Size * Zoom instead of Window.Size since it wouldn't have updated yet
            Vector2i winSize = new Vector2i((int)(Image.Texture.Size.X * CurrentZoom), (int)(Image.Texture.Size.Y * CurrentZoom));


            // Position Window
            Vector2i winPos;

            if (Config.Setting_PositionLargeWideImagesInCorner && CurrentImageSize().X > CurrentImageSize().Y&& CurrentImageSize().X *CurrentZoom >= bounds.Width)
            {
                // Position Window in top-left if the image is wide (ie: a Desktop Wallpaper / Screenshot)
                winPos = new Vector2i(bounds.Left, bounds.Top);
            }
            else if (Config.Setting_OpenAtMousePosition)
            {
                // At Mouse Position
                winPos = new Vector2i(mousePos.X - (int)(winSize.X / 2), mousePos.Y - (int)(winSize.Y / 2));

                if (!FitToMonitorHeightForced)
                {
                    if (winPos.Y < bounds.Top)
                    {
                        winPos.Y = 0;
                    }
                    else if (winPos.Y + winSize.Y > bounds.Height)
                    {
                        winPos.Y = bounds.Height - (int)winSize.Y;
                    }
                }
                else
                {
                    winPos.Y = bounds.Top;
                }

                if (winPos.X < bounds.Left)
                {
                    winPos.X = bounds.Left;
                }
                else if (winPos.X + winSize.X > bounds.Left + bounds.Width)
                {
                    winPos.X = bounds.Left + bounds.Width - (int)winSize.X;
                }
            }
            else
            {
                // At Monitor Center
                IntRect monitorBounds = ImageViewerUtils.GetCurrentBounds(mousePos);
                winPos = new Vector2i(monitorBounds.Left + (int)((monitorBounds.Width - winSize.X) / 2), monitorBounds.Top + (int)((monitorBounds.Height - winSize.Y) / 2));
            }

            Window.Position = winPos;

            // Force Always On Top Mode (so it's above the task bar)
            if (FitToMonitorHeightForced || (Image.Texture.Size.Y >= bounds.Height && Image.Texture.Size.X < bounds.Width))
            {
                _forceAlwaysOnTop = true;
            }

            // Defaults
            // Rotation (some images have a rotation set in their exif data)
            RotateImage(DefaultRotation, false);
            // Smoothing
            if (Image is AnimatedImage)
            {
                Image.Data.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
            }
            else
            {
                Image.Texture.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
            }
            // Backgrounds For Images With Transparency
            BackgroundsForImagesWithTransparency = Config.Setting_BackgroundForImagesWithTransparencyDefault;

            ForceAlwaysOnTopNextTick = _forceAlwaysOnTop;

            Redraw();
            NextWindowPos = Window.Position;

            // Interaction
            Window.Closed              += OnWindowClosed;
            Window.MouseButtonPressed  += OnMouseDown;
            Window.MouseButtonReleased += OnMouseUp;
            Window.MouseWheelMoved     += OnMouseWheelMoved;
            Window.MouseMoved          += OnMouseMoved;
            Window.KeyReleased         += OnKeyUp;
            Window.KeyPressed          += OnKeyDown;

            // Loop
            Stopwatch clock = new Stopwatch();

            clock.Start();

            while (Window.IsOpen())
            {
                // Add in some idle time to not thrash the CPU
                Thread.Sleep(1);

                if (CloseNextTick)
                {
                    Window.Close();
                    break;
                }

                // Process events
                Window.DispatchEvents();

                if (ReloadConfigNextTick)
                {
                    ReloadConfig();
                    ReloadConfigNextTick = false;
                }

                // Animated Image?
                if (Image is AnimatedImage)
                {
                    bool imageUpdated = Image.Update((float)clock.Elapsed.TotalMilliseconds);
                    if (!Updated && imageUpdated)
                    {
                        Update();
                    }
                }
                clock.Restart();

                // Drag Window
                if (Dragging)
                {
                    Window.Position = new Vector2i(Mouse.GetPosition().X - DragPos.X, Mouse.GetPosition().Y - DragPos.Y);
                }

                // Update
                if (Updated)
                {
                    Updated = false;
                    Redraw();
                    Window.Position = NextWindowPos;
                }

                if (ForceAlwaysOnTopNextTick)
                {
                    bounds = ImageViewerUtils.GetCurrentBounds(Window.Position);
                    if (Window.Size.Y >= bounds.Height && Window.Size.X < bounds.Width)
                    {
                        ForceAlwaysOnTop();
                    }
                    else
                    {
                        ForceAlwaysOnTopNextTick = false;
                    }
                }

                if (PreloadNextImageStart)
                {
                    PreloadNextImage();
                }
            }
        }
Пример #4
0
        public ImageViewer(string file)
        {
            IL.Initialize();

            // Extension supported?
            if (!ImageViewerUtils.IsValidExtension(file, EXTENSIONS))
                return;

            // Save Mouse Position -> will open image at this position
            Vector2i mousePos = Mouse.GetPosition();

            // Get Image
            LoadImage(file);

            if (Image == null)
                return;

            // Load Config File
            Config = new Config();
            Config.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.txt"));

            if (Config.Setting_ListenForConfigChanges)
            {
                ConfigFileWatcher = new FileSystemWatcher(AppDomain.CurrentDomain.BaseDirectory, "config.txt");
                ConfigFileWatcher.NotifyFilter = NotifyFilters.LastWrite;
                ConfigFileWatcher.Changed += new FileSystemEventHandler(OnConfigChanged);
                ConfigFileWatcher.EnableRaisingEvents = true;
            }

            // Get/Set Folder Sorting
            SortImagesBy = Config.Setting_DefaultSortBy;
            SortImagesByDir = Config.Setting_DefaultSortDir;

            if (SortImagesBy == SortBy.FolderDefault || SortImagesByDir == SortDirection.FolderDefault)
            {
                // Get parent folder name
                string parentFolder = file.Substring(0, file.LastIndexOf('\\'));
                parentFolder = parentFolder.Substring(parentFolder.LastIndexOf('\\') + 1, parentFolder.Length - parentFolder.LastIndexOf('\\') - 1);

                // Get sort column info from window with corresponding name
                SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows();
                foreach (SHDocVw.ShellBrowserWindow shellWindow in shellWindows)
                {
                    if (shellWindow.LocationName != parentFolder)
                        continue;

                    Shell32.ShellFolderView view = (Shell32.ShellFolderView)shellWindow.Document;

                    string sort = view.SortColumns;
                    sort = sort.Substring(5, sort.Length - 5);

                    // Direction
                    if (sort[0] == '-')
                    {
                        sort = sort.Substring(1, sort.Length - 1);

                        if (SortImagesByDir == SortDirection.FolderDefault)
                            SortImagesByDir = SortDirection.Descending;
                    }
                    else if (SortImagesByDir == SortDirection.FolderDefault)
                        SortImagesByDir = SortDirection.Ascending;

                    // By
                    if (SortImagesBy == SortBy.FolderDefault)
                    {
                        switch (sort)
                        {
                            case "System.ItemDate;": SortImagesBy = SortBy.Date; break;
                            case "System.DateModified;": SortImagesBy = SortBy.DateModified; break;
                            case "System.DateCreated;": SortImagesBy = SortBy.DateCreated; break;
                            case "System.Size;": SortImagesBy = SortBy.Size; break;
                            default: SortImagesBy = SortBy.Name; break;
                        }
                    }
                }
            }
            // Default sorting if folder was closed
            if (SortImagesBy == SortBy.FolderDefault)
                SortImagesBy = SortBy.Name;
            if (SortImagesByDir == SortDirection.FolderDefault)
                SortImagesByDir = SortDirection.Ascending;

            // Create Context Menu
            ContextMenu = new ContextMenu(this);
            ContextMenu.LoadItems(Config.ContextMenu, Config.ContextMenu_Animation, Config.ContextMenu_Animation_InsertAtIndex);
            ContextMenu.Setup(false);

            // Create Window
            Window = new RenderWindow(new VideoMode(Image.Texture.Size.X, Image.Texture.Size.Y), File + " - vimage", Styles.None);
            Window.SetActive();

            // Make Window Transparent (can only tell if image being viewed has transparency)
            DWM_BLURBEHIND bb = new DWM_BLURBEHIND(false);
            bb.dwFlags = DWM_BB.Enable;
            bb.fEnable = true;
            bb.hRgnBlur = new IntPtr();
            DWM.DwmEnableBlurBehindWindow(Window.SystemHandle, ref bb);

            bool _forceAlwaysOnTop = false;

            // Get Bounds
            IntRect bounds = ImageViewerUtils.GetCurrentBounds(mousePos);

            // Resize Window
            if (Config.Setting_LimitImagesToMonitor != Config.NONE)
            {
                // Fit to monitor height/width
                int limit = Config.Setting_LimitImagesToMonitor;

                if (limit == Config.AUTO)
                {
                    if (bounds.Height < bounds.Width)
                        limit = Config.HEIGHT;
                    else
                        limit = Config.WIDTH;
                }

                if (limit == Config.HEIGHT && Image.Texture.Size.Y > bounds.Height)
                {
                    Zoom(1 + (((float)bounds.Height - Image.Texture.Size.Y) / Image.Texture.Size.Y), true);
                    FitToMonitorHeightForced = true;
                }
                else if (limit == Config.WIDTH && Image.Texture.Size.X > bounds.Width)
                {
                    Zoom(1 + (((float)bounds.Width - Image.Texture.Size.X) / Image.Texture.Size.X), true);
                    AutomaticallyZoomed = true;
                }
            }
            if (Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_MinImageSize)
            {
                // Reisze images smaller than min size to min size
                AutomaticallyZoomed = true;
                Zoom(Config.Setting_MinImageSize / Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y), true);
            }
                // Use Texture Size * Zoom instead of Window.Size since it wouldn't have updated yet
            Vector2i winSize = new Vector2i((int)(Image.Texture.Size.X * CurrentZoom), (int)(Image.Texture.Size.Y * CurrentZoom));

            // Position Window
            Vector2i winPos;

            if (Config.Setting_PositionLargeWideImagesInCorner && CurrentImageSize().X > CurrentImageSize().Y && CurrentImageSize().X * CurrentZoom >= bounds.Width)
            {
                // Position Window in top-left if the image is wide (ie: a Desktop Wallpaper / Screenshot)
                winPos = new Vector2i(bounds.Left, bounds.Top);
            }
            else if (Config.Setting_OpenAtMousePosition)
            {
                // At Mouse Position
                winPos = new Vector2i(mousePos.X - (int)(winSize.X / 2), mousePos.Y - (int)(winSize.Y / 2));

                if (!FitToMonitorHeightForced)
                {
                    if (winPos.Y < bounds.Top)
                        winPos.Y = 0;
                    else if (winPos.Y + winSize.Y > bounds.Height)
                        winPos.Y = bounds.Height - (int)winSize.Y;
                }
                else
                    winPos.Y = bounds.Top;

                if (winPos.X < bounds.Left)
                    winPos.X = bounds.Left;
                else if (winPos.X + winSize.X > bounds.Left + bounds.Width)
                    winPos.X = bounds.Left + bounds.Width - (int)winSize.X;
            }
            else
            {
                // At Monitor Center
                IntRect monitorBounds = ImageViewerUtils.GetCurrentBounds(mousePos);
                winPos = new Vector2i(monitorBounds.Left + (int)((monitorBounds.Width - winSize.X) / 2), monitorBounds.Top + (int)((monitorBounds.Height - winSize.Y) / 2));
            }

            Window.Position = winPos;

            // Force Always On Top Mode (so it's above the task bar)
            if (FitToMonitorHeightForced || (Image.Texture.Size.Y >= bounds.Height && Image.Texture.Size.X < bounds.Width))
                _forceAlwaysOnTop = true;

            // Defaults
                // Rotation (some images have a rotation set in their exif data)
            RotateImage(DefaultRotation, false);
                // Smoothing
            if (Image is AnimatedImage)
                Image.Data.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
            else
                Image.Texture.Smooth = Math.Min(Image.Texture.Size.X, Image.Texture.Size.Y) < Config.Setting_SmoothingMinImageSize ? false : Config.Setting_SmoothingDefault;
                // Backgrounds For Images With Transparency
            BackgroundsForImagesWithTransparency = Config.Setting_BackgroundForImagesWithTransparencyDefault;

            ForceAlwaysOnTopNextTick = _forceAlwaysOnTop;

            Redraw();
            NextWindowPos = Window.Position;

            // Interaction
            Window.Closed += OnWindowClosed;
            Window.MouseButtonPressed += OnMouseDown;
            Window.MouseButtonReleased += OnMouseUp;
            Window.MouseWheelScrolled += OnMouseWheelScrolled;
            Window.MouseMoved += OnMouseMoved;
            Window.KeyReleased += OnKeyUp;
            Window.KeyPressed += OnKeyDown;

            // Loop
            Stopwatch clock = new Stopwatch();
            clock.Start();

            while (Window.IsOpen)
            {
                // Add in some idle time to not thrash the CPU
                Thread.Sleep(1);

                if (CloseNextTick)
                {
                    Window.Close();
                    break;
                }

                // Process events
                Window.DispatchEvents();

                if (ReloadConfigNextTick)
                {
                    ReloadConfig();
                    ReloadConfigNextTick = false;
                }

                // Animated Image?
                if (Image is AnimatedImage)
                {
                    bool imageUpdated = Image.Update((float)clock.Elapsed.TotalMilliseconds);
                    if (!Updated && imageUpdated)
                        Update();
                }
                clock.Restart();

                // Drag Window
                if (Dragging)
                    Window.Position = new Vector2i(Mouse.GetPosition().X - DragPos.X, Mouse.GetPosition().Y - DragPos.Y);

                // Update
                if (Updated)
                {
                    Updated = false;
                    Redraw();
                    Window.Position = NextWindowPos;
                }

                if (ForceAlwaysOnTopNextTick)
                {
                    bounds = ImageViewerUtils.GetCurrentBounds(Window.Position);
                    if (Window.Size.Y >= bounds.Height && Window.Size.X < bounds.Width)
                        ForceAlwaysOnTop();
                    else
                        ForceAlwaysOnTopNextTick = false;
                }

                if (PreloadNextImageStart)
                    PreloadNextImage();
            }
        }