|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: S T
Length: 23864 (0x5d38)
Types: TextFile
Names: »ScrollBar.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/Toolkit/DECToolkit/src/ScrollBar.c«
/*
* $Source: /u1/X/DECToolkit/src/RCS/ScrollBar.c,v $
* $Header: ScrollBar.c,v 1.1 86/12/17 09:02:26 swick Exp $
*/
#ifndef lint
static char *rcsid_ScrollBar_c = "$Header: ScrollBar.c,v 1.1 86/12/17 09:02:26 swick Exp $";
#endif lint
#ifndef lint
static char *sccsid = "@(#)ScrollBar.c 1.11 12/11/86";
#endif lint
/*
* COPYRIGHT 1986
* DIGITAL EQUIPMENT CORPORATION
* MAYNARD, MASSACHUSETTS
* ALL RIGHTS RESERVED.
*
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
* SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
* DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
* ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
*
* IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
* APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
* SET FORTH ABOVE.
*
*
* 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 Digital Equipment Corporation not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*/
/*
*
* Author: K. Langone
*
*/
#include <stdio.h>
#include <X/Xlib.h>
#include "Toolkit.h"
/* Private Definitions */
#define scrollbarEvents (LeaveWindow | EnterWindow | ButtonPressed | \
ButtonReleased | LeftDownMotion | ExposeWindow)
#define scrollbuttonEvents (ExposeRegion | ExposeWindow | \
ButtonPressed | ButtonReleased)
#define IgnoreEvent -1
typedef struct _ScrollBarData {
Window tw; /* scroll bar tool window */
Window pw; /* parent window, needed for resizing */
Window leftorupw; /* window for the left or upper button */
Window rightordownw; /* window for the righ or lower button */
enum WhichWay orientation; /* left-right-up-down */
float thumbpos; /* thumb pos. on scroll bar(0.0-1.0) */
int thumbx, thumby; /* integer pixel position */
int thumbsize; /* height of thumb */
Pixmap brcolor; /* border color index */
Pixmap background; /* pixmap of background */
int brwidth; /* border width */
Pixmap thumbcolor; /* thumb color iondex */
int width; /* max width of scroll bar */
int otherdim; /* other window dimension */
int sthick; /* thickness of scroll bar */
int (*ThumbProc) (); /* procedure called when thumb is moved */
int (*PageProc) (); /* procedure called when either of the two
page buttons are clicked */
caddr_t tag; /* additional tool data */
} ScrollBarData;
static int scrollbarContext;
static int initDone = 0;
extern char *malloc ();
float *ptr;
/* =================================================================== */
/* Private Procedures */
static Initialize ()
{
scrollbarContext = UniqueEntryType ();
initDone = 1;
}
static Dummy()
{
printf("dummy callback for ScrollBar\n");
}
/* -----> Utilities */
/* This procedure will move the thumb using
* two XTileSet calls
* If the thumbx or thumby = IgnoreEvent the
* current thumb position is not updated ,
* this condition will occur on expose window events
*/
/* =================================================================== */
/* -----> Utilities */
/* This procedure will move the thumb using
* two XTileSet calls
* If the thumbx or thumby = IgnoreEvent the
* current thumb position is not updated ,
* this condition will occur on expose window events or
* changing the thumb size
*/
static void MoveTheThumb (data, event)
ScrollBarData * data;
XButtonPressedEvent * event;
{
int newpos, update, delta, deltax, deltay;
/* -----> check to see if thumb should be moved */
update = 1;
if (data -> orientation == Down | data -> orientation == Up) {
/* -----> move thumb pixmap horizontally */
if (data -> thumbx == IgnoreEvent) {
/* ignore input event */
update = 0;
data -> thumbx =
(int) (data -> thumbpos * (data -> width - data -> thumbsize));
/* don't need to clear */
XTileSet (data -> tw, data -> thumbx, data -> thumby,
data -> thumbsize, data -> sthick, data -> thumbcolor);
}
else
if (event -> x >= data -> width - data -> thumbsize)
/* got input at end of scroll bar */
newpos = data -> width - data -> thumbsize;
else
if (event -> x < 0)/* possible error */
newpos = 0;
else /* valid input for scroll bar */
newpos = event -> x;
/* ----->Calculate the clear and draw areas */
if (update) {
delta = abs (newpos - data -> thumbx);
deltax = data -> thumbsize - delta;
if (abs (newpos - data -> thumbx) >= data -> thumbsize) {
/* clear all of the thumb */
XTileSet (data -> tw, newpos, data -> thumby,
data -> thumbsize, data -> sthick,
data -> thumbcolor);
XTileSet (data -> tw, data -> thumbx, data -> thumby,
data -> thumbsize, data -> sthick,
data -> background);
}
else
if (newpos < data -> thumbx) {
XTileSet (data -> tw, newpos, data -> thumby,
delta, data -> sthick,
data -> thumbcolor);
XTileSet (data -> tw, data -> thumbx + deltax,
data -> thumby, delta, data -> sthick,
data -> background);
}
else { /* newpos > data->thumbx */
XTileSet (data -> tw, newpos + deltax, data -> thumby,
delta, data -> sthick, data -> thumbcolor);
XTileSet (data -> tw, data -> thumbx, data -> thumby,
delta, data -> sthick, data -> background);
}
/* update thumb position */
data -> thumbx = newpos;
}
} /* end up/down scroll bar */
else {
/* -----> move thumb pixmap vertically */
if (data -> thumby == IgnoreEvent) {
/* ignore input event */
update = 0;
data -> thumby =
(int) (data -> thumbpos * (data -> width - data -> thumbsize));
/* don't need to clear */
XTileSet (data -> tw, data -> thumbx, data -> thumby,
data -> sthick, data -> thumbsize, data -> thumbcolor);
}
else
if (event -> y >= data -> width - data -> thumbsize)
/* got input at end of scroll bar */
newpos = data -> width - data -> thumbsize;
else
if (event -> y < 0)/* possible error */
newpos = 0;
else /* valid input for scroll bar */
newpos = event -> y;
/* ----->Calculate the clear and draw areas */
if (update) {
delta = abs (newpos - data -> thumby);
deltay = data -> thumbsize - delta;
if (abs (newpos - data -> thumby) >= data -> thumbsize) {
/* clear all of the thumb */
XTileSet (data -> tw, data -> thumbx, newpos,
data -> sthick, data -> thumbsize,
data -> thumbcolor);
XTileSet (data -> tw, data -> thumbx, data -> thumby,
data -> sthick, data -> thumbsize,
data -> background);
}
else
if (newpos < data -> thumby) {
XTileSet (data -> tw, data -> thumbx, newpos,
data -> sthick, delta,
data -> thumbcolor);
XTileSet (data -> tw, data -> thumbx,
data -> thumby + deltay,
data -> sthick, delta, data -> background);
}
else { /* newpos > data->thumby */
XTileSet (data -> tw, data -> thumbx, newpos + deltay,
data -> sthick, delta, data -> thumbcolor);
XTileSet (data -> tw, data -> thumbx, data -> thumby,
data -> sthick, delta, data -> background);
}
/* update thumb position */
data -> thumby = newpos;
}
}
/* -----> Change the floating point relative thumb position */
if (update) {
data -> thumbpos =
(float) newpos / (float) (data -> width - 2 * data -> brwidth);
}
}
/* =================================================================== */
/* This procedure reports the thumb position
* in floating point to the ThumbProc
*/
static void ReportThumbPosition (data, event)
ScrollBarData * data;
XButtonPressedEvent * event;
{
float finalvalue;
caddr_t tooldata;
if (data -> orientation == Down | data -> orientation == Up) {
if (event -> x >= data -> width - (int) data -> thumbsize)
finalvalue = 1.0;
else
if (event -> x < 0)
finalvalue = 0.0;
else
finalvalue = (float) event -> x /
((float) (data -> width - data -> thumbsize));
}
else {
if (event -> y >= data -> width - (int) data -> thumbsize)
finalvalue = 1.0;
else
if (event -> y < 0)
finalvalue = 0.0;
else
finalvalue = (float) event -> y /
((float) (data -> width - data -> thumbsize));
}
/* -----> call the client procedure */
data -> ThumbProc (finalvalue, data -> tag);
}
/* =================================================================== */
/* This procedure will configure the scroll bar with
* the new dimensions and update the parent window
* dimensions in the scroll bar data structure
*/
static void ConfigureScrollBar (data, x, y, width, height)
ScrollBarData * data;
int x, y;
int width;
int height;
{
/* -----> Set the Scroll Bar data to the new values */
if (data -> orientation == Up | data -> orientation == Down) {
data -> width = width;
data -> otherdim = height;
}
else {
data -> width = height;
data -> otherdim = width;
}
if (data -> orientation == Up)
XConfigureWindow (data -> tw, 0, 0,
data -> width - 2 * data -> brwidth, data -> sthick);
else
if (data -> orientation == Down)
XConfigureWindow (data -> tw, 0,
height - data -> sthick - data -> brwidth,
data -> width - 2 * data -> brwidth, data -> sthick);
else
if (data -> orientation == Left)
XConfigureWindow (data -> tw, 0, 0,
data -> sthick, data -> width - 2 * data -> brwidth);
else
XConfigureWindow (data -> tw,
width - data -> sthick - data -> brwidth, 0,
data -> sthick, data -> width - 2 * data -> brwidth);
XFlush ();
}
/* =================================================================== */
/* The procedure checks to see if the window size was
* and will invoke ConfigureScrollBar if necessary
*/
static void CheckForResize (data, event)
ScrollBarData * data;
XEvent * event;
{
WindowInfo info;
/* -----> get parent window information */
XQueryWindow (data -> pw, &info);
XFlush ();
if (data -> orientation == Up | data -> orientation == Down) {
if (info.width != data -> width | info.height != data -> otherdim) {
/* resize the window */
ConfigureScrollBar (data, info.x, info.y,
info.width, info.height);
}
}
else {
if (info.height != data -> width | info.width != data -> otherdim) {
/* resize the window */
ConfigureScrollBar (data, info.x, info.y,
info.width, info.height);
}
}
}
/* =================================================================== */
/* This procedure will process the Scroll Bar events
* and given the event will invoke routines to
* move the thumb and check for resize
*/
static int TProcessScrollBarEvent (event)
XEvent * event;
{
int x, y, subW, error;
int returnCode;
short state;
ScrollBarData * data;
Status status;
error = FindEntry (event -> window, scrollbarContext, &data);
if (error != ERRNONE)
return (NOTHANDLED);
returnCode = PROCESSED;
switch (event -> type) {
case MouseMoved:
MoveTheThumb (data, event);
case ButtonPressed:
MoveTheThumb (data, event);
ReportThumbPosition (data, event);
break;
case ButtonReleased:
MoveTheThumb (data, event);
ReportThumbPosition (data, event);
break;
case ExposeWindow:
CheckForResize (data, event);
/* -----> Don't Update Relative Thumb position */
if (data -> orientation == Up | data -> orientation == Down)
data -> thumbx = IgnoreEvent;
else
data -> thumby = IgnoreEvent;
MoveTheThumb (data, event);
case EnterWindow:
break;
case LeaveWindow:
break;
default:
returnCode = NOTHANDLED;
}
return (returnCode);
}
/* =================================================================== */
/* ----->NOTE: This routine has not been debugged
*/
/* This procedure will handle input for the scroll bar buttons */
static int TProcessSButtonEvent (event)
XEvent * event;
{
int x, y, subW, error;
int returnCode;
short state;
ScrollBarData * data;
Status status;
/* Code to be supplied */
return (returnCode);
}
/* Public Procedures */
/* =================================================================== */
/*
* This procedure will reposition the thumb
* and can be called from the application
*/
Status TSetThumbPosition (tw, thumbpos)
Window tw; /* scroll bar tool window */
float thumbpos; /* thumb position on scroll bar(0.0-1.0)
*/
{
ScrollBarData * data;
int error;
Status status;
float movelength;
WindowInfo info;
error = FindEntry (tw, scrollbarContext, &data);
/* put in error check on thumbpos later (0.0-1.0) */
movelength = (float) (data -> width) - data -> thumbsize;
/* if (data->orientation == Up | data->orientation == Down) else */
/* -----> change the value in the data structure */
data -> thumbpos = thumbpos;
status = 1;
}
/* =================================================================== */
/*
*
* This procedure will resize the scroll bar thumb
*/
Status TSetThumbSize (tw, thumbsize)
Window tw; /* scroll bar tool window */
float thumbsize; /* thumb size as portion of scroll bar */
{
ScrollBarData * data;
XEvent * event; /* this is only used as a pointer */
int error;
Status status;
/* -----> Error check for appropriate thumbsize */
/* if (thumbsize > 1.0) or (thumbsize < 0.0) then report error */
/* -----> Get scroll bar data */
error = FindEntry (tw, scrollbarContext, &data);
/* -----> Calulate the thumb size in pixels */
data -> thumbsize = (int) (thumbsize * (float) data -> width);
}
/* =================================================================== */
/*
*
* This procedure will refresh the Scroll Bar
*/
Status TRefreshScrollBar (tw)
Window tw; /* scroll bar tool window */
{
ScrollBarData * data;
XEvent * event; /* this is only used as a pointer */
int error;
Status status;
/* -----> Get the data */
error = FindEntry (tw, scrollbarContext, &data);
/* -----> Set Ignore Event flag */
if (data -> orientation == Down | data -> orientation == Up)
data -> thumbx = IgnoreEvent;
else
data -> thumby = IgnoreEvent;
/* -----> Invoke procedure to display new thumb size */
MoveTheThumb (data, event);
}
/* =================================================================== */
/*
* This procedure will reconfigure the scroll bar
* and obtain the tool's data
* Note: if Up/Down Scroll bar - width = long dimension
* else for Left/Right Scroll bar - height = long dimension
*/
Status TConfigureScrollBar (tw, x, y, width, height)
Window tw; /* scroll bar tool window */
int x, y; /* new window position */
int width; /* new scroll bar width */
int height; /* new scroll bar height */
{
ScrollBarData * data;
int error;
float thumbsize;
Status status;
/* -----> Get the scroll bar data */
error = FindEntry (tw, scrollbarContext, data);
/* -----> Proportionally Change the Thumbsize */
if (data -> orientation == Down | data -> orientation == Up)
thumbsize = (float) width / (float) data -> width;
else
thumbsize = (float) height / (float) data -> width;
TSetThumbSize (tw, thumbsize);
ConfigureScrollBar (data, x, y, width, height);
}
/* =================================================================== */
/*
* This procedure will destroy a scroll bar
*
*/
Status TDestroyScrollBar (tw)
Window tw;
{
/* -----> Delete the data in the table */
DeleteEntry (tw, scrollbarContext);
/* Other code, tbd... */
}
/* =================================================================== */
/*
* This procedure will create a command button and will set predefined
* values colors,font,and state selection. If any errors are detected
* during the parsing of the input arguments, an exit will occur.
*
*/
Status TGetScrollBarAttr (tw, arglist)
Window tw; /* tool window */
Targ * arglist;
{
ScrollBarData * data;
int return_code; /* return code from window creation */
int i, error;
error = FindEntry (tw, scrollbarContext, &data);
/* -----> Parsing input parameters */
while (arglist -> name) {
switch (arglist -> name) {
case T_SCROLLBAR_ORIENT:
arglist -> data = (caddr_t) data -> orientation;
break;
case T_SCROLLBAR_STHICK:
arglist -> data = (caddr_t) data -> sthick;
break;
case T_SCROLLBAR_THUMBPOS:
arglist -> data = (caddr_t) & data -> thumbpos;
break;
case T_SCROLLBAR_THUMBSIZE:
arglist -> data = (caddr_t) data -> thumbsize;
break;
case T_SCROLLBAR_THUMBCOLOR:
arglist -> data = (caddr_t) data -> thumbcolor;
break;
case T_SCROLLBAR_BRCOLOR:
arglist -> data = (caddr_t) data -> brcolor;
break;
case T_SCROLLBAR_BACKGROUND:
arglist -> data = (caddr_t) data -> background;
break;
case T_SCROLLBAR_BRWIDTH:
arglist -> data = (caddr_t) data -> brwidth;
break;
case T_SCROLLBAR_TPROC:
arglist -> data = (caddr_t) data -> ThumbProc;
break;
case T_SCROLLBAR_PPROC:
arglist -> data = (caddr_t) data -> PageProc;
break;
case T_SCROLLBAR_TAG:
arglist -> data = (caddr_t) data -> tag;
default:
break;
}
arglist++;
}
}
/* =================================================================== */
/*
* This procedure will create a command button and will set predefined
* values colors,font,and state selection. If any errors are detected
* during the parsing of the input arguments, an exit will occur.
*
*/
Status TSetScrollBarAttr (tw, arglist)
Window tw; /* tool window */
Targ * arglist;
{
ScrollBarData * data;
int return_code; /* return code from window creation */
int twidth, theight;
int error;
error = FindEntry (tw, scrollbarContext, &data);
/* -----> Parsing input parameters */
while (arglist -> name) {
switch (arglist -> name) {
case T_SCROLLBAR_ORIENT:
data -> orientation = (enum WhichWay) arglist -> data;
break;
case T_SCROLLBAR_STHICK:
data -> sthick = (int) arglist -> data;
break;
case T_SCROLLBAR_THUMBPOS:
ptr = (float *) (arglist -> data);
data -> thumbpos = *ptr;
break;
case T_SCROLLBAR_THUMBSIZE:
data -> thumbsize = (int) arglist -> data;
break;
case T_SCROLLBAR_THUMBCOLOR:
data -> thumbcolor = (int) arglist -> data;
break;
case T_SCROLLBAR_BRCOLOR:
data -> brcolor = (Pixmap) arglist -> data;
break;
case T_SCROLLBAR_BACKGROUND:
data -> background = (Pixmap) arglist -> data;
break;
case T_SCROLLBAR_BRWIDTH:
data -> brwidth = (int) arglist -> data;
break;
case T_SCROLLBAR_TPROC:
data -> ThumbProc = (int (*) ()) arglist -> data;
break;
case T_SCROLLBAR_PPROC:
data -> PageProc = (int (*) ()) arglist -> data;
break;
case T_SCROLLBAR_TAG:
data -> tag = arglist -> data;
default:
break;
}
arglist++;
}
TRefreshScrollBar (tw);
}
/* =================================================================== */
/*
*
* This procedure will create a scroll bar
*
*/
Window TCreateScrollBar (pw, arglist)
Window pw;
Targ * arglist;
{
ScrollBarData * data;
WindowInfo info;
Window tw;
Status status;
int thumbx, thumby;
int brdelta;
/* -----> Perform initialization */
if (!initDone)
Initialize ();
/* -----> Allocate space for data structure */
data = (ScrollBarData *) Tmalloc (sizeof (ScrollBarData));
/* -----> Set Default Values */
data -> orientation = Right;
data -> sthick = 20;
data -> thumbpos = 0.0;
data -> thumbsize = 10;
data -> brcolor = BlackPixmap;
data -> background = WhitePixmap;
data -> brwidth = 2;
data -> thumbcolor = BlackPixmap;
data -> ThumbProc = Dummy;
data -> PageProc = NULL;
/* -----> Parsing input parameters */
while (arglist -> name) {
switch (arglist -> name) {
case T_SCROLLBAR_ORIENT:
data -> orientation = (enum WhichWay) arglist -> data;
break;
case T_SCROLLBAR_STHICK:
data -> sthick = (int) arglist -> data;
break;
case T_SCROLLBAR_THUMBPOS:
ptr = (float *) (arglist -> data);
data -> thumbpos = *ptr;
break;
case T_SCROLLBAR_THUMBSIZE:
data -> thumbsize = (int) arglist -> data;
break;
case T_SCROLLBAR_THUMBCOLOR:
data -> thumbcolor = (int) arglist -> data;
break;
case T_SCROLLBAR_BRCOLOR:
data -> brcolor = (Pixmap) arglist -> data;
break;
case T_SCROLLBAR_BACKGROUND:
data -> background = (Pixmap) arglist -> data;
break;
case T_SCROLLBAR_BRWIDTH:
data -> brwidth = (int) arglist -> data;
break;
case T_SCROLLBAR_TPROC:
data -> ThumbProc = (int (*) ()) arglist -> data;
break;
case T_SCROLLBAR_PPROC:
data -> PageProc = (int (*) ()) arglist -> data;
break;
case T_SCROLLBAR_TAG:
data -> tag = arglist -> data;
default:
break;
}
arglist++;
}
/* -----> Get parent window dimensions */
status = XQueryWindow (pw, &info);
/* -----> Given the dimensions, create the scroll bar window and thumb
window */
brdelta = 2 * data -> brwidth;
if (data -> orientation == Up) {
tw = XCreateWindow (pw, 0, 0,
info.width - brdelta, data -> sthick,
data -> brwidth,
data -> brcolor, data -> background);
data -> width = info.width;
data -> otherdim = info.height;
}
else
if (data -> orientation == Down) {
tw = XCreateWindow (pw, 0,
info.height - data -> sthick - data -> brwidth,
info.width - brdelta, data -> sthick,
data -> brwidth,
data -> brcolor, data -> background);
data -> width = info.width;
data -> otherdim = info.height;
}
else
if (data -> orientation == Left) {
tw = XCreateWindow (pw, 0, 0,
data -> sthick, info.height - brdelta,
data -> brwidth,
data -> brcolor, data -> background);
data -> width = info.height;
data -> otherdim = info.width;
}
else { /* orientation==Right */
tw = XCreateWindow (pw,
info.width - data -> sthick - data -> brwidth,
0,
data -> sthick, info.height - brdelta,
data -> brwidth,
data -> brcolor, data -> background);
data -> width = info.height;
data -> otherdim = info.width;
}
if (tw == 0)
printf ("Error in creating scrollbar\n");
/* -----> Get tool window dimensions */
status = XQueryWindow (tw, &info);
if (data -> orientation == Up | data -> orientation == Down) {
data -> thumbx = -1;
data -> thumby = 0;
data -> sthick = info.height;
}
else {
data -> thumby = -1;
data -> thumbx = 0;
data -> sthick = info.width;
}
data -> tw = tw;
data -> pw = pw;
SaveEntry (tw, scrollbarContext, data);
TSetXEventDispatch (tw, TProcessScrollBarEvent, scrollbarEvents, 0);
/* Put in page buttons later if (data->PageProc != 0) { /* -----> Save
the scroll button entries, select in input, and save the event handler
*/
/* SaveEntry(leftorupw, scrollbarContext, data);
TSetXEventDispatch(leftorupw, TProcessSButtonEvent,
scrollbuttonEvents, 0); SaveEntry(rightordownw, scrollbarContext,
data); TSetXEventDispatch(rightordownw, TProcessSButtonEvent,
scrollbuttonEvents, 0); } */
return (tw);
}