/* X11resizebr - brush resizing dialog for X11 */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
/***********************************************************************/
/** **/
/** General Includes and Definitions **/
/** **/
/***********************************************************************/
#include "xlisp.h"
#include "xlstat.h"
#include "xlgraph.h"
extern Display *StX11Display();
typedef struct {
unsigned long fore, back;
} ColorPair;
/* forward declarations */
LOCAL VOID draw_dialog _((Window win));
LOCAL VOID draw_button _((Window win, char *text));
LOCAL VOID drag_brush _((XEvent report, int *pwidth, int *pheight));
/***********************************************************************/
/** **/
/** Global Variables **/
/** **/
/***********************************************************************/
#define WindowWidth 250
#define WindowHeight 200
static char ResizeMessage1[] = "To resize brush click in";
static char ResizeMessage2[] = "this window and drag";
static char OK_String[] = "OK";
static char CANCEL_String[] = "Cancel";
/* configuration parameters - should be set using the defaults database */
extern XFontStruct *DialogFont;
extern unsigned long DialogBorderColor, ButtonBorderColor;
extern ColorPair DialogC, ButtonC;
extern unsigned int dialog_border_width, button_border_width;
extern int min_button_height, min_button_width, dialog_item_gap;
extern GC DialogGC, ResizeGC;
extern Cursor ArrowCursor;
/***********************************************************************/
/** **/
/** Resize Brush Dialog Function **/
/** **/
/***********************************************************************/
int IViewGetNewBrushSize(w, new_width, new_height)
IVIEW_WINDOW w;
int *new_width, *new_height;
{
Window win, ok_win, cancel_win;
unsigned int width = WindowWidth, height = WindowHeight;
int left, top;
XSetWindowAttributes setwinattr;
unsigned long valuemask;
XEvent report;
int done = FALSE;
Display *dpy = StX11Display();
int screen = StX11Screen();
int brush_width, brush_height;
int cancelled = FALSE;
/* create opaque dialog window */
left = (DisplayWidth(dpy, screen) - WindowWidth) / 2;
top = (DisplayHeight(dpy, screen) - WindowHeight) / 3;
win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
left, top, width, height, dialog_border_width,
DialogBorderColor, DialogC.back);
/* set the override_redirect and save_under attributes for a dialog */
valuemask = CWOverrideRedirect | CWSaveUnder;
setwinattr.override_redirect = TRUE;
setwinattr.save_under = TRUE;
XChangeWindowAttributes(dpy, win, valuemask, &setwinattr);
XSelectInput(dpy, win, ExposureMask | ButtonPressMask | ButtonMotionMask);
/* make the buttons */
ok_win = XCreateSimpleWindow(dpy, win,
dialog_item_gap,
WindowHeight - dialog_item_gap
- min_button_height,
min_button_width, min_button_height,
button_border_width,
ButtonBorderColor, ButtonC.back);
XSelectInput(dpy, ok_win,
ExposureMask | EnterWindowMask |
LeaveWindowMask | ButtonPressMask | ButtonReleaseMask);
cancel_win = XCreateSimpleWindow(dpy, win,
WindowWidth - min_button_width
- dialog_item_gap,
WindowHeight - dialog_item_gap
- min_button_height,
min_button_width, min_button_height,
button_border_width,
ButtonBorderColor, ButtonC.back);
XSelectInput(dpy, cancel_win,
ExposureMask | EnterWindowMask |
LeaveWindowMask | ButtonPressMask | ButtonReleaseMask);
/* set the cursor */
XDefineCursor(dpy, win, ArrowCursor);
/* Display (map) the windows */
XMapSubwindows(dpy, win);
XMapWindow(dpy, win);
/* grap the pointer */
StX11ReleaseButton();
XGrabPointer(dpy, win, TRUE,
ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
/* Loop until button is released, examining each event */
brush_width = 0;
brush_height = 0;
while (! done) {
XNextEvent(dpy, &report);
switch (report.type) {
case Expose:
if (report.xexpose.window == win) {
draw_dialog(win);
}
else if (report.xexpose.window == ok_win)
draw_button(ok_win, OK_String);
else if (report.xexpose.window == cancel_win)
draw_button(cancel_win, CANCEL_String);
else StProcessEvent(dpy, report);
break;
case ButtonPress:
if (report.xbutton.window == win)
drag_brush(report, &brush_width, &brush_height);
break;
case ButtonRelease:
if (report.xbutton.window == ok_win
|| report.xbutton.window == cancel_win) {
if (report.xbutton.window == cancel_win) cancelled = TRUE;
done = TRUE;
}
break;
case EnterNotify:
if (report.xcrossing.window == ok_win)
XSetWindowBorderWidth(dpy, ok_win, button_border_width + 1);
else if (report.xcrossing.window == cancel_win)
XSetWindowBorderWidth(dpy, cancel_win, button_border_width + 1);
break;
case LeaveNotify:
if (report.xcrossing.window == ok_win)
XSetWindowBorderWidth(dpy, ok_win, button_border_width);
else if (report.xcrossing.window == cancel_win)
XSetWindowBorderWidth(dpy, cancel_win, button_border_width);
break;
default:
break;
}
}
/* clean up */
XDestroyWindow(dpy, win);
XFlush(dpy);
if (new_width != NULL) *new_width = brush_width;
if (new_height != NULL) *new_height = brush_height;
return(! cancelled);
}
LOCAL VOID draw_dialog(win)
Window win;
{
int font_height, margin, x, y, len, text_width;
GC gc;
Display *dpy = StX11Display();
char *text;
font_height = DialogFont->max_bounds.ascent
+ DialogFont->max_bounds.descent;
margin = DialogFont->max_bounds.descent / 2;
gc = DialogGC;
text = ResizeMessage1;
len = strlen(text);
text_width = XTextWidth(DialogFont, text, len);
x = (WindowWidth - text_width) / 2;
y = DialogFont->max_bounds.ascent + margin;
XDrawString(dpy, win, gc, x, y, text, len);
text = ResizeMessage2;
len = strlen(text);
text_width = XTextWidth(DialogFont, text, len);
x = (WindowWidth - text_width) / 2;
y = 2 * y;
XDrawString(dpy, win, gc, x, y, text, len);
}
LOCAL VOID draw_button(win, text)
Window win;
char *text;
{
int font_height, x, y, len, text_width;
GC gc;
Display *dpy = StX11Display();
len = strlen(text);
text_width = XTextWidth(DialogFont, text, len);
font_height = DialogFont->max_bounds.ascent
+ DialogFont->max_bounds.descent;
x = (min_button_width - text_width) / 2;
y = DialogFont->max_bounds.ascent + (min_button_height - font_height) / 2;
gc = DialogGC;
XDrawString(dpy, win, gc, x, y, text, len);
}
LOCAL VOID drag_brush(report, pwidth, pheight)
XEvent report;
int *pwidth, *pheight;
{
Window win = report.xbutton.window, child;
Display *dpy = StX11Display();
int done = FALSE, newx, newy;
int xinit = report.xbutton.x, yinit = report.xbutton.y, x = xinit, y = yinit;
GC gc = ResizeGC;
XDrawRectangle(dpy, win, gc, xinit, yinit, 0, 0); /* to draw */
/* Loop until button is released, examining each event */
while (! done) {
XNextEvent(dpy, &report);
switch (report.type) {
case MotionNotify:
if (win == report.xmotion.window) {
newx = report.xmotion.x;
newy = report.xmotion.y;
}
else {
XTranslateCoordinates(dpy, report.xmotion.window, win,
report.xmotion.x, report.xmotion.y, &newx, &newy,
&child);
}
XDrawRectangle(dpy, win, gc,
(xinit < x) ? xinit : x,
(yinit < y) ? yinit : y,
(xinit < x) ? x - xinit : xinit - x,
(yinit < y) ? y - yinit : yinit - y); /* to erase */
x = newx;
y = newy;
XDrawRectangle(dpy, win, gc,
(xinit < x) ? xinit : x,
(yinit < y) ? yinit : y,
(xinit < x) ? x - xinit : xinit - x,
(yinit < y) ? y - yinit : yinit - y); /* to draw */
break;
case ButtonRelease:
done = TRUE;
break;
default:
break;
}
}
XDrawRectangle(dpy, win, gc,
(xinit < x) ? xinit : x,
(yinit < y) ? yinit : y,
(xinit < x) ? x - xinit : xinit - x,
(yinit < y) ? y - yinit : yinit - y); /* to erase */
*pwidth = (x < xinit) ? xinit - x : x - xinit;
*pheight = (y < yinit) ? yinit - y : y - yinit;
}
#ifdef TODO
try to leave brush up after it has been set
use dashed lines
#endif /* TODO */
syntax highlighted by Code2HTML, v. 0.9.1