xenocara/app/fvwm/extras/FvwmScript/Widgets/TextField.c

410 lines
12 KiB
C

#include "Tools.h"
/***********************************************/
/* Fonction for TextField */
/***********************************************/
void InitTextField(struct XObj *xobj)
{
unsigned long mask;
XSetWindowAttributes Attr;
int i;
int asc,desc,dir;
XCharStruct struc;
/* Enregistrement des couleurs et de la police */
MyAllocNamedColor(xobj->display,*xobj->colormap,xobj->forecolor,&xobj->TabColor[fore]);
MyAllocNamedColor(xobj->display,*xobj->colormap,xobj->backcolor,&xobj->TabColor[back]);
MyAllocNamedColor(xobj->display,*xobj->colormap,xobj->licolor,&xobj->TabColor[li]);
MyAllocNamedColor(xobj->display,*xobj->colormap,xobj->shadcolor,&xobj->TabColor[shad]);
MyAllocNamedColor(xobj->display,*xobj->colormap,"#000000",&xobj->TabColor[black]);
MyAllocNamedColor(xobj->display,*xobj->colormap,"#FFFFFF",&xobj->TabColor[white]);
mask=0;
Attr.cursor=XCreateFontCursor(xobj->display,XC_xterm);
mask|=CWCursor; /* Curseur pour la fenetre */
Attr.background_pixel=xobj->TabColor[back].pixel;
mask|=CWBackPixel;
xobj->win=XCreateWindow(xobj->display,*xobj->ParentWin,
xobj->x,xobj->y,xobj->width,xobj->height,0,
CopyFromParent,InputOutput,CopyFromParent,
mask,&Attr);
xobj->gc=XCreateGC(xobj->display,xobj->win,0,NULL);
XSetForeground(xobj->display,xobj->gc,xobj->TabColor[fore].pixel);
XSetBackground(xobj->display,xobj->gc,xobj->TabColor[back].pixel);
if ((xobj->xfont=XLoadQueryFont(xobj->display,xobj->font))==NULL)
fprintf(stderr,"Can't load font %s\n",xobj->font);
else
XSetFont(xobj->display,xobj->gc,xobj->xfont->fid);
XSetLineAttributes(xobj->display,xobj->gc,1,LineSolid,CapRound,JoinMiter);
/* value2 représente la fin de la zone selectionnee */
if (xobj->value>strlen(xobj->title))
xobj->value=strlen(xobj->title);
xobj->value2=xobj->value;
/* Redimensionnement du widget */
XTextExtents(xobj->xfont,"lp",strlen("lp"),&dir,&asc,&desc,&struc);
xobj->height=asc+desc+10;
i=XTextWidth(xobj->xfont,xobj->title,strlen(xobj->title))+40;
if (xobj->width<i)
xobj->width=i;
XResizeWindow(xobj->display,xobj->win,xobj->width,xobj->height);
}
void DestroyTextField(struct XObj *xobj)
{
XFreeFont(xobj->display,xobj->xfont);
XFreeGC(xobj->display,xobj->gc);
XDestroyWindow(xobj->display,xobj->win);
}
/* Dessin du curseur du texte */
void DrawPointTxt(struct XObj *xobj,unsigned int color)
{
#define dec 2
int x,y;
XSegment segm[2];
int asc,desc,dir;
XCharStruct struc;
XTextExtents(xobj->xfont,"lp",strlen("lp"),&dir,&asc,&desc,&struc);
x=XTextWidth(xobj->xfont,xobj->title,xobj->value)+5;
y=asc+5;
segm[0].x1=x;
segm[0].y1=y;
segm[0].x2=x-dec;
segm[0].y2=y+dec;
segm[1].x1=x;
segm[1].y1=y;
segm[1].x2=x+dec;
segm[1].y2=y+dec;
XSetForeground(xobj->display,xobj->gc,color);
XDrawSegments(xobj->display,xobj->win,xobj->gc,segm,2);
}
/* Dessin du contenu du champs texte */
void DrawTextField(struct XObj *xobj)
{
int x1,y1;
int x2,l;
int desc,dir,asc;
XCharStruct struc;
l=strlen(xobj->title);
if (xobj->value>l)
xobj->value=l;
if (xobj->value2>l)
xobj->value2=l;
DrawReliefRect(0,0,xobj->width,xobj->height,xobj,
xobj->TabColor[shad].pixel,xobj->TabColor[li].pixel,xobj->TabColor[black].pixel,1);
XSetForeground(xobj->display,xobj->gc,xobj->TabColor[back].pixel);
XFillRectangle(xobj->display,xobj->win,xobj->gc,3,3,xobj->width-6,xobj->height-6);
XSetForeground(xobj->display,xobj->gc,xobj->TabColor[fore].pixel);
XTextExtents(xobj->xfont,"lp",strlen("lp"),&dir,&y1,&desc,&struc);
XDrawImageString(xobj->display,xobj->win,xobj->gc,5,y1+5,xobj->title,strlen(xobj->title));
/* Dessin de la zone selectionnee */
XSetFunction(xobj->display,xobj->gc,GXinvert);
if (xobj->value2>xobj->value) /* Curseur avant la souris */
{
x1=XTextWidth(xobj->xfont,&xobj->title[0],xobj->value);
x2=XTextWidth(xobj->xfont,&xobj->title[xobj->value],xobj->value2-xobj->value);
}
else /* Curseur apres la souris */
{
x1=XTextWidth(xobj->xfont,&xobj->title[0],xobj->value2);
x2=XTextWidth(xobj->xfont,&xobj->title[xobj->value2],xobj->value-xobj->value2);
}
XTextExtents(xobj->xfont,"lp",strlen("lp"),&dir,&asc,&desc,&struc);
XFillRectangle(xobj->display,xobj->win,xobj->gc,x1+5,7,x2,y1+desc-2);
XSetFunction(xobj->display,xobj->gc,GXcopy);
/* Dessin du point d'insertion */
DrawPointTxt(xobj,xobj->TabColor[fore].pixel);
}
void EvtMouseTextField(struct XObj *xobj,XButtonEvent *EvtButton)
{
unsigned int modif;
int x1,x2,y1,y2,i;
Window Win1,Win2;
int PosCurs=0;
int SizeBuf;
char *str;
int NewPos;
Atom type;
XEvent event;
int ButPress=1;
int format;
unsigned long longueur,octets_restant;
unsigned char *donnees="";
XRectangle rect;
/* On deplace le curseur a la position de la souris */
/* On recupere la position de la souris */
switch (EvtButton->button)
{
case Button1:
XQueryPointer(xobj->display,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
x2=x2-xobj->x;
PosCurs=0;
while ((PosCurs<strlen(xobj->title))&&(x2>XTextWidth(xobj->xfont,xobj->title,PosCurs)+8))
PosCurs++;
DrawPointTxt(xobj,xobj->TabColor[back].pixel);
xobj->value=PosCurs;
xobj->value2=PosCurs;
DrawPointTxt(xobj,xobj->TabColor[fore].pixel);
DrawTextField(xobj);
while (ButPress)
{
XNextEvent(xobj->display, &event);
switch (event.type)
{
case MotionNotify:
XQueryPointer(xobj->display,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
x2=x2-xobj->x;
PosCurs=0;
while ((PosCurs<strlen(xobj->title))&&(x2>XTextWidth(xobj->xfont,xobj->title,PosCurs)+8))
PosCurs++;
/* Limitation de la zone de dessin */
if (PosCurs>xobj->value2)
{
rect.x=XTextWidth(xobj->xfont,xobj->title,xobj->value2);
rect.y=0;
rect.width=XTextWidth(xobj->xfont,xobj->title,PosCurs+1)-rect.x+1;
rect.height=xobj->height;
XSetClipRectangles(xobj->display,xobj->gc,0,0,&rect,1,Unsorted);
xobj->value2=PosCurs;
DrawTextField(xobj);
XSetClipMask(xobj->display,xobj->gc,None);
}
else
if (PosCurs<xobj->value2)
{
rect.x=XTextWidth(xobj->xfont,xobj->title,PosCurs)-1;
rect.y=0;
rect.width=XTextWidth(xobj->xfont,xobj->title,xobj->value2+1)-rect.x+2;
rect.height=xobj->height;
XSetClipRectangles(xobj->display,xobj->gc,0,0,&rect,1,Unsorted);
xobj->value2=PosCurs;
DrawTextField(xobj);
XSetClipMask(xobj->display,xobj->gc,None);
}
break;
case ButtonRelease:
ButPress=0;
break;
}
}
XSetClipMask(xobj->display,xobj->gc,None);
/* Enregistrement de la selection dans le presse papier */
/* Le programme devient proprietaire de la selection */
if (xobj->value!=xobj->value2)
{
str=(char*)GetText(xobj,xobj->value2);
for (i=0;i<=7;i++)
XStoreBuffer(xobj->display,str,strlen(str),i);
Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char));
Scrapt=strcpy(Scrapt,str);
free(str);
x11base->HaveXSelection=True;
XSetSelectionOwner(x11base->display,XA_PRIMARY,x11base->win,EvtButton->time);
SelectOneTextField(xobj);
}
break;
case Button2: /* Colle le texte */
/* Si l'application possede pas la selection, elle la demande */
/* sinon elle lit son presse papier */
if (!x11base->HaveXSelection)
{
/* Demande de la selection */
XConvertSelection(xobj->display,XA_PRIMARY,XA_STRING,propriete,*xobj->ParentWin,
EvtButton->time);
while (!(XCheckTypedEvent(xobj->display,SelectionNotify,&event)))
;
if (event.xselection.property!=None)
if (event.xselection.selection==XA_PRIMARY)
{
XGetWindowProperty(xobj->display,event.xselection.requestor,event.xselection.property,0,
8192,False,event.xselection.target,&type,&format,&longueur,&octets_restant,
&donnees);
if (longueur>0)
{
Scrapt=(char*)realloc((void*)Scrapt,(longueur+1)*sizeof(char));
Scrapt=strcpy(Scrapt,donnees);
XDeleteProperty(xobj->display,event.xselection.requestor,event.xselection.property);
XFree(donnees);
}
}
}
SizeBuf=strlen(Scrapt);
if (SizeBuf>0)
{
NewPos=InsertText(xobj,Scrapt,SizeBuf);
DrawPointTxt(xobj,xobj->TabColor[back].pixel);
xobj->value=NewPos;
xobj->value2=NewPos;
DrawPointTxt(xobj,xobj->TabColor[fore].pixel);
DrawTextField(xobj);
SendMsg(xobj,SingleClic);
}
break;
case Button3: /* Appuie sur le troisieme bouton */
XQueryPointer(xobj->display,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
x2=x2-xobj->x;
PosCurs=0;
while ((PosCurs<strlen(xobj->title))&&
(x2>XTextWidth(xobj->xfont,xobj->title,PosCurs)+8))
PosCurs++;
if ((PosCurs<xobj->value) && (xobj->value<xobj->value2))
xobj->value=xobj->value2;
if ((PosCurs>xobj->value) && (xobj->value>xobj->value2))
xobj->value=xobj->value2;
xobj->value2=PosCurs;
DrawTextField(xobj);
while (ButPress)
{
XNextEvent(xobj->display, &event);
switch (event.type)
{
case MotionNotify:
XQueryPointer(xobj->display,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
x2=x2-xobj->x;
while ((PosCurs<strlen(xobj->title))&&(x2>XTextWidth(xobj->xfont,xobj->title,PosCurs)+8))
PosCurs++;
if (PosCurs>xobj->value2)
{
rect.x=XTextWidth(xobj->xfont,xobj->title,xobj->value2);
rect.y=0;
rect.width=XTextWidth(xobj->xfont,xobj->title,PosCurs+1)-rect.x+1;
rect.height=xobj->height;
XSetClipRectangles(xobj->display,xobj->gc,0,0,&rect,1,Unsorted);
xobj->value2=PosCurs;
DrawTextField(xobj);
XSetClipMask(xobj->display,xobj->gc,None);
}
else
if (PosCurs<xobj->value2)
{
rect.x=XTextWidth(xobj->xfont,xobj->title,PosCurs)-1;
rect.y=0;
rect.width=XTextWidth(xobj->xfont,xobj->title,xobj->value2+1)-rect.x+2;
rect.height=xobj->height;
XSetClipRectangles(xobj->display,xobj->gc,0,0,&rect,1,Unsorted);
xobj->value2=PosCurs;
DrawTextField(xobj);
XSetClipMask(xobj->display,xobj->gc,None);
}
PosCurs=0;
break;
case ButtonRelease:
ButPress=0;
break;
}
}
if (xobj->value!=xobj->value2)
{
str=(char*)GetText(xobj,xobj->value2);
for (i=0;i<=7;i++)
XStoreBuffer(xobj->display,str,strlen(str),i);
Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char));
Scrapt=strcpy(Scrapt,str);
free(str);
x11base->HaveXSelection=True;
XSetSelectionOwner(x11base->display,XA_PRIMARY,x11base->win,EvtButton->time);
}
break;
}
}
void EvtKeyTextField(struct XObj *xobj,XKeyEvent *EvtKey)
{
int i,x2;
char car[11];
char* carks2;
char* carks = NULL;
KeySym ks;
int Size;
int NewPos;
/* Recherche du charactere */
i=XLookupString(EvtKey,car,10,&ks,NULL);
NewPos=xobj->value;
car[i]='\0';
carks2=XKeysymToString(ks);
if (carks2!=NULL)
{
carks=(char*)calloc(sizeof(char),30);
sprintf(carks,"%s",carks2);
if (strcmp(carks,"Right")==0)
{
NewPos++;
if (NewPos>strlen(xobj->title))
NewPos=strlen(xobj->title);
}
else if (strcmp(carks,"Left")==0)
{
NewPos--;
if (NewPos<0)
NewPos=0;
}
else if (strcmp(carks,"Return")==0)
{
;
}
else if ((strcmp(carks,"Delete")==0)||(strcmp(carks,"BackSpace")==0))
{
if (NewPos>0)
{
Size=strlen(xobj->title);
memmove(&xobj->title[NewPos-1],&xobj->title[NewPos],
Size-NewPos+1);
xobj->title=(char*)realloc(xobj->title,(Size)*sizeof(char));
NewPos--;
SendMsg(xobj,SingleClic);
}
}
else if (i!=0) /* Cas d'un caractere normal */
{
/* Insertion du caractere dans le titre */
Size=strlen(xobj->title);
xobj->title=(char*)realloc(xobj->title,(2+Size)*sizeof(char));
memmove(&xobj->title[NewPos+1],&xobj->title[NewPos],
Size-NewPos+1);
xobj->title[NewPos]=car[0];
NewPos++;
SendMsg(xobj,SingleClic);
}
}
if ((xobj->value!=NewPos)||(xobj->value2!=NewPos))
{
XSetForeground(xobj->display,xobj->gc,xobj->TabColor[back].pixel);
x2=XTextWidth(xobj->xfont,xobj->title,strlen(xobj->title));
XFillRectangle(xobj->display,xobj->win,xobj->gc,x2+4,4,xobj->width-x2-8,xobj->height-8);
xobj->value=NewPos;
xobj->value2=NewPos;
DrawPointTxt(xobj,xobj->TabColor[fore].pixel);
DrawTextField(xobj);
}
free(carks);
}
void ProcessMsgTextField(struct XObj *xobj,unsigned long type,unsigned long *body)
{
}