siemens-rtl/try_slide.c
2023-07-11 14:40:13 +02:00

188 lines
6.1 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef lint
static char sccs_id[] = "@(#)try_slide.c 5.3 9/1/88";
#endif
/*
* Copyright 1988 by Siemens Research and Technology Laboratories, Princeton, NJ
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of Siemens Research and Technology
* Laboratories not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
*
*
* SIEMENS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
* SIEMENS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include "copyright.h"
/****************************************************************************
try_slide.c: by Michael Berman
RTL Windows System
last modified: April 24, 1987
most of this used to be in twin_slide.c
version: 0.1
****************************************************************************/
#include "basetype.h"
#include "twinD.h"
#include "twin.h"
#include "trial.h"
#define MAX_TRIES 5
#define MAX_EQ(x,y) (((x) >= (y))? x:y)
#define MIN_EQ(x,y) (((x) <= (y))? x:y)
#define EqualPoints(a,b) \
((Get_PtX(a) == Get_PtX(b)) && (Get_PtY(a) == Get_PtY(b)))
TWPoint Trial_Slide_Nearest_Horizontal(), Trial_Slide_Nearest_Vertical();
/****************************************************************************
TRIAL SLIDE NEAREST IN AREA
Problem: Given a rectangle (representing a window), an area, the center
of the rectangle, a prefered point, and the size of the rectangle,
slide the center of the rectangle as close to the prefered point as
is possible without leaving the area. The center of the rectangle
after the slide is returned.
Arguments:
try: The rectangle to slide.
area: Slide within this area.
cntr: Center of the rectangle.
pt: Point to slide towards. (PRECONDITION: pt is in area)
sz: The size of the try rectangle.
Description:
By successively sliding
horizontally (either left or right) then vertically (either up
or down) attempt to slide closer to pt. Sliding means a move
of the window that crosses space tiles only. This is
a heuristic and won't always get to the best possible
position. Slide until either 1) we reach the goal position,
or 2) we're stuck in one position.
****************************************************************************/
TWPoint Trial_Slide_Nearest_In_Area(try, area, cntr, pt, sz)
TWRectangle try, area;
TWPoint cntr, pt;
Size sz;
{
bool stuck = FALSE, found = FALSE;
TWPoint new_cntr;
TWRectangle new_try;
while (!found && !stuck)
{
new_cntr = Trial_Slide_Nearest_Horizontal(try, area, cntr, pt, sz);
MAKE_RECTANGLE(new_cntr, sz, new_try);
new_cntr = Trial_Slide_Nearest_Vertical(new_try, area, new_cntr, pt, sz);
stuck = EqualPoints(cntr, new_cntr);
found = EqualPoints(new_cntr, pt);
cntr = new_cntr;
MAKE_RECTANGLE(cntr, sz, try);
}
return cntr;
}
TWPoint Trial_Slide_Nearest_Horizontal(try, area, cntr, pt, sz)
TWRectangle try, area;
TWPoint cntr, pt;
Size sz;
{
Basetype extent;
TWPoint p1, p2;
if (Get_PtX(pt) < Get_PtX(cntr)) /* Left */
{
Get_PtX(p1) = Get_PtX(p2) = Get_LeftX(try);
Get_PtY(p1) = Get_TopY(try);
Get_PtY(p2) = Get_BottomY(try);
Trial_Edge_Sweep(p1,p2,Left,&extent);
if (extent != Get_PtX(p1))
{
/* check whether still in open area -- if not, pull back */
Get_LeftX(try) = MAX_EQ(extent, Get_LeftX(area));
Get_RightX(try) = Get_LeftX(try) + (Get_Width(sz) - 1);
/* check if past pt... */
COMPUTE_CENTER(try, cntr);
Get_PtX(cntr) = MAX_EQ(Get_PtX(cntr), Get_PtX(pt));
MAKE_RECTANGLE(cntr, sz, try);
}
}
else if (Get_PtX(pt) > Get_PtX(cntr)) /* Right */
{
Get_PtX(p1) = Get_PtX(p2) = Get_RightX(try);
Get_PtY(p1) = Get_TopY(try);
Get_PtY(p2) = Get_BottomY(try);
Trial_Edge_Sweep(p1,p2,Right,&extent);
if (extent != Get_PtX(p1))
{
/* check whether still in open area -- if not, pull back */
Get_RightX(try) = MIN_EQ(extent, Get_RightX(area));
Get_LeftX(try) = Get_RightX(try) - (Get_Width(sz) - 1);
/* check if past pt... */
COMPUTE_CENTER(try, cntr);
Get_PtX(cntr) = MIN_EQ(Get_PtX(cntr), Get_PtX(pt));
MAKE_RECTANGLE(cntr, sz, try);
}
}
return cntr;
}
TWPoint Trial_Slide_Nearest_Vertical(try, area, cntr, pt, sz)
TWRectangle try, area;
TWPoint cntr, pt;
Size sz;
{
Basetype extent;
TWPoint p1, p2;
if (Get_PtY(pt) < Get_PtY(cntr)) /* Top */
{
Get_PtY(p1) = Get_PtY(p2) = Get_TopY(try);
Get_PtX(p1) = Get_LeftX(try);
Get_PtX(p2) = Get_RightX(try);
Trial_Edge_Sweep(p1,p2,Top,&extent);
if (extent != Get_PtY(p1))
{
/* check whether still in open area -- if not, pull back */
Get_TopY(try) = MAX_EQ(extent, Get_TopY(area));
Get_BottomY(try) = Get_TopY(try) + (Get_Height(sz) - 1);
/* check if past pt... */
COMPUTE_CENTER(try, cntr);
Get_PtY(cntr) = MAX_EQ(Get_PtY(cntr), Get_PtY(pt));
MAKE_RECTANGLE(cntr, sz, try);
}
}
else if (Get_PtY(pt) > Get_PtY(cntr)) /* Bottom */
{
Get_PtY(p1) = Get_PtY(p2) = Get_BottomY(try);
Get_PtX(p1) = Get_LeftX(try);
Get_PtX(p2) = Get_RightX(try);
Trial_Edge_Sweep(p1,p2,Bottom,&extent);
if (extent != Get_PtY(p1))
{
/* check whether still in open area -- if not, pull back */
Get_BottomY(try) = MIN_EQ(extent, Get_BottomY(area));
Get_TopY(try) = Get_BottomY(try) - (Get_Height(sz) - 1);
/* check if past pt... */
COMPUTE_CENTER(try, cntr);
Get_PtY(cntr) = MIN_EQ(Get_PtY(cntr), Get_PtY(pt));
MAKE_RECTANGLE(cntr, sz, try);
}
}
return cntr;
}