V9/jtools/src/cip/menus.c
/*
%Z% %M% version %I% %Q%of %H% %T%
Last Delta: %G% %U% to %P%
*/
#include "cip.h"
extern int currentBrush, copyFlag, thingSelected, editDepth;
extern Rectangle brushes[];
extern int gridState, videoState, buttonState;
extern short noSpace;
extern Point jString ();
extern void getKbdChar ();
extern void jMoveTo ();
extern struct macro *macroList;
char *lineText[] = {"delete","copy",
"solid","dotted","dashed","arrow",
"reflect x","reflect y",NULL};
Menu lineMenu = { lineText };
char *boxText[] = {"delete","copy","solid","dotted","dashed",NULL};
Menu boxMenu = { boxText };
char *circleText[] = {"delete","copy",NULL};
Menu circleMenu = { circleText };
char *splineText[] = {"delete", "copy", "arrow",
"reflect x", "reflect y", NULL};
Menu splineMenu = { splineText };
char *arcText[] = {"delete","copy","reflect x","reflect y",NULL};
Menu arcMenu = { arcText };
char *macroText[] = {"delete","copy","reflect x","reflect y",
"edit","separate",NULL};
Menu macroMenu = { macroText };
char *textText[] = {"delete","copy","point size","roman",
"italic","bold", "center","left justify",
"right justify","attributes",
NULL};
Menu textMenu = { textText };
#define GET 0
#define PUT 1
#define CLEAR 2
#define REDRAW 3
#define DEFINEMACRO 4
#define GRID 5
#define FLIPVIDEO 6
#define QUIT 7
#define DUMPIT 8
char *commandText[] = {"get file","put file","clear screen",
"redraw screen","define macro","grid",
"reverse video","quit",
#ifdef DUMP
"dump",
#endif
NULL};
Menu commandMenu = { commandText };
int
menuHit (menu, but)
Menu *menu;
int but;
{
int item;
cursswitch ((Word *)NULL);
item = menuhit(menu, but);
cursSwitch ();
return (item);
}
struct thing *
insertReflect (t, p, item, which)
struct thing *t;
Point p; /* Offset */
int item;
int which; /* Which item to be tested */
{
register struct thing d; /* Dummy structure */
register struct thing *h; /* New head of thing list */
drawSelectionLines(t,p);
draw(t,p);
h = remove(t);
d = *t;
free(t);
h = (item==which) ?
insert(reflect(&d,Pt(0,d.bb.corner.y+d.bb.origin.y)),h)
: insert(reflect(&d,Pt(d.bb.corner.x+d.bb.origin.x,0)),h);
draw(h,p);
drawSelectionLines(h,p);
return (h);
}
/* This routine deletes the given macro from the macro list. */
/* It has to scan the macro list looking for that macros entry since */
/* there are no back links within the list. */
void
removeMacro (m)
struct macro *m;
{
register struct macro *ml; /* Pointer for macro list */
if (m == macroList) {
macroList = (struct macro *)NULL;
}
else {
for (ml = macroList; ml != (struct macro *)NULL; ml = ml->next) {
if (ml->next == m) { /* Macro found delete it. */
ml->next = m->next;
}
}
}
free (m);
return;
}
struct thing *
displayThingMenu(m,t,p)
Point m; /* Mouse location */
Point p; /* Offset */
register struct thing *t; /* Thing to be displayed */
{
register int item;
register int i, b, oldED;
register struct thing *pts;
register struct thing *h, *g, *f;
Rectangle r; register char c, s[10];
switch(t->type) {
case LINE: {
item = menuHit (&lineMenu, 3);
b = -1;
switch (item) {
case 2: {
/* make line solid */
b = SOLID;
break;
}
case 3: {
/* make line dotted */
b = DOTTED;
break;
}
case 4: {
/* make line dashed */
b = DASHED;
break;
}
case 5: {
/* add or remove arrowheads */
draw(t,p);
if (distance(m,t->origin) < distance(m,t->otherValues.end)) {
if ((t->arrow==startARROW)||(t->arrow==doubleARROW)) {
t->arrow -= startARROW;
}
else {
t->arrow += startARROW;
}
}
else {
if ((t->arrow==endARROW)||(t->arrow==doubleARROW)) {
t->arrow -= endARROW;
}
else {
t->arrow += endARROW;
}
}
draw(t,p);
break;
}
case 6:
case 7: {
t = insertReflect (t, p, item, 6);
break;
}
}
if (b >= 0 && b!=t->boorder) {
draw(t,p);
t->boorder = b;
draw(t,p);
}
break;
}
case BOX: {
item = menuHit(&boxMenu,3);
b = -1;
switch(item) {
case 2: { /* make box outline solid */
b = SOLID;
break;
}
case 3: { /* make box outline dotted */
b = DOTTED;
break;
}
case 4: { /* make box outline dashed */
b = DASHED;
break;
}
}
if (b>=0 && b!=t->boorder) {
draw(t,p);
t->boorder = b;
draw(t,p);
}
break;
}
case MACRO: {
item = menuHit(¯oMenu,3);
switch (item) {
case 2:
case 3: {
r = t->otherValues.list->bb;
h = TNULL;
draw(t,p);
if (item==2 && t->otherValues.list->xReflectionOf
!= (struct macro *)NULL) {
t->otherValues.list->useCount--;
t->otherValues.list = t->otherValues.list->xReflectionOf;
}
else {
if (item==3 && t->otherValues.list->yReflectionOf
!= (struct macro *)NULL) {
t->otherValues.list->useCount--;
t->otherValues.list = t->otherValues.list->yReflectionOf;
}
else {
/* Go thru parts list, reflect all things, and */
/* make copies of them. The copies go into the list h. */
if ((g=t->otherValues.list->parts)
!=TNULL) {
do {
h = (item==2) ?
insert(reflect(
g,Pt(0,r.origin.y+r.corner.y)),h)
: insert(reflect(
g,Pt(r.corner.x+r.origin.x,0)),h);
g = g->next;
} while (g != t->otherValues.list->parts);
}
t->otherValues.list = recordMacro(h,r,
(item==2)?t->otherValues.list :(struct macro *)NULL,
(item==2)?(struct macro *)NULL :t->otherValues.list,
NULL);
}
}
t->otherValues.list->useCount++;
draw(t,p);
break;
}
case 4: {
/* edit macro */
oldED = editDepth;
removeReflectionReferences(t->otherValues.list);
pts = t->otherValues.list->parts;
/* Draw edit button when editDepth==1, other times */
/* undraw button. */
if ((editDepth)!=0) {
drawEDbutton(editDepth);
}
drawEDbutton(++editDepth);
changeButtons (INITbuttons);
thingSelected = 0;
while (editDepth>oldED) {
pts = doMouseButtons(pts,add(p,t->origin));
jnap(2);
}
t->otherValues.list->parts = pts;
t->otherValues.list->bb = macroBB(pts);
if (thingSelected) {
drawSelectionLines (t, p);
thingSelected = 0;
}
if (editDepth==0) {
doRedraw(t, p);
}
break;
}
case 5: { /* separate */
h = remove(t); /* Cut macro from thing list */
t->otherValues.list->useCount--;
m = sub(Pt(0,0),t->origin);
/* Go thru macro's thing list and make everything relative */
if ((g=t->otherValues.list->parts)!=TNULL) {
if (t->otherValues.list->useCount > 0) {
do { /* Copy list */
if ((f=(struct thing *)getSpace(sizeof(struct thing)))
== TNULL) {
break;
}
g = g->next;
*f = *g;
f = makeRelative (f, m);
h = insert (f, h);
} while (g != t->otherValues.list->parts);
}
else {
do{ /* Move list */
g = g->next;
g = makeRelative(g,m);
f = g;
g = remove (f);
h = insert (f, h);
} while (g != TNULL);
removeMacro (t->otherValues.list);
}
}
thingSelected = 0;
copyFlag = 0;
changeButtons(INITbuttons);
free(t); /* Remove macro thing */
t = h;
break;
}
}
break;
}
case TEXT: {
item = menuHit(&textMenu,3);
switch (item) {
case 2: { /* point size */
m = MOUSE_XY;
m.x += 20;
getKbdText (s, m, 0, &pointsize, sizeof (s)-1);
b = atoi (s);
draw(t,p);
t->otherValues.text.f->useCount--;
t->otherValues.text.f =
findFont(b,t->otherValues.text.f->num);
draw(t,p);
BoundingBox(t);
break;
}
case 3: /* roman face */
case 4: /* italic face */
case 5: { /* bold face */
draw(t,p);
t->otherValues.text.f->useCount--;
t->otherValues.text.f =
findFont(t->otherValues.text.f->ps,item-2);
BoundingBox(t);
draw(t,p);
break;
}
case 6: /* center */
case 7: /* left justify */
case 8: { /* right justify */
draw(t,p);
t->otherValues.text.just = item - 6;
BoundingBox(t);
draw(t,p);
break;
}
case 9: { /* show attributes */
char buf[25];
cursswitch(&candle);
sprintf(buf,"%s f:%c ps:%d",
(t->otherValues.text.just==CENTER)?"center":
((t->otherValues.text.just==LEFTJUST)?"ljust":"rjust"),
(t->otherValues.text.f->num==ROMAN)?'R':
((t->otherValues.text.f->num==ITALIC)?'I':'B'),
t->otherValues.text.f->ps);
m = MOUSE_XY;
jMoveTo(Pt(m.x+20,m.y));
jString(buf);
wait(MOUSE);
while (!button123()) {
jnap(2);
}
jMoveTo(Pt(m.x+20,m.y));
jString(buf);
cursSwitch();
break;
}
}
break;
}
case CIRCLE:
case ELLIPSE: {
item = menuHit(&circleMenu,3);
break;
}
case ARC: {
item = menuHit(&arcMenu,3);
switch (item) {
case 2:
case 3: {
t = insertReflect (t, p, item, 2);
break;
}
}
break;
}
case SPLINE: {
item = menuHit(&splineMenu,3);
switch (item) {
case 2: { /* arrow */
b = t->otherValues.spline.used;
if (distance(m,t->origin)<
distance(m,t->otherValues.spline.plist[b])) {
if ((t->arrow==startARROW)||(t->arrow==doubleARROW)) {
t->arrow -= startARROW;
}
else {
t->arrow += startARROW;
}
arrow(add(p,t->otherValues.spline.plist[2]),
add(p,t->otherValues.spline.plist[1]));
}
else {
if ((t->arrow==endARROW)||(t->arrow==doubleARROW)) {
t->arrow -= endARROW;
}
else {
t->arrow += endARROW;
}
arrow(add(p,t->otherValues.spline.plist[b-2]),
add(p,t->otherValues.spline.plist[b-1]));
}
break;
}
case 3:
case 4: {
t = insertReflect(t, p, item, 3);
break;
}
}
break;
}
}
if (item == 1) /* copy */ {
if (!noSpace) {
copyFlag=1;
changeButtons(COPYbuttons);
}
}
else {
if (item == 0) {
/* delete */
drawSelectionLines(t,p);
t = deleteThing(t,p);
thingSelected = 0;
copyFlag = 0;
changeButtons(INITbuttons);
}
}
return(t);
}
RUsure ()
{
int savebuttonstate;
int ret;
ret = 0;
cursswitch (&rusure);
savebuttonstate = buttonState;
changeButtons (QUITbuttons);
while (!button123())
jnap(2);
if (button3()) {
ret = 1;
}
changeButtons (savebuttonstate);
while (button12())
jnap(2);
cursSwitch();
return (ret);
}
struct thing *
displayCommandMenu(h, offset)
register struct thing *h;
Point offset;
{
int item;
item = menuHit(&commandMenu,3);
switch (item) {
case GET: {
h = doGet(h);
break;
}
case PUT: {
doPut(h);
break;
}
case CLEAR: {
if (RUsure()) {
h = doClear(h);
}
break;
}
case DEFINEMACRO: {
if (!noSpace) {
h = defineMacro(h);
}
break;
}
case REDRAW: {
doRedraw(h, offset);
break;
}
case QUIT: {
if (RUsure()) {
exit (0);
}
break;
}
case GRID: {
gridState = (gridState==GRIDon)?GRIDoff:GRIDon;
drawGrid();
break;
}
case FLIPVIDEO: {
if (videoState==WHITEfield) {
videoState=BLACKfield;
rectf (&display, Drect, F_XOR);
}
else {
videoState=WHITEfield;
rectf (&display, Drect, F_XOR);
}
break;
}
#ifdef DUMP
case DUMPIT: {
dump (h);
break;
}
#endif
}
return(h);
}
doRedraw(h, offset)
struct thing *h;
Point offset;
{
register struct thing *t;
cursinhibit();
xtipple(&display,brushes[PIC]);
cursallow();
if (gridState==GRIDon) {
drawGrid();
}
if ((t = h) != TNULL) {
do {
if (t->type==MACRO) BoundingBox(t);
draw(t,offset);
t = t->next;
} while (t != h);
}
}