|
Packit |
b099d7 |
/* $XConsortium: ScroVis.c /main/6 1995/09/19 23:07:44 cde-sun $ */
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Motif
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are free software; you can
|
|
Packit |
b099d7 |
* redistribute them and/or modify them under the terms of the GNU
|
|
Packit |
b099d7 |
* Lesser General Public License as published by the Free Software
|
|
Packit |
b099d7 |
* Foundation; either version 2 of the License, or (at your option)
|
|
Packit |
b099d7 |
* any later version.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are distributed in the hope that
|
|
Packit |
b099d7 |
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
Packit |
b099d7 |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
Packit |
b099d7 |
* PURPOSE. See the GNU Lesser General Public License for more
|
|
Packit |
b099d7 |
* details.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b099d7 |
* License along with these librararies and programs; if not, write
|
|
Packit |
b099d7 |
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
Packit |
b099d7 |
* Floor, Boston, MA 02110-1301 USA
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* HISTORY
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include <Xm/ScrolledWP.h>
|
|
Packit |
b099d7 |
#include <Xm/NavigatorT.h>
|
|
Packit |
b099d7 |
#include "ScrollFramTI.h"
|
|
Packit |
b099d7 |
#include "MessagesI.h"
|
|
Packit |
b099d7 |
#include "XmI.h"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define SWMessage1 _XmMMsgScrollVis_0000
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/************************************************************************
|
|
Packit |
b099d7 |
* *
|
|
Packit |
b099d7 |
* XmScrollVisible - TraverseObscureCallback helper *
|
|
Packit |
b099d7 |
* *
|
|
Packit |
b099d7 |
************************************************************************/
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
XmScrollVisible(
|
|
Packit |
b099d7 |
Widget scrw,
|
|
Packit |
b099d7 |
Widget wid,
|
|
Packit |
b099d7 |
Dimension hor_margin,
|
|
Packit |
b099d7 |
Dimension ver_margin)
|
|
Packit |
b099d7 |
/*********************
|
|
Packit |
b099d7 |
* A function that makes visible a unvisible or partially visible descendant
|
|
Packit |
b099d7 |
* of an AUTOMATIC scrolledwindow workwindow.
|
|
Packit |
b099d7 |
*********************
|
|
Packit |
b099d7 |
* - scrw is the ScrolledWindow whose workwindow act as the origin of the move.
|
|
Packit |
b099d7 |
* - wid is the widget to be made visible.
|
|
Packit |
b099d7 |
* - hor_margin, ver_margin are the margins between the widget in its new
|
|
Packit |
b099d7 |
* position and the scrolledwindow clipwindow.
|
|
Packit |
b099d7 |
**********************/
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmScrolledWindowWidget sw = (XmScrolledWindowWidget) scrw ;
|
|
Packit |
b099d7 |
register
|
|
Packit |
b099d7 |
Position newx, newy, /* new workwindow position */
|
|
Packit |
b099d7 |
wx, wy ; /* current workwindow position */
|
|
Packit |
b099d7 |
register
|
|
Packit |
b099d7 |
unsigned short tw, th, /* widget sizes */
|
|
Packit |
b099d7 |
cw, ch ; /* clipwindow sizes */
|
|
Packit |
b099d7 |
Position dx, dy ; /* position inside the workwindow */
|
|
Packit |
b099d7 |
Position src_x, src_y, dst_x, dst_y ;
|
|
Packit |
b099d7 |
Widget w ;
|
|
Packit |
b099d7 |
XmScrolledWindowConstraint swc;
|
|
Packit |
b099d7 |
XmNavigatorDataRec nav_data ;
|
|
Packit |
b099d7 |
_XmWidgetToAppContext(scrw);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
/* check param */
|
|
Packit |
b099d7 |
if (!((scrw) && (XmIsScrolledWindow(scrw)) &&
|
|
Packit |
b099d7 |
(sw->swindow.ScrollPolicy == XmAUTOMATIC))) {
|
|
Packit |
b099d7 |
XmeWarning(scrw, SWMessage1);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* loop up in search for a "workwindow" */
|
|
Packit |
b099d7 |
w = wid;
|
|
Packit |
b099d7 |
while (w && (XtParent(w) != (Widget) sw->swindow.ClipWindow))
|
|
Packit |
b099d7 |
w = XtParent(w);
|
|
Packit |
b099d7 |
if (!w) {
|
|
Packit |
b099d7 |
XmeWarning(scrw, SWMessage1);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
return ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* w is the potentially scrollable ascendant of wid that needs to
|
|
Packit |
b099d7 |
be scrolled, its parent is the clip window */
|
|
Packit |
b099d7 |
/* In the new scheme, w might not be able to scroll at all,
|
|
Packit |
b099d7 |
or even in the direction the margins point to. There is
|
|
Packit |
b099d7 |
nothing much we can do about that except document that
|
|
Packit |
b099d7 |
traversing to an unvisible kid of unscrollable workwindow will
|
|
Packit |
b099d7 |
not scroll it, resulting in unvisible focus widget. We could
|
|
Packit |
b099d7 |
check for NO_SCROLL in w, but since we cannot check for SCROLL_HOR
|
|
Packit |
b099d7 |
or SCROLL_VERT - depend on the traversal layout - I'd rather do
|
|
Packit |
b099d7 |
nothing */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* we need to get the position of wid relative to w,
|
|
Packit |
b099d7 |
so we use 2 XtTranslateCoords */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtTranslateCoords(wid, 0, 0, &src_x, &src_y);
|
|
Packit |
b099d7 |
XtTranslateCoords(w, 0, 0, &dst_x, &dst_y);
|
|
Packit |
b099d7 |
dx = src_x - dst_x ;
|
|
Packit |
b099d7 |
dy = src_y - dst_y ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
swc = GetSWConstraint(w);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* get the other positions and sizes */
|
|
Packit |
b099d7 |
cw = XtWidth((Widget) sw->swindow.ClipWindow) ;
|
|
Packit |
b099d7 |
ch = XtHeight((Widget) sw->swindow.ClipWindow) ;
|
|
Packit |
b099d7 |
wx = swc->orig_x - XtX(w) ;
|
|
Packit |
b099d7 |
wy = swc->orig_y - XtY(w) ; /* both always positive */
|
|
Packit |
b099d7 |
tw = XtWidth(wid) ;
|
|
Packit |
b099d7 |
th = XtHeight(wid) ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* find out the zone where the widget lies and set newx,newy (neg) for
|
|
Packit |
b099d7 |
the workw */
|
|
Packit |
b099d7 |
/* if the widget is bigger than the clipwindow, we put it on
|
|
Packit |
b099d7 |
the left, top or top/left, depending on the zone it was */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (dy < wy) { /* North */
|
|
Packit |
b099d7 |
newy = dy - (Position)ver_margin ; /* stuck it on top + margin */
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
if ((dy + th) <= (ch - XtY(w))) {
|
|
Packit |
b099d7 |
newy = wy ; /* in the middle : don't move y */
|
|
Packit |
b099d7 |
} else { /* South */
|
|
Packit |
b099d7 |
if (th > ch)
|
|
Packit |
b099d7 |
newy = dy - (Position)ver_margin ; /* stuck it on top if too big */
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
newy = swc->orig_y + dy - ch + th + (Position)ver_margin;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (dx < wx) { /* West */
|
|
Packit |
b099d7 |
newx = dx - (Position)hor_margin ; /* stuck it on left + margin */
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
if ((dx + tw) <= (cw - XtX(w))) {
|
|
Packit |
b099d7 |
newx = wx ; /* in the middle : don't move x */
|
|
Packit |
b099d7 |
} else { /* East */
|
|
Packit |
b099d7 |
if (tw > cw)
|
|
Packit |
b099d7 |
newx = dx - (Position)hor_margin ; /* stuck it on left if too big */
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
newx = swc->orig_x + dx - cw + tw + (Position)hor_margin;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* a last check */
|
|
Packit |
b099d7 |
if (newx > sw->swindow.hmax - sw->swindow.hExtent)
|
|
Packit |
b099d7 |
newx = sw->swindow.hmax - sw->swindow.hExtent;
|
|
Packit |
b099d7 |
if (newy > sw->swindow.vmax - sw->swindow.vExtent)
|
|
Packit |
b099d7 |
newy = sw->swindow.vmax - sw->swindow.vExtent;
|
|
Packit |
b099d7 |
if (newx < sw->swindow.hmin) newx = sw->swindow.hmin ;
|
|
Packit |
b099d7 |
if (newy < sw->swindow.vmin) newy = sw->swindow.vmin ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
nav_data.valueMask = NavValue ;
|
|
Packit |
b099d7 |
nav_data.value.x = newx ;
|
|
Packit |
b099d7 |
nav_data.value.y = newy ;
|
|
Packit |
b099d7 |
nav_data.dimMask = NavigDimensionX|NavigDimensionY ;
|
|
Packit |
b099d7 |
_XmSFUpdateNavigatorsValue((Widget)sw, &nav_data, True);
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|