397 lines
8.4 KiB
C
397 lines
8.4 KiB
C
#include <p_std.h>
|
|
#include <wlib.h>
|
|
|
|
#include "lined.h"
|
|
|
|
|
|
GLREF_D UINT wMainWid;
|
|
|
|
|
|
LOCAL_C INT CreateGC(LINED *ed)
|
|
{
|
|
G_GC gc;
|
|
|
|
if (ed->gc)
|
|
return(FALSE);
|
|
gc.font=ed->i.font;
|
|
gc.style=ed->i.style;
|
|
gCreateTempGC(ed->i.winid,G_GC_MASK_FONT|G_GC_MASK_STYLE,&gc);
|
|
ed->gc=TRUE;
|
|
return(TRUE);
|
|
}
|
|
|
|
LOCAL_C VOID FreeGC(LINED *ed,INT gc)
|
|
{
|
|
if (!gc)
|
|
return;
|
|
ed->gc=FALSE;
|
|
gFreeTempGC();
|
|
}
|
|
|
|
LOCAL_C INT WidthTo(LINED *ed,INT blen)
|
|
{
|
|
return(gTextWidth(ed->i.font,ed->i.style,ed->pb,blen));
|
|
}
|
|
|
|
LOCAL_C VOID GetBox(LINED *ed,P_RECT *pbox)
|
|
{
|
|
pbox->tl.x=ed->i.xoff;
|
|
pbox->tl.y=ed->i.yoff;
|
|
pbox->br.x=pbox->tl.x+ed->i.width;
|
|
pbox->br.y=pbox->tl.y+ed->i.height;
|
|
}
|
|
|
|
LOCAL_C VOID DrawCursor(LINED *ed)
|
|
{
|
|
W_CURSOR flash;
|
|
|
|
flash.pos.x=ed->i.xoff+ed->marg+WidthTo(ed,ed->cur);
|
|
flash.pos.y=ed->i.yoff+ed->i.asc;
|
|
flash.height=ed->i.height;
|
|
flash.ascent=ed->i.asc;
|
|
flash.width=ed->cwidth;
|
|
flash.flags=0;
|
|
wTextCursor(ed->i.winid,&flash);
|
|
}
|
|
|
|
LOCAL_C VOID ToggleHighlight(LINED *ed)
|
|
{
|
|
P_RECT box;
|
|
INT gc;
|
|
|
|
if (ed->select)
|
|
{
|
|
gc=CreateGC(ed);
|
|
GetBox(ed,&box);
|
|
box.br.x=box.tl.x+ed->marg+WidthTo(ed,ed->blen);
|
|
gClrRect(&box,G_TRMODE_INV);
|
|
FreeGC(ed,gc);
|
|
}
|
|
}
|
|
|
|
LOCAL_C VOID DrawAll(LINED *ed)
|
|
{
|
|
P_RECT box;
|
|
INT gc;
|
|
|
|
GetBox(ed,&box);
|
|
gc=CreateGC(ed);
|
|
gPrintBoxText(&box,ed->i.asc,G_TEXT_ALIGN_LEFT,ed->marg,ed->pb,ed->blen);
|
|
if (ed->emph)
|
|
{
|
|
DrawCursor(ed);
|
|
ToggleHighlight(ed);
|
|
}
|
|
FreeGC(ed,gc);
|
|
}
|
|
|
|
GLDEF_C VOID le_destroy(LINED *ed)
|
|
{
|
|
p_free(ed->pb);
|
|
p_free(ed);
|
|
}
|
|
|
|
GLDEF_C LINED *le_init(IN_LINED *pin)
|
|
{
|
|
LINED *ed;
|
|
|
|
ed=p_alloc(sizeof(LINED));
|
|
if (!ed)
|
|
return(NULL);
|
|
p_bfil(ed,sizeof(LINED),0);
|
|
ed->cwidth=2;
|
|
ed->pb=p_alloc(pin->maxchars+1);
|
|
if (!ed->pb)
|
|
{
|
|
p_free(ed);
|
|
return(NULL);
|
|
}
|
|
ed->i=(*pin);
|
|
ed->lmarg=ed->i.width/4;
|
|
return(ed);
|
|
}
|
|
|
|
LOCAL_C VOID ScrollForCursor(LINED *ed,INT draw)
|
|
{
|
|
INT oldmarg;
|
|
INT curx;
|
|
INT exx;
|
|
INT exl;
|
|
INT exr;
|
|
|
|
oldmarg=ed->marg;
|
|
curx=WidthTo(ed,ed->cur);
|
|
exx=curx+ed->marg;
|
|
exl=exx-ed->lmarg;
|
|
exr=exx+ed->cwidth-ed->i.width;
|
|
if (exl<0 && ed->marg)
|
|
{
|
|
ed->marg-=exl-ed->scrollx;
|
|
if (ed->marg>0)
|
|
ed->marg=0;
|
|
}
|
|
else if (exr>0)
|
|
ed->marg-=exr+ed->scrollx;
|
|
if (ed->marg!=oldmarg && draw)
|
|
DrawAll(ed);
|
|
}
|
|
|
|
GLDEF_C VOID le_set_text(LINED *ed,INT blen,TEXT *pb)
|
|
{
|
|
*(p_bcpy(ed->pb,pb,blen))=0;
|
|
ed->blen=blen;
|
|
ed->marg=0;
|
|
ed->select=FALSE;
|
|
ed->cur=0;
|
|
if (ed->i.autoselect && blen)
|
|
{
|
|
ed->cur=blen;
|
|
ed->select=TRUE;
|
|
ScrollForCursor(ed,FALSE);
|
|
}
|
|
if (ed->visible)
|
|
DrawAll(ed);
|
|
}
|
|
|
|
LOCAL_C VOID DelSelRange(LINED *ed)
|
|
{
|
|
ed->select=FALSE;
|
|
ed->cur=0;
|
|
ed->marg=0;
|
|
ed->blen=0;
|
|
*ed->pb=0;
|
|
}
|
|
|
|
LOCAL_C VOID DoDelete(LINED *ed,INT modifier)
|
|
{
|
|
INT start;
|
|
INT finish;
|
|
|
|
if (ed->select)
|
|
DelSelRange(ed);
|
|
else
|
|
{
|
|
if (modifier&W_SHIFT_MODIFIER)
|
|
{
|
|
if (ed->cur==ed->blen)
|
|
return;
|
|
}
|
|
else if (!ed->cur)
|
|
return;
|
|
start=finish=ed->cur;
|
|
switch (modifier)
|
|
{
|
|
case W_SHIFT_MODIFIER:
|
|
finish++;
|
|
break;
|
|
case W_PSION_MODIFIER:
|
|
finish=ed->blen;
|
|
break;
|
|
default:
|
|
start--;
|
|
}
|
|
p_bcpy(ed->pb+start,ed->pb+finish,ed->blen+1-finish);
|
|
ed->blen-=finish-start;
|
|
ed->cur=start;
|
|
ScrollForCursor(ed,FALSE);
|
|
}
|
|
DrawAll(ed);
|
|
}
|
|
|
|
LOCAL_C VOID LoseHighlight(LINED *ed)
|
|
{
|
|
ToggleHighlight(ed);
|
|
ed->select=FALSE;
|
|
}
|
|
|
|
LOCAL_C VOID DisplayCursor(LINED *ed)
|
|
{
|
|
ScrollForCursor(ed,TRUE);
|
|
DrawCursor(ed);
|
|
}
|
|
|
|
GLDEF_C INT le_key(LINED *ed,INT keycode,INT modifier)
|
|
{
|
|
TEXT *pb;
|
|
|
|
if (keycode<0x100 && p_isprint(keycode))
|
|
{
|
|
if (ed->select)
|
|
DelSelRange(ed);
|
|
if (ed->blen==ed->i.maxchars)
|
|
{
|
|
p_sound(-5,320);
|
|
return(-1);
|
|
}
|
|
pb=ed->pb+ed->cur;
|
|
p_bcpy(pb+1,pb,ed->blen+1-ed->cur);
|
|
*pb=keycode;
|
|
(ed->blen)++;
|
|
(ed->cur)++;
|
|
ScrollForCursor(ed,FALSE);
|
|
DrawAll(ed);
|
|
return(0);
|
|
}
|
|
if (keycode==W_KEY_DELETE_LEFT || keycode==W_KEY_DELETE_RIGHT)
|
|
DoDelete(ed,modifier);
|
|
else
|
|
{
|
|
switch (keycode)
|
|
{
|
|
case W_KEY_LEFT:
|
|
if (ed->select)
|
|
{
|
|
LoseHighlight(ed);
|
|
ed->cur=0;
|
|
}
|
|
else if (!ed->cur)
|
|
return(0);
|
|
else
|
|
{
|
|
if (modifier&W_PSION_MODIFIER)
|
|
ed->cur=0;
|
|
else
|
|
(ed->cur)--;
|
|
}
|
|
DisplayCursor(ed);
|
|
break;
|
|
case W_KEY_RIGHT:
|
|
if (ed->select)
|
|
{
|
|
LoseHighlight(ed);
|
|
ed->cur=ed->blen;
|
|
}
|
|
else if (ed->cur==ed->blen)
|
|
return(0);
|
|
else
|
|
{
|
|
if (modifier&W_PSION_MODIFIER)
|
|
ed->cur=ed->blen;
|
|
else
|
|
(ed->cur)++;
|
|
}
|
|
DisplayCursor(ed);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
GLDEF_C VOID le_emphasise(LINED *ed,INT emph)
|
|
{
|
|
if (emph)
|
|
emph=TRUE;
|
|
if (ed->emph==emph)
|
|
return;
|
|
ed->emph=emph;
|
|
if (!ed->visible)
|
|
return;
|
|
DrawAll(ed);
|
|
if (!emph)
|
|
wEraseTextCursor();
|
|
}
|
|
|
|
GLDEF_C VOID le_set_cwidth(LINED *ed,INT cwidth)
|
|
{
|
|
ed->cwidth=cwidth;
|
|
if (ed->visible && ed->emph)
|
|
{
|
|
if (cwidth)
|
|
DrawCursor(ed);
|
|
else
|
|
wEraseTextCursor();
|
|
}
|
|
}
|
|
|
|
GLDEF_C VOID le_visible(LINED *ed,INT visible)
|
|
{
|
|
P_RECT box;
|
|
INT gc;
|
|
|
|
if (visible)
|
|
visible=TRUE;
|
|
if (ed->visible==visible)
|
|
return;
|
|
ed->visible=visible;
|
|
if (visible)
|
|
DrawAll(ed);
|
|
else
|
|
{
|
|
GetBox(ed,&box);
|
|
gc=CreateGC(ed);
|
|
gClrRect(&box,G_TRMODE_CLR);
|
|
FreeGC(ed,gc);
|
|
}
|
|
}
|
|
|
|
|
|
/************************** TEST CODE FOLLOWS ***********************/
|
|
|
|
|
|
LOCAL_C LINED *CreateLined(INT yoff,TEXT *msg,INT emph)
|
|
{
|
|
IN_LINED init;
|
|
LINED *ed;
|
|
|
|
init.maxchars=20;
|
|
init.winid=wMainWid;
|
|
init.xoff=10;
|
|
init.yoff=yoff;
|
|
init.width=80;
|
|
init.height=10;
|
|
init.asc=8;
|
|
init.font=WS_FONT_BASE+4;
|
|
init.style=0;
|
|
init.autoselect=TRUE;
|
|
ed=le_init(&init);
|
|
le_set_text(ed,p_slen(msg),msg);
|
|
le_emphasise(ed,emph);
|
|
le_visible(ed,TRUE);
|
|
return(ed);
|
|
}
|
|
|
|
GLDEF_C VOID main(VOID)
|
|
{
|
|
LINED *ed[3];
|
|
INT which;
|
|
WS_EV event;
|
|
INT keycode;
|
|
|
|
wStartup();
|
|
gBorder(W_BORD_CORNER_4);
|
|
ed[0]=CreateLined(10,"One",TRUE);
|
|
ed[1]=CreateLined(30,"Two",FALSE);
|
|
ed[2]=CreateLined(50,"Three",FALSE);
|
|
which=0;
|
|
FOREVER
|
|
{
|
|
do
|
|
{
|
|
wGetEventWait(&event);
|
|
} while (event.type!=WM_KEY);
|
|
keycode=event.p.key.keycode&(~W_SPECIAL_KEY);
|
|
switch (keycode)
|
|
{
|
|
case W_KEY_ESCAPE:
|
|
if (event.p.key.modifiers==W_PSION_MODIFIER)
|
|
p_exit(0);
|
|
case W_KEY_UP:
|
|
if (which)
|
|
{
|
|
le_emphasise(ed[which--],FALSE);
|
|
le_emphasise(ed[which],TRUE);
|
|
}
|
|
break;
|
|
case W_KEY_DOWN:
|
|
if (which<2)
|
|
{
|
|
le_emphasise(ed[which++],FALSE);
|
|
le_emphasise(ed[which],TRUE);
|
|
}
|
|
break;
|
|
default:
|
|
le_key(ed[which],keycode,event.p.key.modifiers);
|
|
}
|
|
}
|
|
}
|
|
|