home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
SOURCE
/
CSSRC
/
SDGFLD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-29
|
8KB
|
272 lines
/*
sdgfld.c
% sed_MoveGField: grid movement function
Provides grid movement between fields.
Combines up, down, right, and left.
If the sed is active, calls the fenter and fexit functions.
C-scape 3.2
Copyright (c) 1986, 1987, by Oakland Group, Inc.
ALL RIGHTS RESERVED.
Revision History:
-----------------
11/18/86 jmd created
3/11/87 jmd always calls scroll_adjust now.
4/01/87 jmd added active mode check
11/18/87 jmd changed names of some low-level funcs
8/24/88 jmd added bob object support
8/25/88 jmd changed to true geographical operation
9/12/88 jmd Added in and out data to objects
12/13/88 jmd Added many divers changes to affect the field motion
2/07/89 jmd initialized depend to avoid warning
4/13/89 jmd added sed_GetCurrField macro
5/25/89 jmd added tests for protected field to bob handling
5/27/89 jmd removed unnecessary call to goto_field
8/11/89 jmd de-bobbed
3/17/90 jmd added Cache/Flush
3/28/90 jmd ansi-fied
*/
#include "sed.h"
#include "fldpriv.h" /* for field_ operations */
#define gfield_func(fname) int fname(menu_type, int)
typedef gfield_func ((*gfield_fptr));
int sed_MoveGField(sed_type sed, int direction)
/*
Attempts to find the "best" up, down, left, right motion
between fields.
In some detail it does the following.
First it uses the grid to find the "nearest" field in the desired
direction (in the case of up and down, nearest means a field
with the same grid column number). If the current field is a bob,
a field representing its current location is temporarily placed into
the field grid in order to use the grid operations.
After a field has been found, a search is made for the closest bob
object in the given direction. In this case straight line distance is
used. If a bob is found that is closer then the field found in the grid
it becomes the new field. The correct location to jump within it
is determined. whew.
*/
{
register int newfield;
bob_type bob;
menu_type menu;
ocbox oldbox, newbox;
boolean isabob;
field_type field;
int frow, fcol, fwid;
int bobno, child, dist, mindist;
int guess = -1;
ocpos_struct ocpos;
ocsize_struct ocsize;
winsfp_struct winsfp;
gfield_fptr get_field; /* pointer to get field function */
cs_Assert(sed_Ok(sed), CS_SD_MGF_SED, 0);
ocpos.row = 0;
ocpos.col = 0;
ocsize.height = 0;
ocsize.width = 0;
menu = sed_GetMenu(sed);
switch (direction) {
case OAK_UP:
get_field = menu_FindUpField;
break;
case OAK_DOWN:
get_field = menu_FindDownField;
break;
case OAK_RIGHT:
get_field = menu_FindRightField;
break;
case OAK_LEFT:
get_field = menu_FindLeftField;
break;
default:
cs_Assert(FALSE, CS_SD_MGF_DIR, 0);
break;
}
/* if the current field has a dependent bob,
temporarily set the field location to the position within the bob
*/
isabob = FALSE;
if ((bob = menu_GetFieldBob(menu, sed_GetFieldNo(sed))) != NULL) {
isabob = bob_IsDepend(bob);
}
if (!isabob) {
/* get field's location */
menu_GetFieldBox(menu, sed_GetFieldNo(sed), &oldbox);
}
else {
/* remember old field location */
field = sed_GetCurrField(sed);
frow = field_GetRow(field);
fcol = field_GetCol(field);
fwid = field_GetWidth(field);
/* find the position WITHIN the bob */
/* Note: this code will not be called for non-window bobs
because of Depend Check
*/
bob_Do(bob, WINM_GETFLDPOS, NULL, (VOID *) &oldbox);
ocpos.row = bord_GetTopRow(bob);
ocpos.col = bord_GetLeftCol(bob);
/* translate bob coords into menu coords */
oldbox.toprow += ocpos.row - win_GetTopRow(sed) + sed_GetYoffset(sed);
oldbox.botrow += ocpos.row - win_GetTopRow(sed) + sed_GetYoffset(sed);
oldbox.leftcol += ocpos.col - win_GetLeftCol(sed) + sed_GetXoffset(sed);
oldbox.rightcol += ocpos.col - win_GetLeftCol(sed) + sed_GetXoffset(sed);
/* move the field to a new, temporary spot */
menu_TakeFieldFromGrid(menu, sed_GetFieldNo(sed));
menu_AddFieldToGrid(menu, sed_GetFieldNo(sed), oldbox.toprow, oldbox.leftcol);
field_SetWidth(field, oldbox.rightcol - oldbox.leftcol + 1);
}
/* find nearest, unprotected, unvirtual field */
/* remember first unprotected, virtual field, we may need it later */
newfield = sed_GetFieldNo(sed);
do {
if ((newfield = (*get_field)(menu, newfield)) < 0) {
break;
}
if (guess == -1 && menu_GetFieldWidth(menu, newfield) <= 0 &&
!menu_IsProtected(menu, newfield)) {
guess = newfield;
}
} while (menu_IsProtected(menu, newfield) ||
menu_GetFieldWidth(menu, newfield) <= 0);
if (isabob) {
/* restore the current field's location */
menu_TakeFieldFromGrid(menu, sed_GetFieldNo(sed));
menu_AddFieldToGrid(menu, sed_GetFieldNo(sed), frow, fcol);
field_SetWidth(field, fwid);
}
/* find closest unprotected dependent bob, skip current field */
child = -1;
mindist = -1;
for (bobno = 0; bobno < menu_GetBobCount(menu); bobno++) {
if ((bob = menu_GetBob(menu, bobno)) != NULL &&
menu_GetBobFieldNo(menu, bobno) != sed_GetFieldNo(sed) &&
!menu_IsProtected(menu, menu_GetBobFieldNo(menu, bobno))) {
if (bob_IsDepend(bob)) {
ocpos.row = bord_GetTopRow(bob);
ocpos.col = bord_GetLeftCol(bob);
ocsize.height = bord_GetHeight(bob);
ocsize.width = bord_GetWidth(bob);
/* get bob box, translate to menu coords */
newbox.toprow = ocpos.row - win_GetTopRow(sed) + sed_GetYoffset(sed);
newbox.botrow = newbox.toprow + ocsize.height - 1;
newbox.leftcol = ocpos.col - win_GetLeftCol(sed) + sed_GetXoffset(sed);
newbox.rightcol = newbox.leftcol + ocsize.width - 1;
/* compare distances */
if ((dist = ocbox_FindDist(&oldbox, &newbox, direction)) >= 0) {
if (mindist < 0 || dist < mindist) {
child = bobno;
mindist = dist;
}
}
}
}
}
if (newfield < 0) {
if (child < 0) {
if (guess < 0) {
return(SED_STUCK);
}
else {
/* nothing else looks good, let's use that guess we made */
newfield = guess;
}
}
else {
newfield = menu_GetBobFieldNo(menu, child);
}
}
else if (child >= 0) {
/* compare distance of new field with child */
menu_GetFieldBox(menu, newfield, &newbox);
dist = ocbox_FindDist(&oldbox, &newbox, direction);
if (dist < 0 || mindist < dist ) {
newfield = menu_GetBobFieldNo(menu, child);
}
else {
/* reset child */
child = -1;
}
}
/* If we're jumping to a bob, tell it the best place to be jump to */
if (child >= 0) {
/* find the child's box (relative to the child) */
bob = menu_GetBob(menu, child);
if (bob_IsDepend(bob)) {
ocpos.row = bord_GetTopRow(bob);
ocpos.col = bord_GetLeftCol(bob);
ocsize.height = bord_GetHeight(bob);
ocsize.width = bord_GetWidth(bob);
}
/* get setcurpos box in child bob coords */
if (direction == OAK_RIGHT || direction == OAK_LEFT) {
newbox.toprow = oldbox.toprow + win_GetTopRow(sed) - sed_GetYoffset(sed) - ocpos.row;
newbox.botrow = oldbox.botrow + win_GetTopRow(sed) - sed_GetYoffset(sed)- ocpos.row;
newbox.leftcol = 0;
newbox.rightcol = ocsize.width - 1;
}
else {
newbox.toprow = 0;
newbox.botrow = ocsize.height - 1;
newbox.leftcol = oldbox.leftcol + win_GetLeftCol(sed) - sed_GetXoffset(sed) - ocpos.col;
newbox.rightcol = oldbox.rightcol + win_GetLeftCol(sed) - sed_GetXoffset(sed)- ocpos.col;
}
/* set child's current pos */
winsfp.ocboxp = &newbox;
winsfp.pref = direction;
bob_Do(bob, WINM_SETFLDPOS, &winsfp, NULL);
}
if (!sd_exitfield(sed)) {
return(SED_INVALID);
}
disp_Cache();
sd_scroll_adjust(sed, newfield);
sd_goto_field(sed, newfield);
if (sed_IsActive(sed)) {
sed_DoFieldFenter(sed, sed_GetFieldNo(sed));
}
disp_Flush();
return(SED_MOVED);
}