Files
sibo-playground/code/SIBOSDK/hwdemo/iconed.c
T
2026-07-06 18:01:36 +01:00

1365 lines
32 KiB
C

/*
ICONED.C
Written by DavidW
Started on 12/9/91
Based in part on work by Robert, May 91
*/
#include <p_std.h>
#include <p_gen.h>
#include <p_file.h>
#include <wlib.h>
#include <hwif.h>
GLREF_D UWORD DatLocked;
GLREF_D TEXT *DatUsedPathNamePtr;
LOCAL_D TEXT *cmds[]=
{
"nNew icon",
"oOpen icon",
"aSave as",
"sSave",
"rRevert",
"xExit",
"iInsert",
"cCopy",
"uUse",
"pPlaster",
"mMove",
"gGoto",
"zSet",
"qClear",
"tToggle",
"fFrame off",
"kCursor off",
"hHighlight select",
"wWrite text",
"bBorder",
"yInterrogation",
NULL
};
#define FILE_ITEMS 6
#define EDIT_ITEMS 6
#define BRUSH_ITEMS 3
#define SPECIAL_ITEMS 6
#define ITEMS_BEFORE_FILE 0
#define ITEMS_BEFORE_EDIT FILE_ITEMS
#define ITEMS_BEFORE_BRUSH (ITEMS_BEFORE_EDIT+EDIT_ITEMS)
#define ITEMS_BEFORE_SPECIAL (ITEMS_BEFORE_BRUSH+BRUSH_ITEMS)
#define FRAME_ITEM ITEMS_BEFORE_SPECIAL
#define CURSOR_ITEM ITEMS_BEFORE_SPECIAL+1
LOCAL_D H_MENU_DATA mdata[]=
{
"File",FILE_ITEMS,
"Edit",EDIT_ITEMS,
"Brush",BRUSH_ITEMS,
"Special",SPECIAL_ITEMS,
NULL
};
GLDEF_D TEXT ** _cmds=(&cmds[0]);
GLDEF_D H_MENU_DATA * _mdata=(&mdata[0]);
LOCAL_D UINT MainWid;
LOCAL_D WMSG_KEY key;
LOCAL_D WORD bid;
LOCAL_D VOID *fcb;
LOCAL_D TEXT filename[P_FNAMESIZE];
LOCAL_D WORD clipbid[6]={0,0,0,0,0,0};
LOCAL_D P_POINT clipsize[6];
#define MOVE_BACKUP 0
#define MOVE_RAFT 5
LOCAL_D UWORD MoveUpdatePending;
LOCAL_D P_RECT moveorigin;
LOCAL_D P_RECT movedto;
LOCAL_D UWORD MoveSingle;
LOCAL_D UWORD using=1;
LOCAL_D UWORD brush=2;
LOCAL_D UWORD changed=FALSE;
LOCAL_D UWORD show_cursor=TRUE;
LOCAL_D UWORD show_frame=FALSE;
LOCAL_D UWORD show_statwin=FALSE;
LOCAL_D UWORD require_query=TRUE;
LOCAL_D P_POINT anch;
LOCAL_D P_POINT curs;
LOCAL_D UWORD issel;
LOCAL_D TEXT ToWrite[10]={0};
LOCAL_D UWORD font=1;
LOCAL_D UWORD italic=1;
LOCAL_D UWORD BordCorner=2;
LOCAL_D UWORD BordShadow=1;
LOCAL_D UWORD BordCushion=1;
#define ICON_SIZE 24
#define LARGE_ICON_SCALE 3
#define SMALL_ICON_X 41
#define SMALL_ICON_WIDTH ICON_SIZE
#define SMALL_ICON_Y 8
#define SMALL_ICON_HEIGHT ICON_SIZE
#define LEFT_CURSOR_X 106
#define TOP_CURSOR_Y 0
#define LARGE_ICON_X 110
#define LARGE_ICON_Y 4
#define RIGHT_CURSOR_X 185
#define BOTTOM_CURSOR_Y 79
#define TEXT_TL_X 4
#define BRUSH_TEXT_Y 41
#define USING_TEXT_Y 50
#define CURSOR_TEXT_Y 59
#define ANCHOR_TEXT_Y 68
#define TEXT_BR_X 104
#define TEXT_HEIGHT 9
#define TEXT_ASCENT 8
LOCAL_C VOID CDECL WriteAt(INT y,TEXT *str,...)
{
P_RECT box;
TEXT buf[40];
INT len;
len=p_atob(&buf[0],str,&str+1);
box.tl.x=TEXT_TL_X;
box.tl.y=y;
box.br.x=TEXT_BR_X;
box.br.y=y+TEXT_HEIGHT;
gPrintBoxText(&box,TEXT_ASCENT,G_TEXT_ALIGN_LEFT,0,&buf[0],len);
}
LOCAL_C VOID WriteBrushText(VOID)
{
WriteAt(BRUSH_TEXT_Y,"Brush is `%s'",cmds[brush+ITEMS_BEFORE_BRUSH]+1);
}
LOCAL_C VOID WriteCursorText(VOID)
{
WriteAt(CURSOR_TEXT_Y,"Cursor: X %d, Y %d",curs.x,curs.y);
WriteAt(ANCHOR_TEXT_Y,(issel? "Anchor: X %d, Y %d": ""),anch.x,anch.y);
}
LOCAL_C VOID WriteClipboardText(VOID)
{
WriteAt(USING_TEXT_Y,"Using clipboard %d",using);
}
LOCAL_C VOID ScaleUp(P_RECT *pbox)
{
pbox->tl.x=LARGE_ICON_X+pbox->tl.x*LARGE_ICON_SCALE;
pbox->tl.y=LARGE_ICON_Y+pbox->tl.y*LARGE_ICON_SCALE;
pbox->br.x=LARGE_ICON_X+pbox->br.x*LARGE_ICON_SCALE;
pbox->br.y=LARGE_ICON_Y+pbox->br.y*LARGE_ICON_SCALE;
}
LOCAL_C VOID GetSmallSelectRegion(P_RECT *pbox)
{
if (anch.x>curs.x)
{
pbox->tl.x=curs.x;
pbox->br.x=anch.x+1;
}
else
{
pbox->tl.x=anch.x;
pbox->br.x=curs.x+1;
}
if (anch.y>curs.y)
{
pbox->tl.y=curs.y;
pbox->br.y=anch.y+1;
}
else
{
pbox->tl.y=anch.y;
pbox->br.y=curs.y+1;
}
}
LOCAL_C VOID GetSelectRegion(P_RECT *pbox)
{
GetSmallSelectRegion(pbox);
ScaleUp(pbox);
}
LOCAL_C VOID GetCursorBox(P_RECT *pbox)
{
pbox->tl.x=LARGE_ICON_X+curs.x*LARGE_ICON_SCALE;
pbox->tl.y=LARGE_ICON_Y+curs.y*LARGE_ICON_SCALE;
pbox->br.x=pbox->tl.x+LARGE_ICON_SCALE;
pbox->br.y=pbox->tl.y+LARGE_ICON_SCALE;
}
LOCAL_C VOID MakeCursorFlash(P_RECT *pbox)
{
W_CURSOR wc;
wc.pos.x=pbox->tl.x+1;
wc.pos.y=pbox->tl.y+1;
wc.height=1;
wc.width=1;
wc.ascent=0;
wDrawTextCursor(MainWid,&wc);
}
LOCAL_C VOID ReassertCursor(VOID)
{
P_RECT box;
if (show_cursor)
{
GetCursorBox(&box);
MakeCursorFlash(&box);
}
}
LOCAL_C INT RunDialog(VOID)
{
INT ret;
ret=uRunDialog();
ReassertCursor();
return(ret);
}
LOCAL_C VOID ToggleHorizCurs(P_RECT *pbox,INT tly,INT dely)
{
P_RECT box;
box=(*pbox);
box.tl.y=tly;
box.br.y=tly+1;
gClrRect(&box,G_TRMODE_INV);
p_offrec(&box,0,dely);
p_insrec(&box,1,0);
gClrRect(&box,G_TRMODE_INV);
}
LOCAL_C VOID ToggleVertCurs(P_RECT *pbox,INT tlx,INT delx)
{
P_RECT box;
box=(*pbox);
box.tl.x=tlx;
box.br.x=tlx+1;
gClrRect(&box,G_TRMODE_INV);
p_offrec(&box,delx,0);
p_insrec(&box,0,1);
gClrRect(&box,G_TRMODE_INV);
}
LOCAL_C VOID ToggleSelectBox(VOID)
{
P_RECT box;
GetSelectRegion(&box);
gDrawBox(&box);
}
LOCAL_C VOID ToggleCursor(VOID)
{
P_RECT box;
if (show_cursor)
{
GetCursorBox(&box);
ToggleHorizCurs(&box,TOP_CURSOR_Y,1);
ToggleHorizCurs(&box,BOTTOM_CURSOR_Y,-1);
ToggleVertCurs(&box,LEFT_CURSOR_X,1);
ToggleVertCurs(&box,RIGHT_CURSOR_X,-1);
MakeCursorFlash(&box);
if (issel)
ToggleSelectBox();
}
}
LOCAL_C VOID DrawSmallIcon(VOID)
{
P_POINT offset;
P_RECT size;
offset.x=SMALL_ICON_X;
offset.y=SMALL_ICON_Y;
size.tl.x=size.tl.y=0;
size.br.x=SMALL_ICON_WIDTH;
size.br.y=SMALL_ICON_HEIGHT;
gCopyBit(&offset,bid,&size,G_TRMODE_REPL);
}
LOCAL_C VOID DrawLargeIcon(VOID)
{
ULONG bits[2];
P_POINT log;
P_RECT box;
INT j;
log.x=0;
box.tl.y=LARGE_ICON_Y;
for (log.y=0; log.y<ICON_SIZE; log.y++)
{
gPeekBit(bid,&log,ICON_SIZE,&bits[0]);
box.br.y=box.tl.y+LARGE_ICON_SCALE;
box.tl.x=LARGE_ICON_X;
for (j=0; j<ICON_SIZE; j++)
{
box.br.x=box.tl.x+LARGE_ICON_SCALE;
gClrRect(&box,(bits[0]&(1L<<j))? G_TRMODE_SET: G_TRMODE_CLR);
box.tl.x=box.br.x;
}
box.tl.y=box.br.y;
}
}
LOCAL_C VOID DrawIcons(VOID)
{
DrawSmallIcon();
DrawLargeIcon();
}
LOCAL_C VOID SetupFilename(TEXT *pb)
{
p_bcpy(pb+1,DatUsedPathNamePtr,*pb=p_slen(DatUsedPathNamePtr));
}
LOCAL_C INT TryOpenIconFile(TEXT *newname,VOID **pfcb)
{
INT newbid;
P_POINT size;
INT ret;
newbid=gOpenBit(newname,0,WS_BIT_WRITE,&size);
if (newbid<0)
uErrorValue(newbid);
else if (size.x!=ICON_SIZE || size.y!=ICON_SIZE)
{
uErrorString("File has wrong size of icon");
wFree(newbid);
newbid=0;
}
else if ((ret=p_open(pfcb,newname,P_FOPEN))<0)
{
uErrorValue(ret);
wFree(newbid);
newbid=0;
}
return(newbid);
}
LOCAL_C VOID RestartDisplay(VOID)
{
changed=FALSE;
DrawIcons();
curs.x=curs.y=0;
issel=FALSE;
ToggleCursor();
WriteCursorText();
}
LOCAL_C VOID RetryOrExit(TEXT *message)
{
uForceToFront();
DatLocked=TRUE;
if (!wsAlertW(WS_ALERT_CLIENT,0,message,"Terminate","Retry",0))
p_exit(0);
DatLocked=FALSE;
}
LOCAL_C VOID ChangeName(TEXT *newname)
{
p_scpy(&filename[0],newname);
hSetUpStatusNames(&filename[0]);
wsUpdate(WS_UPDATE_NAME);
}
LOCAL_C VOID DoSave(TEXT *savename,INT usenew)
{
INT ret;
p_close(fcb);
while ((ret=gSaveBit(savename,bid))!=0)
{
uErrorValue(ret);
RetryOrExit("Failed to save icon");
}
if (usenew)
{
ChangeName(savename);
changed=FALSE;
}
while (p_open(&fcb,DatUsedPathNamePtr,P_FOPEN))
RetryOrExit("No memory to continue");
}
LOCAL_C VOID SaveIfChanged(VOID)
{
if (changed)
{
DoSave(DatUsedPathNamePtr,FALSE);
changed=FALSE;
}
}
LOCAL_C VOID ChangeOverTo(INT newbid,VOID *newfcb,TEXT *newname)
{
wFree(bid);
bid=newbid;
p_close(fcb);
fcb=newfcb;
ChangeName(newname);
ToggleCursor();
RestartDisplay();
}
LOCAL_C VOID OpenIconFile(VOID)
{
H_DI_FSEL open;
TEXT openbuf[P_FNAMESIZE+2];
INT newbid;
VOID *newfcb;
SetupFilename(open.fname=(&openbuf[0]));
open.flags=H_FILE_PICK_SELECTOR|H_FILE_RESTRICT_LIST|H_FILE_SET_DEFEXT;
do
{
if (uOpenDialog("Open icon file"))
return;
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&open))
return;
if (RunDialog()<=0)
return;
SaveIfChanged();
openbuf[1+openbuf[0]]=0;
newbid=TryOpenIconFile(&openbuf[1],&newfcb);
} while (newbid<=0);
ChangeOverTo(newbid,newfcb,&openbuf[1]);
}
LOCAL_C INT AddNoYesChoice(TEXT *prompt,UWORD *nsel)
{
return(uAddChoiceList(prompt,nsel,"No","Yes",NULL));
}
LOCAL_C VOID SaveIconAs(VOID)
{
H_DI_FSEL save;
TEXT savebuf[P_FNAMESIZE+2];
UWORD usenew;
if (uOpenDialog("Save icon as"))
return;
SetupFilename(save.fname=(&savebuf[0]));
save.flags=H_FILE_NEW_EDITOR|H_FILE_SET_DEFEXT;
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&save))
return;
usenew=1;
if (AddNoYesChoice("Use new file",&usenew))
return;
if (RunDialog())
{
savebuf[1+savebuf[0]]=0;
hEnsurePath(&savebuf[1]);
DoSave(&savebuf[1],usenew==2);
wInfoMsg("Saved");
}
}
LOCAL_C VOID SaveIcon(VOID)
{
if (!changed)
wInfoMsg("Not changed");
else
{
DoSave(DatUsedPathNamePtr,FALSE);
wInfoMsg("Saved");
changed=FALSE;
}
}
LOCAL_C VOID TryToRevert(VOID)
{
INT newbid;
p_close(fcb);
while ((newbid=TryOpenIconFile(DatUsedPathNamePtr,&fcb))<=0)
RetryOrExit("Revert has failed");
wFree(bid);
bid=newbid;
ToggleCursor();
RestartDisplay();
}
LOCAL_C INT AddNoYesButs(VOID)
{
return(uAddButtonList("No",-'n',"Yes",'y',0));
}
LOCAL_C INT UserConfirms(TEXT *message)
{
if (uOpenDialog(message) || AddNoYesButs())
return(0);
return(uRunDialog()=='y');
}
LOCAL_C INT CheckUserConfirms(TEXT *message)
{
return(require_query? UserConfirms(message): TRUE);
}
LOCAL_C VOID RevertIfConfirmed(VOID)
{
if (!changed)
{
wInfoMsg("Not changed");
return;
}
if (UserConfirms("Revert to saved"))
TryToRevert();
}
LOCAL_C VOID ToggleFrame(VOID)
{
P_RECT box;
box.tl.x=LARGE_ICON_X-1;
box.tl.y=LARGE_ICON_Y-1;
box.br.x=LARGE_ICON_X+ICON_SIZE*LARGE_ICON_SCALE+1;
box.br.y=LARGE_ICON_Y+ICON_SIZE*LARGE_ICON_SCALE+1;
gDrawBox(&box);
cmds[FRAME_ITEM]=((show_frame^=TRUE)? "fFrame off": "fFrame on");
}
LOCAL_C VOID ToggleStatusWindow(VOID)
{
if (show_statwin^=TRUE)
wsEnable();
else
wsDisable();
}
LOCAL_C INT TryNewIconFile(TEXT *newname,VOID **pfcb)
{
INT newbid;
P_RECT rect;
INT ret;
hEnsurePath(newname);
rect.tl.x=rect.tl.y=0;
rect.br.x=rect.br.y=ICON_SIZE;
newbid=gCreateBit(0,&rect.br);
if (newbid<0)
uErrorValue(newbid);
else
{
gCreateTempGC0(newbid);
gClrRect(&rect,G_TRMODE_CLR);
gFreeTempGC();
ret=gSaveBit(newname,newbid);
if (ret!=0 || (ret=p_open(pfcb,newname,P_FOPEN))<0)
{
uErrorValue(ret);
wFree(newbid);
newbid=0;
}
else
changed=FALSE;
}
return(newbid);
}
LOCAL_C VOID NewIconFile(VOID)
{
H_DI_FSEL new;
TEXT newbuf[P_FNAMESIZE+2];
INT newbid;
VOID *newfcb;
SetupFilename(new.fname=(&newbuf[0]));
new.flags=H_FILE_NEW_EDITOR|H_FILE_SET_DEFEXT;
do
{
if (uOpenDialog("New icon"))
return;
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&new))
return;
if (RunDialog()<=0)
return;
SaveIfChanged();
newbuf[1+newbuf[0]]=0;
newbid=TryNewIconFile(&newbuf[1],&newfcb);
} while (newbid<=0);
ChangeOverTo(newbid,newfcb,&newbuf[1]);
}
LOCAL_C VOID ExitApplication(VOID)
{
SaveIfChanged();
p_exit(0);
}
LOCAL_C VOID GetWholeIcon(P_RECT *pbox)
{
pbox->tl.x=pbox->tl.y=0;
pbox->br.x=pbox->br.y=ICON_SIZE;
}
LOCAL_C VOID InvertOrGrey(VOID)
{
INT keycode;
P_RECT box;
if (uOpenDialog(issel? "Plaster selection": "Plaster whole icon"))
return;
if (uAddButtonList("Cancel",W_KEY_ESCAPE,"Grey",'g',"Invert",'i',NULL))
return;
if (!(keycode=RunDialog()))
return;
if (!issel)
GetWholeIcon(&box);
else
{
ToggleSelectBox();
GetSmallSelectRegion(&box);
}
gCreateTempGC0(bid);
if (keycode=='i')
gClrRect(&box,G_TRMODE_INV);
else
gFillPattern(&box,WS_BITMAP_GREY,G_TRMODE_INV);
changed=TRUE;
gFreeTempGC();
DrawIcons();
if (issel)
ToggleSelectBox();
}
LOCAL_C VOID ToggleCursorVisibility(VOID)
{
cmds[CURSOR_ITEM]=(show_cursor? "kCursor on": "kCursor off");
if (show_cursor)
{
ToggleCursor();
show_cursor=FALSE;
wEraseTextCursor();
}
else
{
show_cursor=TRUE;
ToggleCursor();
}
}
LOCAL_C VOID WriteText(VOID)
{
H_DI_EDIT edit;
G_GC gc;
INT gcflags;
if (uOpenDialog("Write text"))
return;
edit.str=(&ToWrite[0]);
edit.len=9;
if (uAddDialogItem(H_DIALOG_EDIT,"Text",&edit))
return;
if (uAddChoiceList("Font",&font,"Standard","Bold","Small digits",NULL))
return;
if (AddNoYesChoice("Italic",&italic))
return;
if (RunDialog()<=0)
return;
gCreateTempGC0(bid);
gcflags=G_GC_MASK_TEXTMODE|G_GC_MASK_FONT;
gc.textmode=brush;
gc.font=WS_FONT_BASE+font-1;
if (italic==2)
{
gcflags|=G_GC_MASK_STYLE;
gc.style=G_STY_ITALIC;
}
gSetGC(0,gcflags,&gc);
gPrintText(curs.x,curs.y,&ToWrite[1],ToWrite[0]);
changed=TRUE;
gFreeTempGC();
DrawIcons();
}
LOCAL_C VOID DrawBorder(VOID)
{
INT bflags;
G_GC gc;
if (uOpenDialog("Draw border"))
return;
if (uAddChoiceList("Corner",&BordCorner,"Simple","Gentle","Round",NULL))
return;
if (uAddChoiceList("Shadow",&BordShadow,"None","Single","Double",NULL))
return;
if (AddNoYesChoice("Cushion",&BordCushion))
return;
if (RunDialog()<=0)
return;
gc.gmode=brush;
gCreateTempGC(bid,G_GC_MASK_GMODE,&gc);
bflags=W_BORD_SHADOW_ON;
if (BordCorner==1)
bflags|=W_BORD_CORNER_1;
else if (BordCorner==3)
bflags|=W_BORD_CORNER_4;
if (BordShadow==2)
bflags|=W_BORD_SHADOW_S;
else if (BordShadow==3)
bflags|=W_BORD_SHADOW_D;
if (BordCushion==2)
bflags|=W_BORD_CUSHION;
gBorder(bflags);
changed=TRUE;
gFreeTempGC();
DrawIcons();
}
LOCAL_C VOID ChangeClipboardUsed(VOID)
{
if (uOpenDialog("Use"))
return;
if (uAddChoiceList("Clipboard",&using,"1","2","3","4",NULL))
return;
if (RunDialog()<=0)
return;
WriteClipboardText();
}
LOCAL_C VOID CancelSelect(VOID)
{
ToggleSelectBox();
issel=FALSE;
WriteCursorText();
}
LOCAL_C VOID CheckIfSelectStatusChanging(VOID)
{
if (!(key.modifiers&W_SHIFT_MODIFIER))
issel=FALSE;
else if (!issel)
{
issel=TRUE;
anch=curs;
}
}
LOCAL_C VOID CheckForNullSelect(VOID)
{
if (anch.x==curs.x && anch.y==curs.y)
issel=FALSE;
}
LOCAL_C VOID MoveCursorAbsolute(INT newx,INT newy)
{
ToggleCursor();
CheckIfSelectStatusChanging();
if (newx>=0)
curs.x=newx;
if (newy>=0)
curs.y=newy;
CheckForNullSelect();
ToggleCursor();
WriteCursorText();
}
LOCAL_C VOID RepositionCursor(VOID)
{
H_DI_NUMBER posx;
H_DI_NUMBER posy;
LONG curx;
LONG cury;
UWORD extend;
curx=curs.x;
cury=curs.y;
posx.low=0;
posx.high=23;
posx.value=(&curx);
posy.low=0;
posy.high=23;
posy.value=(&cury);
extend=(issel? 2: 1);
if (uOpenDialog("Go to"))
return;
if (uAddDialogItem(H_DIALOG_NUMBER,"Cursor x",&posx))
return;
if (uAddDialogItem(H_DIALOG_NUMBER,"Cursor y",&posy))
return;
if (AddNoYesChoice("Extend select",&extend))
return;
if (RunDialog()<=0)
return;
key.modifiers=(extend==2? W_SHIFT_MODIFIER: 0);
MoveCursorAbsolute((INT)curx,(INT)cury);
}
LOCAL_C VOID FlashHighlightRegion(VOID)
{
P_RECT select;
if (!issel)
{
wInfoMsg("No select region");
return;
}
GetSelectRegion(&select);
wInfoMsgCorner("Showing select region",W_CORNER_TOP_LEFT);
gFillPattern(&select,WS_BITMAP_GREY,G_TRMODE_INV);
wFlush();
p_sleep(20L);
gFillPattern(&select,WS_BITMAP_GREY,G_TRMODE_INV);
}
LOCAL_C INT DoCopy(P_RECT *prect,INT clipindex)
{
P_POINT size;
P_POINT origin;
INT newclipbid;
size.x=prect->br.x-prect->tl.x;
size.y=prect->br.y-prect->tl.y;
newclipbid=gCreateBit(0,&size);
if (newclipbid<0)
{
uErrorValue(newclipbid);
return(-1);
}
gCreateTempGC0(newclipbid);
origin.x=origin.y=0;
gCopyBit(&origin,bid,prect,G_TRMODE_REPL);
gFreeTempGC();
wFree(clipbid[clipindex]);
clipbid[clipindex]=newclipbid;
clipsize[clipindex]=size;
return(0);
}
LOCAL_C VOID CopyToClipboard(VOID)
{
P_RECT rect;
if (issel)
{
if (!CheckUserConfirms("Copy select region to clipboard"))
return;
GetSmallSelectRegion(&rect);
}
else
{
if (!CheckUserConfirms("Copy whole icon to clipboard"))
return;
GetWholeIcon(&rect);
}
if (DoCopy(&rect,using))
return;
wInfoMsg("Copied");
}
LOCAL_C VOID DoDelete(P_RECT *prect)
{
gCreateTempGC0(bid);
gClrRect(prect,G_TRMODE_CLR);
gFreeTempGC();
}
LOCAL_C VOID CutToClipboard(VOID)
{
P_RECT rect;
if (issel)
{
if (!CheckUserConfirms("Cut select region into clipboard"))
return;
GetSmallSelectRegion(&rect);
}
else
{
if (!CheckUserConfirms("Cut whole icon into clipboard"))
return;
GetWholeIcon(&rect);
}
if (DoCopy(&rect,using))
return;
key.modifiers=0;
MoveCursorAbsolute(rect.tl.x,rect.tl.y);
DoDelete(&rect);
changed=TRUE;
DrawIcons();
}
LOCAL_C VOID DoInsert(P_POINT *target,INT clipindex,INT mode)
{
P_RECT rect;
rect.tl.x=rect.tl.y=0;
rect.br.x=clipsize[clipindex].x;
rect.br.y=clipsize[clipindex].y;
gCreateTempGC0(bid);
gCopyBit(target,clipbid[clipindex],&rect,mode);
gFreeTempGC();
}
LOCAL_C VOID InsertFromClipboard(VOID)
{
if (!clipbid[using])
{
wInfoMsg("Current clipboard is empty");
return;
}
if (!CheckUserConfirms("Insert from clipboard"))
return;
if (issel)
CancelSelect();
DoInsert(&curs,using,brush);
DrawIcons();
changed=TRUE;
}
LOCAL_C VOID ConsiderInterrogation(VOID)
{
UWORD nsel;
if (uOpenDialog("Before cut/copy/insert"))
return;
nsel=(require_query? 2: 1);
if (AddNoYesChoice("Request confirmation",&nsel))
return;
if (RunDialog()<=0)
return;
require_query=(nsel==2);
}
LOCAL_C VOID ResetStateBeforeMove(VOID)
{
P_POINT origin;
origin.x=origin.y=0;
DoInsert(&origin,MOVE_BACKUP,G_TRMODE_REPL);
}
LOCAL_C VOID MoveBy(INT offx,INT offy)
{
if (issel || !MoveSingle)
ResetStateBeforeMove();
if (MoveSingle)
DoDelete(&moveorigin);
p_offrec(&movedto,offx,offy);
DoInsert(&movedto.tl,MOVE_RAFT,G_TRMODE_REPL);
MoveUpdatePending=TRUE;
}
LOCAL_C VOID EnterMoveState(VOID)
{
TEXT *title;
INT keycode;
GetWholeIcon(&moveorigin);
if (DoCopy(&moveorigin,MOVE_BACKUP))
return;
if (issel)
{
title="Move select region";
GetSmallSelectRegion(&moveorigin);
}
else
title="Move whole icon";
if (uOpenDialog(title))
goto TidyUp;
if (uAddButtonList("Single copy",'s',"Double copy",'d',NULL))
goto TidyUp;
if (!(keycode=RunDialog()))
goto TidyUp;
MoveSingle=(keycode=='s');
if (DoCopy(&moveorigin,MOVE_RAFT))
goto TidyUp;
movedto=moveorigin;
ToggleCursor();
wEraseTextCursor();
DatLocked=TRUE;
wSetBusyMsg("Moving",W_CORNER_BOTTOM_LEFT);
MoveUpdatePending=FALSE;
FOREVER
{
uGetKey(&key);
switch (key.keycode)
{
case W_KEY_UP:
MoveBy(0,-1);
break;
case W_KEY_DOWN:
MoveBy(0,1);
break;
case W_KEY_LEFT:
MoveBy(-1,0);
break;
case W_KEY_RIGHT:
MoveBy(1,0);
break;
case W_KEY_ESCAPE:
ResetStateBeforeMove();
DrawIcons();
goto ExitMoveState;
case W_KEY_RETURN:
changed=TRUE;
goto ExitMoveState;
default:
p_sound(-5,320);
wInfoMsg("ENTER or ESC exits `Moving'");
}
if (MoveUpdatePending && !uKeyPressOutstanding())
{
DrawIcons();
MoveUpdatePending=FALSE;
}
}
ExitMoveState:
DatLocked=FALSE;
ToggleCursor();
wCancelBusyMsg();
wFree(clipbid[MOVE_RAFT]);
clipbid[MOVE_RAFT]=0;
TidyUp:
wFree(clipbid[MOVE_BACKUP]);
clipbid[MOVE_BACKUP]=0;
}
LOCAL_C INT IncrementAndFix(INT value,INT delta)
{
value+=delta;
if (value<0)
value+=ICON_SIZE;
else if (value>=ICON_SIZE)
value-=ICON_SIZE;
return(value);
}
LOCAL_C VOID AlterBit(INT gmode)
{
P_RECT box;
gCreateTempGC0(bid);
box.tl=curs;
box.br.x=curs.x+1;
box.br.y=curs.y+1;
gClrRect(&box,gmode);
changed=TRUE;
gFreeTempGC();
DrawSmallIcon();
ScaleUp(&box);
gClrRect(&box,gmode);
}
LOCAL_C VOID MoveCursorRelative(INT delx,INT dely)
{
if (key.modifiers&W_CTRL_MODIFIER)
AlterBit(brush);
ToggleCursor();
CheckIfSelectStatusChanging();
curs.x=IncrementAndFix(curs.x,delx);
curs.y=IncrementAndFix(curs.y,dely);
CheckForNullSelect();
ToggleCursor();
WriteCursorText();
}
LOCAL_C VOID ReduceScreenSize(VOID)
{
W_WINDATA wd;
wd.extent.tl.x=wd.extent.tl.y=0;
wd.extent.width=189;
wd.extent.height=80;
wSetWindow(MainWid,W_WIN_EXTENT,&wd);
if (uErrorValue(wCheckPoint()))
p_exit(0);
}
LOCAL_C INT ObeySystemCommand(INT cmd,TEXT *pb,VOID **newfcb)
{
return((cmd=='O'? TryOpenIconFile: TryNewIconFile)(pb,newfcb));
}
LOCAL_C VOID CreateGC(VOID)
{
G_GC gc;
INT hgc;
gc.gmode=G_TRMODE_INV;
hgc=gCreateGC(MainWid,G_GC_MASK_GMODE,&gc);
if (hgc<0)
p_exit(hgc);
}
LOCAL_C VOID SpecificInit(VOID)
{
INT command;
MainWid=uFindMainWid();
CreateGC();
ToggleFrame();
command=hCrackCommandLine();
bid=ObeySystemCommand(command,DatUsedPathNamePtr,&fcb);
if (bid<=0)
p_exit(0);
ReduceScreenSize();
ToggleStatusWindow();
RestartDisplay();
WriteBrushText();
WriteClipboardText();
wInfoMsg("Press `Help' for tips on usage");
}
LOCAL_C VOID ProcessSystemCommand(VOID)
{
TEXT buf[P_FNAMESIZE+2];
INT newbid;
VOID *newfcb;
wGetCommand((UBYTE *)&buf[0]);
if (buf[0]=='X')
ExitApplication();
SaveIfChanged();
newbid=ObeySystemCommand(buf[0],&buf[1],&newfcb);
if (newbid>0)
ChangeOverTo(newbid,newfcb,&buf[1]);
}
LOCAL_C VOID DisplayHelpText(VOID)
{
INT choice;
FOREVER
{
choice=uDialogMenu("Help on which topic",
"Cursor position",
"Select regions",
"Drawing lines",
"Brushes",
"Using clipboards",
"Borders and frames",NULL);
switch (choice)
{
case 0:
return;
case 2:
uDisplayText("To move the cursor:",
"use the usual cursor keys",
"including Home, End, PgUp and PgDn",
"or use `Goto' in the `Edit' menu.",
"Use Enter or Space to toggle the pixel",
"at the cursor position.",NULL);
break;
case 3:
uDisplayText("To create a select region:",
"use SHIFTed cursor keys.",
"To emphasise a select region:",
"use `Highlight' in the `Special' menu.",
"`Move', Delete, `Copy' and `Plaster'",
"all operate on the current select region.",NULL);
break;
case 4:
uDisplayText("To draw vertical or horizontal lines:",
"use the cursor keys plus CONTROL.",
"Lines are drawn in the current Brush.",NULL);
break;
case 5:
uDisplayText("The Brush setting affects:",
"horizontal and vertical lines drawn",
"borders drawn using `Border'",
"text written using `Write'",
"and contents inserted from clipboards.",
"`Toggle' is the most useful setting.",NULL);
break;
case 6:
uDisplayText("Choose between 4 clipboards with `Use'.",
"Cut into a clipboard with the Delete key.",
"To eliminate `Are you sure?' queries:",
"use `Interrogation' in the `Special' menu.",NULL);
break;
case 7:
uDisplayText("To apply one of many types of border:",
"use `Border' in the `Special' menu.",
"To hide or show a frame round the icon:",
"use `Frame' in the `Special' menu.",
"To control cursor indicators in the frame:",
"use `Cursor' in the `Special' menu.",NULL);
break;
}
}
}
LOCAL_C VOID ManageCommand(INT index)
{
switch (index)
{
case ITEMS_BEFORE_FILE:
NewIconFile();
break;
case ITEMS_BEFORE_FILE+1:
OpenIconFile();
break;
case ITEMS_BEFORE_FILE+2:
SaveIconAs();
break;
case ITEMS_BEFORE_FILE+3:
SaveIcon();
break;
case ITEMS_BEFORE_FILE+4:
RevertIfConfirmed();
break;
case ITEMS_BEFORE_FILE+5:
ExitApplication();
break;
case ITEMS_BEFORE_EDIT:
InsertFromClipboard();
break;
case ITEMS_BEFORE_EDIT+1:
CopyToClipboard();
break;
case ITEMS_BEFORE_EDIT+2:
ChangeClipboardUsed();
break;
case ITEMS_BEFORE_EDIT+3:
InvertOrGrey();
break;
case ITEMS_BEFORE_EDIT+4:
EnterMoveState();
break;
case ITEMS_BEFORE_EDIT+5:
RepositionCursor();
break;
case ITEMS_BEFORE_BRUSH:
case ITEMS_BEFORE_BRUSH+1:
case ITEMS_BEFORE_BRUSH+2:
brush=index-ITEMS_BEFORE_BRUSH;
WriteBrushText();
break;
case ITEMS_BEFORE_SPECIAL:
ToggleFrame();
break;
case ITEMS_BEFORE_SPECIAL+1:
ToggleCursorVisibility();
break;
case ITEMS_BEFORE_SPECIAL+2:
FlashHighlightRegion();
break;
case ITEMS_BEFORE_SPECIAL+3:
WriteText();
break;
case ITEMS_BEFORE_SPECIAL+4:
DrawBorder();
break;
case ITEMS_BEFORE_SPECIAL+5:
ConsiderInterrogation();
break;
}
}
LOCAL_C VOID TryExecuteCommand(INT keycode)
{
keycode=uLocateCommand(keycode);
if (keycode>=0)
ManageCommand(keycode);
}
LOCAL_C VOID MainLoop(VOID)
{
INT ret;
FOREVER
{
uGetKey(&key);
if (key.keycode&W_EVENT_KEY)
{
if (key.keycode==CONS_EVENT_COMMAND)
ProcessSystemCommand();
}
else if (key.keycode&W_SPECIAL_KEY)
TryExecuteCommand(key.keycode&(~W_SPECIAL_KEY));
else
{
switch (key.keycode)
{
case W_KEY_MENU:
if (key.modifiers&W_CTRL_MODIFIER)
ToggleStatusWindow();
else
{
ret=uPresentMenus();
if (ret>0)
TryExecuteCommand(ret);
}
break;
case W_KEY_RETURN:
case ' ':
AlterBit(G_TRMODE_INV);
break;
case W_KEY_LEFT:
MoveCursorRelative(-1,0);
break;
case W_KEY_RIGHT:
MoveCursorRelative(1,0);
break;
case W_KEY_UP:
MoveCursorRelative(0,-1);
break;
case W_KEY_DOWN:
MoveCursorRelative(0,1);
break;
case W_KEY_HOME:
MoveCursorAbsolute(0,-1);
break;
case W_KEY_END:
MoveCursorAbsolute(ICON_SIZE-1,-1);
break;
case W_KEY_PAGE_UP:
MoveCursorAbsolute(-1,0);
break;
case W_KEY_PAGE_DOWN:
MoveCursorAbsolute(-1,ICON_SIZE-1);
break;
case W_KEY_ESCAPE:
if (issel)
CancelSelect();
break;
case W_KEY_DELETE_LEFT:
CutToClipboard();
break;
case W_KEY_HELP:
DisplayHelpText();
}
}
}
}
GLDEF_C VOID main(VOID)
{
uCommonInit();
SpecificInit();
MainLoop();
}