1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-01-08 23:04:15 +01:00
Files
wmaker/WINGs/wruler.c
dan 4cb5649545 Gaaah!
This thing is completely broken! There are functions that take a
completely different set of arguments than the ones currently used to call
them. There are even functions that are not defined anywhere but
called from wtext.c

Please fix it before re-enabling it in Makefile.am
2000-07-06 01:28:13 +00:00

535 lines
13 KiB
C

/* WMRuler: nifty ruler widget for WINGs (OK, for WMText ;-) */
/* Copyleft (>) 1999, 2000 Nwanua Elumeze <nwanua@colorado.edu> */
#include "WINGsP.h"
#define MIN_DOC_WIDTH 10
typedef struct W_Ruler {
W_Class widgetClass;
W_View *view;
W_View *pview; /* the parent's view (for drawing the line) */
WMAction *moveAction; /* what to when while moving */
WMAction *releaseAction; /* what to do when released */
void *clientData;
GC fg, bg;
WMFont *font;
WMRulerMargins margins;
int offset;
int motion; /* the position of the _moving_ marker(s) */
int end; /* the last tick on the baseline (restrict markers to it) */
Pixmap drawBuffer;
struct {
unsigned int buttonPressed:1;
/* 0, 1, 2, 3, 4, 5, 6 */
unsigned int whichMarker:3; /* none, left, right, first, body, tabstop, both */
unsigned int RESERVED:28;
} flags;
} Ruler;
/* Marker for left margin
|\
| \
|__\
|
|
*/
static void
drawLeftMarker(Ruler *rPtr)
{
XPoint points[4];
int xpos = (rPtr->flags.whichMarker==1?
rPtr->motion:rPtr->margins.left);
XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, xpos, 8, xpos, 22);
points[0].x = xpos;
points[0].y = 1;
points[1].x = points[0].x+6;
points[1].y = 8;
points[2].x = points[0].x+6;
points[2].y = 9;
points[3].x = points[0].x;
points[3].y = 9;
XFillPolygon (rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, points, 4, Convex, CoordModeOrigin);
}
/* Marker for right margin
/|
/ |
/__|
|
|
*/
static void
drawRightMarker(Ruler *rPtr)
{
XPoint points[4];
int xpos = (rPtr->flags.whichMarker==2?
rPtr->motion:rPtr->margins.right);
XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, xpos, 8, xpos, 22);
points[0].x = xpos+1;
points[0].y = 0;
points[1].x = points[0].x-6;
points[1].y = 7;
points[2].x = points[0].x-6;
points[2].y = 9;
points[3].x = points[0].x;
points[3].y = 9;
XFillPolygon (rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, points, 4, Convex, CoordModeOrigin);
}
/* Marker for first line only
_____
|___|
|
*/
static void
drawFirstMarker(Ruler *rPtr)
{
int xpos = ((rPtr->flags.whichMarker==3 || rPtr->flags.whichMarker==6)?
rPtr->motion:rPtr->margins.first);
XFillRectangle(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, xpos-5, 10, 11, 5);
XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, xpos, 12, xpos, 22);
}
/* Marker for rest of body
_____
\ /
\./
*/
static void
drawBodyMarker(Ruler *rPtr)
{
XPoint points[4];
int xpos = ((rPtr->flags.whichMarker==4 || rPtr->flags.whichMarker==6)?
rPtr->motion:rPtr->margins.body);
points[0].x = xpos-5;
points[0].y = 16;
points[1].x = points[0].x+11;
points[1].y = 16;
points[2].x = points[0].x+5;
points[2].y = 22;
XFillPolygon (rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, points, 3, Convex, CoordModeOrigin);
}
static void
createDrawBuffer(Ruler *rPtr)
{
if(rPtr->drawBuffer)
XFreePixmap(rPtr->view->screen->display, rPtr->drawBuffer);
rPtr->drawBuffer = XCreatePixmap(rPtr->view->screen->display,
rPtr->view->window, rPtr->view->size.width, 40,
rPtr->view->screen->depth);
XFillRectangle(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->bg, 0, 0, rPtr->view->size.width, 40);
}
static void
drawRulerOnPixmap(Ruler *rPtr)
{
int i, j, w, m;
char c[3];
int marks[9] = {11, 3, 5, 3, 7, 3, 5, 3};
if(!rPtr->drawBuffer)
createDrawBuffer(rPtr);
XFillRectangle(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->bg, 0, 0, rPtr->view->size.width, 40);
WMDrawString(rPtr->view->screen, rPtr->drawBuffer, rPtr->fg,
rPtr->font, rPtr->margins.left+2, 26, "0 inches", 10);
/* marker ticks */
i=j=m=0;
w = rPtr->view->size.width - rPtr->margins.left;
while(m < w) {
XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->fg, rPtr->margins.left+m, 23,
rPtr->margins.left+m, marks[i%8]+23);
if(i!=0 && i%8==0) {
if(j<10)
snprintf(c,3,"%d",++j);
else
snprintf(c,3,"%2d",++j);
WMDrawString(rPtr->view->screen, rPtr->drawBuffer, rPtr->fg,
rPtr->font, rPtr->margins.left+2+m, 26, c, 2);
}
m = (++i)*10;
}
rPtr->end = rPtr->margins.left+m-10;
if(rPtr->margins.right > rPtr->end)
rPtr->margins.right = rPtr->end;
/* base line */
XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fg,
rPtr->margins.left, 22, rPtr->margins.left+m-10, 22);
drawLeftMarker(rPtr);
drawRightMarker(rPtr);
drawFirstMarker(rPtr);
drawBodyMarker(rPtr);
}
static void
paintRuler(Ruler *rPtr)
{
WMScreen *screen = rPtr->view->screen;
if(1||!rPtr->drawBuffer) {
drawRulerOnPixmap(rPtr);
}
XCopyArea(rPtr->view->screen->display, rPtr->drawBuffer,
rPtr->view->window, rPtr->bg, 0, 0, rPtr->view->size.width, 40,
0, 0);
}
static Bool
verifyMarkerMove(Ruler *rPtr, int x)
{
if(rPtr->flags.whichMarker<1 || rPtr->flags.whichMarker>6)
return False;
switch(rPtr->flags.whichMarker) {
case 1:
if(x > rPtr->margins.right - 10 || x < rPtr->offset ||
rPtr->margins.body + x > rPtr->margins.right-MIN_DOC_WIDTH ||
rPtr->margins.first + x > rPtr->margins.right-MIN_DOC_WIDTH)
return False;
break;
case 2:
if(x < rPtr->margins.first+MIN_DOC_WIDTH ||
x < rPtr->margins.body+MIN_DOC_WIDTH ||
x < rPtr->margins.left+MIN_DOC_WIDTH ||
x > rPtr->end) /*rPtr->view->size.width)*/
return False;
break;
case 3:
if(x >= rPtr->margins.right-MIN_DOC_WIDTH || x < rPtr->margins.left)
return False;
break;
case 4:
if(x >= rPtr->margins.right-MIN_DOC_WIDTH || x < rPtr->margins.left)
return False;
break;
case 6:
if(x >= rPtr->margins.right-MIN_DOC_WIDTH || x < rPtr->margins.left)
return False;
break;
default:
return False;
}
rPtr->motion = x;
return True;
}
static int
whichMarker(Ruler *rPtr, int x, int y)
{
if(x<rPtr->offset || y>22)
return 0;
if( rPtr->margins.left-x >= -6 && y <= 9
&& (rPtr->margins.left-x <=0) && y>=4) {
rPtr->motion = rPtr->margins.left;
return 1;
}
if(rPtr->margins.right-x >= -1 && y <= 11
&& rPtr->margins.right-x <=5 && y>=4) {
rPtr->motion = rPtr->margins.right;
return 2;
}
#if 0
/* both first and body? */
if( rPtr->margins.first-x <= 4 && rPtr->margins.first-x >= -5
&& rPtr->margins.body-x <= 4 && rPtr->margins.body-x >= -5
&& y>=15 && y<=17) {
rPtr->motion = rPtr->margins.first;
return 6;
}
#endif
if(rPtr->margins.first-x <= 4 && y<=15
&& rPtr->margins.first-x >= -5 && y>=10) {
rPtr->motion = rPtr->margins.first;
return 3;
}
if( rPtr->margins.body-x <= 4 && y<=21 &&
rPtr->margins.body-x >= -5 && y>=17) {
rPtr->motion = rPtr->margins.body;
return 4;
}
/* do tabs (5)*/
return 0;
}
static void
handleEvents(XEvent *event, void *data)
{
Ruler *rPtr = (Ruler*)data;
Display *dpy = event->xany.display;
switch (event->type) {
case Expose:
paintRuler(rPtr);
break;
case MotionNotify:
if(rPtr->flags.buttonPressed
&& (event->xmotion.state & Button1Mask)) {
if(verifyMarkerMove(rPtr, event->xmotion.x)){
GC gc = WMColorGC(WMDarkGrayColor(rPtr->view->screen));
paintRuler(rPtr);
if(rPtr->moveAction)
(rPtr->moveAction)(rPtr, rPtr->clientData);
XSetLineAttributes(rPtr->view->screen->display, gc, 1,
LineSolid, CapNotLast, JoinMiter);
XDrawLine(rPtr->pview->screen->display,
rPtr->pview->window,
gc, rPtr->motion+1, 40,
rPtr->motion+1, rPtr->pview->size.height-5);
}
}
break;
case ButtonPress:
if(event->xbutton.button != Button1)
return;
rPtr->flags.buttonPressed = True;
rPtr->flags.whichMarker =
whichMarker(rPtr, event->xmotion.x,
event->xmotion.y);
break;
case ButtonRelease:
if(event->xbutton.button != Button1)
return;
rPtr->flags.buttonPressed = False;
switch(rPtr->flags.whichMarker) {
case 1: {
int change = rPtr->margins.left-rPtr->motion;
rPtr->margins.first -=change;
rPtr->margins.body -= change;
rPtr->margins.left = rPtr->motion;
paintRuler(rPtr); break;
}
case 2: rPtr->margins.right = rPtr->motion; break;
case 3: rPtr->margins.first = rPtr->motion; break;
case 4: rPtr->margins.body = rPtr->motion; break;
case 6: rPtr->margins.first = rPtr->margins.body
= rPtr->motion; break;
}
if(rPtr->releaseAction)
(rPtr->releaseAction)(rPtr, rPtr->clientData);
break;
}
}
static void
rulerDidResize(W_ViewDelegate *self, WMView *view)
{
Ruler *rPtr = (Ruler *)view->self;
createDrawBuffer(rPtr);
paintRuler(rPtr);
}
W_ViewDelegate _RulerViewDelegate =
{
NULL,
NULL,
rulerDidResize,
NULL,
NULL
};
WMRuler *
WMCreateRuler(WMWidget *parent)
{
Ruler *rPtr = wmalloc(sizeof(Ruler));
unsigned int w = WMWidgetWidth(parent);
memset(rPtr, 0, sizeof(Ruler));
rPtr->widgetClass = WC_Ruler;
rPtr->view = W_CreateView(W_VIEW(parent));
if (!rPtr->view) {
free(rPtr);
return NULL;
}
rPtr->view->self = rPtr;
rPtr->drawBuffer = (Pixmap) NULL;
W_ResizeView(rPtr->view, w, 40);
WMCreateEventHandler(rPtr->view, ExposureMask|StructureNotifyMask
|EnterWindowMask|LeaveWindowMask|FocusChangeMask
|ButtonReleaseMask|ButtonPressMask|KeyReleaseMask
|KeyPressMask|Button1MotionMask, handleEvents, rPtr);
rPtr->view->delegate = &_RulerViewDelegate;
rPtr->bg = WMColorGC(WMGrayColor(rPtr->view->screen));
rPtr->fg = WMColorGC(WMBlackColor(rPtr->view->screen));
rPtr->font = WMSystemFontOfSize(rPtr->view->screen, 8);
rPtr->offset = 22;
rPtr->margins.left = 22;
rPtr->margins.body = 22;
rPtr->margins.first = 42;
rPtr->margins.right = (w<502?w:502);
rPtr->flags.whichMarker = 0; /* none */
rPtr->flags.buttonPressed = False;
rPtr->moveAction = NULL;
rPtr->releaseAction = NULL;
rPtr->pview = W_VIEW(parent);
return rPtr;
}
void
WMSetRulerMargins(WMRuler *rPtr, WMRulerMargins margins)
{
if(!rPtr)
return;
rPtr->margins.left = margins.left + rPtr->offset;
rPtr->margins.right = margins.right + rPtr->offset;
rPtr->margins.first = margins.first + rPtr->offset;
rPtr->margins.body = margins.body + rPtr->offset;
rPtr->margins.tabs = margins.tabs; /*for loop*/
paintRuler(rPtr);
}
WMRulerMargins
WMGetRulerMargins(WMRuler *rPtr)
{
WMRulerMargins margins;
if(!rPtr)
return margins;
margins.left = rPtr->margins.left - rPtr->offset;
margins.right = rPtr->margins.right - rPtr->offset;
margins.first = rPtr->margins.first - rPtr->offset;
margins.body = rPtr->margins.body - rPtr->offset;
/*for*/
margins.tabs = rPtr->margins.tabs;
return rPtr->margins;
}
void
WMSetRulerOffset(WMRuler *rPtr, int pixels)
{
if(!rPtr || pixels<0 || pixels+MIN_DOC_WIDTH>=rPtr->view->size.width)
return;
rPtr->offset = pixels;
/*rulerDidResize(rPtr, rPtr->view);*/
}
int
WMGetRulerOffset(WMRuler *rPtr)
{
if(!rPtr)
return;
return rPtr->offset;
}
void
WMSetRulerReleaseAction(WMRuler *rPtr, WMAction *action, void *clientData)
{
if(!rPtr)
return;
rPtr->releaseAction = action;
rPtr->clientData = clientData;
}
void
WMSetRulerMoveAction(WMRuler *rPtr, WMAction *action, void *clientData)
{
if(!rPtr)
return;
rPtr->moveAction = action;
rPtr->clientData = clientData;
}
/* _which_ one was released */
int
WMGetReleasedRulerMargin(WMRuler *rPtr)
{
if(!rPtr)
return 0;
return rPtr->flags.whichMarker;
}
/* _which_ one is being grabbed */
int
WMGetGrabbedRulerMargin(WMRuler *rPtr)
{
if(!rPtr)
return 0;
return rPtr->flags.whichMarker;
}