380 lines
10 KiB
C
380 lines
10 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these librararies and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/*
|
|
* $XConsortium: abobj_layout.c /main/3 1995/11/06 17:16:15 rswiston $
|
|
*
|
|
* @(#)abobj_layout.c 1.17 15 Feb 1994 cde_app_builder/src/libABobj
|
|
*
|
|
* RESTRICTED CONFIDENTIAL INFORMATION:
|
|
*
|
|
* The information in this document is subject to special
|
|
* restrictions in a confidential disclosure agreement between
|
|
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
|
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
|
* Sun's specific written approval. This document and all copies
|
|
* and derivative works thereof must be returned or destroyed at
|
|
* Sun's request.
|
|
*
|
|
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
***********************************************************************
|
|
* ab_layout.c - Implements Layout semantics for objects
|
|
*
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
#include <stdio.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <X11/StringDefs.h>
|
|
#include <Xm/Xm.h>
|
|
#include <ab_private/objxm.h>
|
|
#include <ab_private/trav.h>
|
|
#include "abobjP.h"
|
|
|
|
#define LL_BUF_SIZE 20
|
|
|
|
/*************************************************************************
|
|
** **
|
|
** Private Function Declarations **
|
|
** **
|
|
**************************************************************************/
|
|
static void clear_layout(
|
|
ABObj obj
|
|
);
|
|
|
|
/*************************************************************************
|
|
** **
|
|
** Private Data **
|
|
** **
|
|
**************************************************************************/
|
|
static ABObj layout_list[LL_BUF_SIZE];
|
|
static int layout_count = 0;
|
|
|
|
|
|
/*************************************************************************
|
|
** **
|
|
** Function Definitions **
|
|
** **
|
|
**************************************************************************/
|
|
int
|
|
abobj_layout_changed(
|
|
ABObj obj
|
|
)
|
|
{
|
|
|
|
if (obj->attachments)
|
|
layout_list[layout_count++] = obj;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* Given a new x,y,width,height, calculate appropriate layout info
|
|
*/
|
|
int
|
|
abobj_calculate_new_layout(
|
|
ABObj obj,
|
|
int new_x,
|
|
int new_y,
|
|
Dimension new_width,
|
|
Dimension new_height
|
|
)
|
|
{
|
|
ABObj parent;
|
|
ABAttachListPtr attachments;
|
|
Position x, y;
|
|
Dimension width, height;
|
|
Dimension p_width, p_height;
|
|
long gridpos;
|
|
|
|
if ((attachments = obj->attachments) == NULL)
|
|
return -1;
|
|
|
|
if (obj->ui_handle == NULL)
|
|
{
|
|
if (util_get_verbosity() > 0)
|
|
fprintf(stderr,"abobj_calculate_new_layout: %s: NULL widget\n", obj_get_name(obj));
|
|
return -1;
|
|
}
|
|
|
|
XtVaGetValues((Widget)obj->ui_handle,
|
|
XmNx, &x,
|
|
XmNy, &y,
|
|
XmNwidth, &width,
|
|
XmNheight, &height,
|
|
NULL);
|
|
|
|
parent = obj_get_parent(obj);
|
|
XtVaGetValues((Widget)parent->ui_handle,
|
|
XmNwidth, &p_width,
|
|
XmNheight, &p_height,
|
|
NULL);
|
|
|
|
switch(attachments->west.type)
|
|
{
|
|
case AB_ATTACH_POINT:
|
|
attachments->west.offset = new_x;
|
|
break;
|
|
case AB_ATTACH_GRIDLINE:
|
|
gridpos = (100 * new_x)/(int)p_width;
|
|
attachments->west.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_CENTER_GRIDLINE:
|
|
gridpos = (100 * (new_x + (int)new_width/2))/(int)p_width;
|
|
attachments->west.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_OBJ:
|
|
case AB_ATTACH_ALIGN_OBJ_EDGE:
|
|
attachments->west.offset += (new_x - x);
|
|
if (new_x == 0 && attachments->west.offset < 0)
|
|
attachments->west.offset = 0;
|
|
break;
|
|
}
|
|
|
|
switch(attachments->east.type)
|
|
{
|
|
case AB_ATTACH_POINT:
|
|
attachments->east.offset = p_width - (new_x + new_width);
|
|
break;
|
|
case AB_ATTACH_GRIDLINE:
|
|
gridpos = (100 * (new_x + (int)new_width))/(int)p_width;
|
|
attachments->east.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_CENTER_GRIDLINE:
|
|
gridpos = (100 * (new_x + (int)new_width/2))/(int)p_width;
|
|
attachments->east.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_OBJ:
|
|
attachments->east.offset = p_width - (new_x + new_width + 1);
|
|
break;
|
|
case AB_ATTACH_ALIGN_OBJ_EDGE:
|
|
attachments->east.offset += (x + width - new_x - new_width);
|
|
break;
|
|
}
|
|
|
|
switch(attachments->north.type)
|
|
{
|
|
case AB_ATTACH_POINT:
|
|
attachments->north.offset = new_y;
|
|
break;
|
|
case AB_ATTACH_GRIDLINE:
|
|
gridpos = (100 * new_y)/(int)p_height;
|
|
attachments->north.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_CENTER_GRIDLINE:
|
|
gridpos = (100 * (new_y + (int)new_height/2))/(int)p_height;
|
|
attachments->north.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_OBJ:
|
|
case AB_ATTACH_ALIGN_OBJ_EDGE:
|
|
attachments->north.offset += (new_y - y);
|
|
if (new_y == 0 && attachments->north.offset < 0)
|
|
attachments->north.offset = 0;
|
|
break;
|
|
}
|
|
|
|
switch(attachments->south.type)
|
|
{
|
|
case AB_ATTACH_POINT:
|
|
attachments->south.offset = p_height - (new_y + new_height);
|
|
break;
|
|
case AB_ATTACH_GRIDLINE:
|
|
gridpos = (100 * (new_y + (int)new_height))/(int)p_height;
|
|
attachments->south.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_CENTER_GRIDLINE:
|
|
gridpos = (100 * (new_y + (int)new_height/2))/(int)p_height;
|
|
attachments->south.value = (void*)gridpos;
|
|
break;
|
|
case AB_ATTACH_OBJ:
|
|
attachments->south.offset = p_height - (new_y + new_height + 1);
|
|
break;
|
|
case AB_ATTACH_ALIGN_OBJ_EDGE:
|
|
attachments->south.offset += (y + height - new_y - new_height);
|
|
break;
|
|
}
|
|
|
|
objxm_obj_set_attachment_args(obj, OBJXM_CONFIG_BUILD);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
* Sort the objects children by either X or Y.
|
|
*/
|
|
void
|
|
abobj_sort_children(
|
|
ABObj obj,
|
|
int sort
|
|
)
|
|
{
|
|
ABObj child1, child2;
|
|
ABObj pobj = objxm_comp_get_subobj(obj, AB_CFG_PARENT_OBJ);
|
|
int num_children = obj_get_num_children(pobj);
|
|
int i, j;
|
|
int x1, y1, x2, y2;
|
|
|
|
for (i = 0; i < num_children; i++)
|
|
{
|
|
for (j = i; j < num_children; j++)
|
|
{
|
|
child1 = obj_get_child(pobj, i);
|
|
child2 = obj_get_child(pobj, j);
|
|
|
|
x1 = obj_get_x(child1);
|
|
y1 = obj_get_y(child1);
|
|
x2 = obj_get_x(child2);
|
|
y2 = obj_get_y(child2);
|
|
|
|
if (sort == XSORT)
|
|
{
|
|
if (x2 < x1 || (x2 == x1 && y2 < y1))
|
|
obj_swap_siblings(child1, child2);
|
|
} else
|
|
{
|
|
if (y2 < y1 || (y2 == y1 && x2 < x1))
|
|
obj_swap_siblings(child1, child2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Set North and West to objs y and x positions. Set
|
|
* South and East to none.
|
|
*/
|
|
void
|
|
clear_layout(
|
|
ABObj obj
|
|
)
|
|
{
|
|
obj_set_attachment(obj, AB_CP_NORTH,
|
|
AB_ATTACH_POINT,
|
|
NULL,
|
|
obj_get_y(obj));
|
|
obj_set_attachment(obj, AB_CP_WEST,
|
|
AB_ATTACH_POINT,
|
|
NULL,
|
|
obj_get_x(obj));
|
|
obj_set_attachment(obj, AB_CP_SOUTH,
|
|
AB_ATTACH_NONE,
|
|
NULL,
|
|
0);
|
|
obj_set_attachment(obj, AB_CP_EAST,
|
|
AB_ATTACH_NONE,
|
|
NULL,
|
|
0);
|
|
}
|
|
|
|
/*
|
|
* Either works on a object or its children.
|
|
* Clear the obj's attachments entirely if init_attachments
|
|
* is TRUE but also configure the widget hierarchy to have two
|
|
* basic connections: North and West point attachments with the
|
|
* objs x and y offsets.
|
|
*/
|
|
void
|
|
abobj_clear_layout(
|
|
ABObj obj,
|
|
BOOL clear_children,
|
|
BOOL init_attachments
|
|
)
|
|
{
|
|
ABObj pos_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ);
|
|
ABAttachment attach;
|
|
|
|
if (clear_children)
|
|
{
|
|
AB_TRAVERSAL trav;
|
|
ABObj child;
|
|
|
|
for (trav_open(&trav, pos_obj, AB_TRAV_SALIENT_CHILDREN |
|
|
AB_TRAV_MOD_SAFE);
|
|
(child = trav_next(&trav)) != NULL; )
|
|
{
|
|
/* Configure the tree to have just basic attachments */
|
|
attach.type = AB_ATTACH_POINT;
|
|
attach.value = (void *)NULL;
|
|
attach.offset = abobj_get_y(child);
|
|
abobj_set_attachment(child, AB_CP_NORTH, &attach);
|
|
|
|
attach.type = AB_ATTACH_POINT;
|
|
attach.value = (void *)NULL;
|
|
attach.offset = abobj_get_x(child);
|
|
abobj_set_attachment(child, AB_CP_WEST, &attach);
|
|
|
|
attach.type = AB_ATTACH_NONE;
|
|
attach.value = (void *)NULL;
|
|
attach.offset = 0;
|
|
abobj_set_attachment(child, AB_CP_SOUTH, &attach);
|
|
|
|
abobj_set_attachment(child, AB_CP_EAST, &attach);
|
|
|
|
abobj_instantiate_changes(child);
|
|
|
|
/*
|
|
* Clear out all attachments in obj structure
|
|
* if init_attachments is set
|
|
*/
|
|
if (init_attachments)
|
|
obj_init_attachments(child);
|
|
}
|
|
trav_close(&trav);
|
|
}
|
|
else
|
|
{
|
|
attach.type = AB_ATTACH_POINT;
|
|
attach.value = (void *)NULL;
|
|
attach.offset = abobj_get_y(pos_obj);
|
|
abobj_set_attachment(pos_obj, AB_CP_NORTH, &attach);
|
|
|
|
attach.type = AB_ATTACH_POINT;
|
|
attach.value = (void *)NULL;
|
|
attach.offset = abobj_get_x(pos_obj);
|
|
abobj_set_attachment(pos_obj, AB_CP_WEST, &attach);
|
|
|
|
attach.type = AB_ATTACH_NONE;
|
|
attach.value = (void *)NULL;
|
|
attach.offset = 0;
|
|
abobj_set_attachment(pos_obj, AB_CP_SOUTH, &attach);
|
|
|
|
abobj_set_attachment(pos_obj, AB_CP_EAST, &attach);
|
|
|
|
abobj_instantiate_changes(pos_obj);
|
|
|
|
/*
|
|
* Clear out all attachments in obj structure
|
|
* if init_attachments is set
|
|
*/
|
|
if (init_attachments)
|
|
obj_init_attachments(pos_obj);
|
|
|
|
}
|
|
}
|