Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Move Windows Through Pre-Configured Smaller Offset Locations

Description
Moves the window through pre-configured locations as set in the script.
Language
C#.net
Minimum Version
Created By
William Rawls
Contributors
-
Date Created
May 22, 2020
Date Last Modified
May 22, 2020

Scripted Function (Macro) Code

using System;
using System.Drawing;

public static class DisplayFusionFunction 
{
	public static void Run(IntPtr windowHandle) 
	{
		if (windowHandle == null)   return;

		Rectangle window = BFS.Window.GetBounds(windowHandle);
		if (window == null) return;

		Rectangle screenWorkArea = BFS.Monitor.GetMonitorWorkAreaByWindow(windowHandle);
		if (screenWorkArea == null)	return;

		bool isRestored = BFS.Window.IsRestored(windowHandle);
		if (!isRestored) BFS.Window.Restore(windowHandle);

        // You can add, change or remove some lines from the locations array below.
        // Each line is a set of cooridinates for the selected window to move to
        // Each coordinate can be set from 0% to 100%
        //    Left %, Top %, Width %, Height %
        //
        // Example: If one of the entries in the locations array is
        //   CalculateNewLocation(screenWorkArea, 10, 25, 30, 44)
        //
        // The current window would move to
        //    10% (of the monitor's width) from the left edge
        //    25% (of the monitor's height) from the top edge
        //
        // It would resize the window to 
        //    30% wide (of the monitor's width)
        //    44% tall (of the monitor's height)
        //
        //  Sometimes two positions may interfere with each other.
        //  You can tell because when a window moves through the locations
        //    one or both of the locations will get skipped.
        //  It may even cause the rest of the locations to be skipped.
        //  When this happens, you'll need to adjust the location's 
        //    first two numbers (the window's new top left corner) 
        //    until all locations work well together.
        //  Luckily this doesn't happen often
        //

		// Small (less than large)
        Rectangle[] locations = new Rectangle[]
        {
            CalculateNewLocation(screenWorkArea,  0, 15, 45, 60),
            CalculateNewLocation(screenWorkArea,  2, 15, 25, 80),
            CalculateNewLocation(screenWorkArea,  3, 10, 20, 30),
            CalculateNewLocation(screenWorkArea, 30,  0, 50, 40),
            CalculateNewLocation(screenWorkArea, 47, 37, 50, 60),
            CalculateNewLocation(screenWorkArea, 68, 58, 31, 41),
            CalculateNewLocation(screenWorkArea, 80, 70, 21, 31),
            CalculateNewLocation(screenWorkArea, 80, 15, 20, 85),
        }; 

		// Start with the first location and look for the first matching X and Y
		Rectangle newLocation = locations[0];
		for(int i = 0; i < locations.Length; i++)
		{
			Rectangle location = locations[i];
			if (IsCloseEnough(window, location))
			{
				if (i < locations.Length - 1)
				{
					// Set the new location to the next location.
					// If it's the last location, use the already set first location.
					newLocation = locations[i+1];
				}
				
				break;
			}
		}
		
		// Move and resize the window to it's new location
		BFS.Window.SetSizeAndLocation(windowHandle, newLocation.X, newLocation.Y, newLocation.Width, newLocation.Height);
	}
	
    //
	// Checks to see if the upper left coordinates of each rectangle 
	//   are close enough to each other within a number of pixels (a tolerance)
	// Initially, tolerance is 25 pixels. You may want to play with it
	//   to get a better personal flow
	//
	// This is used with a window's starting location 
	//   to figure out what the next location 
	//   the window should be moved to
	//
	public static bool IsCloseEnough(Rectangle a, Rectangle b)
	{
		const int TOLERANCE = 25; //50;
		int deltaX = a.X - b.X;
		if (deltaX < 0)
			deltaX = -deltaX;

		int deltaY = a.Y - b.Y;
		if (deltaY < 0)
			deltaY = -deltaY;

		return (deltaX <= TOLERANCE) && (deltaY <= TOLERANCE);
	}

    //
	// Scales the boundaries of a window to fit within certain percentages of the boundaries
	//
	public static Rectangle CalculateNewLocation(Rectangle bounds, double percentX, double percentY, double percentWidth, double percentHeight)
	{
		// Adjust the top randomly by up to +/- 10 pixels 
		//   and the left coordinate randomly by up to +/- 10 pixels
		// This done to let each window move (probably) not exactly overlap another
		// So if you move one window to x,y (+/-10 pixels) and then a different
		//   window to the same location, both will not exactly overlap
		//
		Random rnd = new Random();
		percentX += (int) (rnd.Next(-10, +10) / 10.0);
		percentY += (int) (rnd.Next(-10, +10) / 10.0);

        var x = bounds.X + (int) (bounds.Width * (percentX / 100.0));
        var y = bounds.Y + (int) (bounds.Height * (percentY / 100.0));
        var w = (int) (bounds.Width * (percentWidth / 100.0));
        var h = (int) (bounds.Height * (percentHeight / 100.0));
		
		if(x < 0) x = 0;
		if(y < 0) y = 0;
		if(w > bounds.Width) w = bounds.Width;
		if(h > bounds.Height) h = bounds.Height;
		
		return new Rectangle(x, y, w, h);
	}	
}