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); }
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); }
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(); } } }
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(); } }