/*
* Command support & miscellaneous commands
*/
#include "art.h"
Image *background, *black;
char *buttons2[]={
"line",
"circle",
"arc",
"box",
"spline",
"group",
0
};
Menu menu2={buttons2};
char *buttons3[]={
"delete",
"heat",
"copy",
"edit",
"open",
"close",
"flatten",
0
};
Menu menu3={buttons3};
int narg;
Dpoint arg[NARG];
/*
* body of command loop
*/
void command(void){
for(;;){
getmouse();
if(button123() && hitmenubar()==-1){
if(button1()) getarg();
else if(button2()){
switch(emenuhit(2, &mouse, &menu2)){
case 0: Oline(); break;
case 1: Ocircle(); break;
case 2: Oarc(); break;
case 3: Obox(); break;
case 4: Ospline(); break;
case 5: Ogroup(); break;
}
}
else if(button3()){
switch(emenuhit(3, &mouse, &menu3)){
case 0: Odelete(); break;
case 1: Oheat(); break;
case 2: Ocopy(); break;
case 3: Oedit(); break;
case 4: Oopengrp(); break;
case 5: Oclosegrp(); break;
case 6: Oflattengrp(); break;
}
}
}
}
}
Cursor confirm3 = {
0, 0,
0x0F, 0xBF,
0x0F, 0xBF,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFE,
0xFF, 0xFE,
0xFF, 0xFE,
0xFF, 0xFE,
0xFF, 0xFF,
0x00, 0x07,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFE,
0xFF, 0xF8,
0x00, 0x0E,
0x07, 0x1F,
0x03, 0x17,
0x73, 0x6F,
0xFB, 0xCE,
0xDB, 0x8C,
0xDB, 0xC0,
0xFB, 0x6C,
0x77, 0xFC,
0x00, 0x00,
0x00, 0x01,
0x00, 0x03,
0x94, 0xA6,
0x63, 0x3C,
0x63, 0x18,
0x94, 0x90,
};
int confirm(char *action){
int b;
msg("button 3 to %s", action);
esetcursor(&confirm3);
while(!button123()) getmouse();
esetcursor((Cursor *)0);
msg(cmdname);
b=button3();
while(button123()) getmouse();
return b;
}
void Oexit(void){
if(confirm("exit")) exits("");
}
int curgrav=6;
char *mgravity[]={
"gravity",
" off",
" .01",
" .02",
" .03",
" .05",
" .08",
"*.13",
" .21",
" .34",
0
};
int gval[]={0, 1, 2, 3, 5, 8, 13, 21, 34};
void Ogravity(int n){
gravity=gval[n]/DPI;
mgravity[curgrav+1][0]=' ';
curgrav=n;
mgravity[curgrav+1][0]='*';
}
char *mheating[]={
"heating",
"*heat new",
0
};
int heatnew=1;
void Oheating(int n){
switch(n){
case 0:
heatnew=!heatnew;
mheating[1][0]=heatnew?'*':' ';
break;
}
}
void getarg(void){
track(movenone, 0, 0);
argument();
}
void argument(void){
register i;
marks();
if(narg!=NARG) narg++;
for(i=narg-1;i!=0;--i) arg[i]=arg[i-1];
arg[0]=curpt;
marks();
msg(cmdname);
}
void Oselall(void){
setselection(scene);
}
void Oanchor(void){
marks();
anchor=curpt;
marks();
}
Scsave *scsp=scstack;
void Oopengrp(void){
int i, g;
Dpoint soffs;
if(scsp==&scstack[NSCSTACK])
msg("open: stack overflow");
else if(!selection || selection->type!=GROUP || !goodgroup(selection->group))
msg("open: must select a group");
else{
scsp->scene=scene;
scsp->scoffs=scoffs;
scsp++;
g=selection->group;
soffs=selection->p[0];
setselection(0);
scene=group[g];
scoffs=dadd(scoffs, soffs);
curpt=dsub(curpt, soffs);
for(i=0;i!=narg;i++) arg[i]=dsub(arg[i], soffs);
}
}
void Oclosegrp(void){
Dpoint delta;
int i;
if(scsp==&scstack[0])
msg("close: nothing open");
else{
setselection(0);
--scsp;
delta=dsub(scoffs, scsp->scoffs);
curpt=dadd(curpt, delta);
for(i=0;i!=narg;i++) arg[i]=dadd(arg[i], delta);
scene=scsp->scene;
scoffs=scsp->scoffs;
redraw();
}
}
void Oflattengrp(void){
Item *ip;
Dpoint offs;
if(!selection || selection->type!=GROUP || !goodgroup(selection->group)){
msg("flatten: must select a group");
return;
}
offs=dadd(selection->p[0], scoffs);
for(ip=group[selection->group]->next;ip->type!=HEAD;ip=ip->next)
additemv(scene, ip->type, ip->r, ip->face, ip->text, ip->group, ip->fn,
ip->np, ip->p, offs);
ip=selection;
setselection(0);
delete(ip);
}
void Odelete(void){
Item *s=selection;
if(s){
if(s==scene && !confirm("delete everything")) return;
setselection(0);
delete(s);
if(s==scene) scene=addhead();
redraw();
reheat();
realign();
setselection(select());
}
else msg("delete: nothing selected");
}
Rune rcmd[]={L'◀',0};
char cmd[]="◀";
Rune *rcmdp=rcmd;
void typein(int c){
switch(c){
case '\n':
case '\r':
*rcmdp='\0';
sprint(cmd, "%S", rcmd);
typecmd();
case '@':
rcmdp=rcmd;
*rcmdp='\0';
break;
case '\b':
if(rcmdp!=rcmd)
*--rcmdp='\0';
break;
case 027: /* ctrl-w */
while(rcmdp!=rcmd && !idchar(rcmdp[-1]))
--rcmdp;
while(rcmdp!=rcmd && idchar(rcmdp[-1]))
--rcmdp;
*rcmdp='\0';
break;
default:
*rcmdp++=c;
*rcmdp='\0';
break;
}
rcmdp[0]=L'◀';
rcmdp[1]='\0';
sprint(cmd, "%S", rcmd);
echo(cmd);
}
int idchar(int c){
return 'a'<=c && c<='z' || 'A'<=c && c<='Z' || '0'<=c && c<='9' || c=='_' || c>0177;
}
char filename[NCMD];
void typecmd(void){
register char *a=cmd;
register c, style;
Item *s;
while(*a==' ' || *a=='\t') a++;
c=*a++;
if(*a=='\0') a=0;
else if(*a!=' ' && *a!='\t'){
What:
msg("what?");
return;
}
else{
while(*a==' ' || *a=='\t') a++;
if(*a=='\0') goto What;
}
switch(c){
default:
goto What;
case 'f': /* font select */
if(a) setface(a);
msg(curface->name);
break;
case 'D': /* draw a clean display */
redraw();
break;
case 'q': /* quit */
if(a) goto What;
rectf(screen, insetrect(screen->r, 3), background); /* width of 8.5 border is 3 */
exits("");
case 'r': /* read a file */
if(a) strcpy(filename, a);
if(filename[0]=='\0') goto What;
input(filename);
break;
case 'w': /* write a file */
if(a) strcpy(filename, a);
if(filename[0]=='\0') goto What;
output(filename);
break;
case 'c':
if(a) goto What;
Ocoolall();
break;
case 'a':
if(a) goto What;
Oselall();
break;
case 'd':
if(a) goto What;
Oanchor();
break;
case 't': /* text */
if(!a) goto What;
s=addtext(scene, curpt, curface, a);
itemdraw(s, scoffs, black);
setselection(s);
break;
case 's':
if(selection==0) goto What; /* no! should give a reasonable message */
if(!a && selection->style)
selection->style=0;
else{
style=0;
while(*a) switch(*a++){
default: goto What;
case '<': style|=ARROW0; break;
case '>': style|=ARROW1; break;
case '-': style|=DASH; break;
case '.': style|=DOT; break;
}
selection->style=style;
}
redraw();
break;
}
}
|