2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "libs/fvwmlib.h"
20 #include "libs/ColorUtils.h"
21 #include "libs/Graphics.h"
24 #define BdWidth 2 /* Border width */
25 #define SbWidth 15 /* ScrollBar width */
28 * Fonction pour Liste / Functions for the List
30 void InitList(struct XObj
*xobj
)
33 XSetWindowAttributes Attr
;
34 int minw
,minh
,resize
=0;
37 /* Enregistrement des couleurs et de la police / fonts and colors */
38 if (xobj
->colorset
>= 0) {
39 xobj
->TabColor
[fore
] = Colorset
[xobj
->colorset
].fg
;
40 xobj
->TabColor
[back
] = Colorset
[xobj
->colorset
].bg
;
41 xobj
->TabColor
[hili
] = Colorset
[xobj
->colorset
].hilite
;
42 xobj
->TabColor
[shad
] = Colorset
[xobj
->colorset
].shadow
;
44 xobj
->TabColor
[fore
] = GetColor(xobj
->forecolor
);
45 xobj
->TabColor
[back
] = GetColor(xobj
->backcolor
);
46 xobj
->TabColor
[hili
] = GetColor(xobj
->hilicolor
);
47 xobj
->TabColor
[shad
] = GetColor(xobj
->shadcolor
);
51 Attr
.background_pixel
= xobj
->TabColor
[back
];
53 Attr
.cursor
= XCreateFontCursor(dpy
,XC_hand2
);
54 mask
|= CWCursor
; /* Curseur pour la fenetre / Window cursor */
55 xobj
->win
= XCreateWindow(dpy
, *xobj
->ParentWin
,
56 xobj
->x
, xobj
->y
, xobj
->width
, xobj
->height
, 0,
57 CopyFromParent
, InputOutput
, CopyFromParent
,
60 xobj
->gc
= fvwmlib_XCreateGC(dpy
, xobj
->win
, 0, NULL
);
61 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[fore
]);
62 XSetLineAttributes(dpy
, xobj
->gc
, 1, LineSolid
, CapRound
, JoinMiter
);
64 if ((xobj
->Ffont
= FlocaleLoadFont(dpy
, xobj
->font
, ScriptName
)) == NULL
)
66 fprintf(stderr
, "%s: Couldn't load font. Exiting!\n", ScriptName
);
69 if (xobj
->Ffont
->font
!= NULL
)
70 XSetFont(dpy
, xobj
->gc
, xobj
->Ffont
->font
->fid
);
72 /* Calcul de la taille du widget *
73 * Taille minimum: une ligne ou ascenseur visible */
74 /* Computation of the size of the widget *
75 * min size: one line or a visible elevator */
76 minh
= 8 + 3*BdWidth
+ 3*(xobj
->Ffont
->height
+ 3);
77 if (xobj
->height
<minh
)
82 minw
= 12 + 3*BdWidth
+SbWidth
+75;
89 XResizeWindow(dpy
, xobj
->win
, xobj
->width
, xobj
->height
);
90 if (xobj
->colorset
>= 0)
91 SetWindowBackground(dpy
, xobj
->win
, xobj
->width
, xobj
->height
,
92 &Colorset
[xobj
->colorset
], Pdepth
,
95 /* Calcul de la premiere cellule visible */
96 /* Computation of the first visible cell */
97 NbVisCell
= (xobj
->height
- 2 - 3*BdWidth
) / (xobj
->Ffont
->height
+ 3);
98 NbCell
= CountOption(xobj
->title
);
99 if (NbCell
> NbVisCell
)
101 if (xobj
->value2
> (NbCell
- NbVisCell
+ 1))
102 xobj
->value2
= NbCell
- NbVisCell
+ 1;
103 if ((xobj
->value2
< 1) || (xobj
->value2
< 0))
108 XSelectInput(dpy
, xobj
->win
, ExposureMask
);
111 void DrawVSbList(struct XObj
*xobj
, int NbCell
, int NbVisCell
, int press
)
117 r
.x
= xobj
->width
- (6+BdWidth
) -SbWidth
;
118 r
.height
= xobj
->height
- r
.y
- 2*BdWidth
;
119 r
.width
= SbWidth
+ 4;
120 DrawReliefRect(r
.x
, r
.y
, r
.width
, r
.height
, xobj
, shad
, hili
);
122 /* Calcul du rectangle pour les fleches *
123 * Compute the rectangle for the arrows */
126 r
.width
= r
.width
- 4;
127 r
.height
= r
.height
- 4;
129 /* Dessin de la fleche haute / Draw the up arrow */
130 DrawArrowN(xobj
, r
.x
+ 1, r
.y
+ 1, press
==1);
131 DrawArrowS(xobj
, r
.x
+ 1, r
.y
+ r
.height
- 14, press
==2);
133 /* Calcul du rectangle pour le pouce*/
135 r
.height
= r
.height
- 26;
138 XClearArea(dpy
, xobj
->win
, r
.x
, r
.y
+1, r
.width
, r
.height
-2, False
);
140 /* Dessin du pouce */
141 if (NbVisCell
< NbCell
)
142 SizeTh
= (NbVisCell
* (r
.height
-8) / NbCell
) + 8;
145 PosTh
= (xobj
->value2
- 1) * (r
.height
- 8) / NbCell
;
146 DrawReliefRect(r
.x
, r
.y
+ PosTh
, r
.width
, SizeTh
, xobj
, hili
, shad
);
150 struct XObj
*xobj
, int NbCell
, int NbVisCell
, int HeightCell
,
151 int asc
, XEvent
*evp
)
159 r
.x
= 4 + BdWidth
+ 4;
161 r
.width
= xobj
->width
- 16 - SbWidth
- BdWidth
- 6;
162 r
.height
= xobj
->height
- r
.y
- 4 - 2*BdWidth
;
164 for (i
= xobj
->value2
; i
< xobj
->value2
+ NbVisCell
; i
++)
166 Title
= (char*)GetMenuTitle(xobj
->title
, i
);
170 if (!frect_get_intersection(
171 r
.x
- 2, r
.y
+ (i
- xobj
->value2
)*HeightCell
+ 2,
172 r
.width
+ 4, HeightCell
-2,
173 evp
->xexpose
.x
, evp
->xexpose
.y
,
174 evp
->xexpose
.width
, evp
->xexpose
.height
,
182 inter
.x
= r
.x
- 2; /* r.x */
183 inter
.y
= r
.y
+ (i
-xobj
->value2
)*HeightCell
+ 2;
184 inter
.width
= r
.width
+ 4;
185 inter
.height
= HeightCell
-2;
191 if (strlen(Title
)!=0)
193 int x
= GetXTextPosition(
195 FlocaleTextWidth(xobj
->Ffont
,Title
,strlen(Title
)),
197 int y
= (i
- xobj
->value2
) * HeightCell
+ asc
+ 2 + r
.y
;
199 if (xobj
->value
== i
)
201 /* hili is better than shad.*/
202 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
204 dpy
, xobj
->win
, xobj
->gc
,
205 inter
.x
, inter
.y
, inter
.width
, inter
.height
);
207 dpy
, xobj
, xobj
->win
, x
, y
, Title
, fore
, back
,
208 shad
, !xobj
->flags
[1], &r
, evp
);
214 inter
.x
, inter
.y
, inter
.width
, inter
.height
,
217 dpy
, xobj
, xobj
->win
, x
, y
, Title
, fore
, hili
,
218 back
, !xobj
->flags
[1], &r
, evp
);
225 inter
.x
, inter
.y
, inter
.width
, inter
.height
,
233 void DestroyList(struct XObj
*xobj
)
235 XFreeGC(dpy
, xobj
->gc
);
236 XDestroyWindow(dpy
, xobj
->win
);
239 void DrawList(struct XObj
*xobj
, XEvent
*evp
)
241 int NbVisCell
,NbCell
;
245 /* Dessin du contour / */
246 DrawReliefRect(0, 0, xobj
->width
, xobj
->height
, xobj
, hili
, shad
);
248 /* Dessin du contour de la liste */
251 r
.width
= xobj
->width
- r
.x
- 4 - 2*BdWidth
- SbWidth
;
252 r
.height
= xobj
->height
- r
.y
- 2*BdWidth
;
253 DrawReliefRect(r
.x
, r
.y
, r
.width
, r
.height
, xobj
, shad
, hili
);
255 /* Calcul du nombre de cellules visibles */
256 HeightCell
= xobj
->Ffont
->height
+ 3;
257 NbVisCell
= r
.height
/HeightCell
;
258 NbCell
= CountOption(xobj
->title
);
259 if (NbCell
> NbVisCell
)
261 if (xobj
->value2
> (NbCell
- NbVisCell
+ 1))
262 xobj
->value2
= NbCell
- NbVisCell
+ 1;
263 if ((xobj
->value2
< 1) || (xobj
->value2
< 0))
270 /* Dessin des cellules */
272 xobj
, NbCell
, NbVisCell
, HeightCell
,
273 /*FlocaleGetMinOffset(xobj->Ffont, ROTATION_0)*/
277 /* Dessin de l'ascenseur vertical */
278 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
282 void EvtMouseList(struct XObj
*xobj
, XButtonEvent
*EvtButton
)
284 XRectangle rect
,rectT
;
291 int NbVisCell
,NbCell
,HeightCell
,NPosCell
,PosMouse
;
294 pt
.x
= EvtButton
->x
-xobj
->x
;
295 pt
.y
= EvtButton
->y
-xobj
->y
;
297 HeightCell
= xobj
->Ffont
->height
+ 3;
298 NbVisCell
= (xobj
->height
-6-BdWidth
)/HeightCell
;
299 NbCell
= CountOption(xobj
->title
);
301 /* Clic dans une cellule */
302 rect
.x
= 4 + BdWidth
;
304 rect
.width
= xobj
->width
- rect
.x
- 10 - 2*BdWidth
- SbWidth
;
305 rect
.height
= xobj
->height
-rect
.y
- 4 - 2*BdWidth
;
306 if(PtInRect(pt
,rect
))
308 /* Determination de la cellule */
309 pt
.y
= pt
.y
- rect
.y
;
310 NPosCell
= xobj
->value2
+ (pt
.y
/(xobj
->Ffont
->height
+3));
311 if (NPosCell
> CountOption(xobj
->title
))
313 else if (NPosCell
>= xobj
->value2
+ NbVisCell
)
317 if (NPosCell
!= xobj
->value
)
319 xobj
->value
= NPosCell
;
322 SendMsg(xobj
, SingleClic
);
326 /* Clic fleche haute asc vertical */
327 rect
.y
= 5 + BdWidth
;
328 rect
.x
= xobj
->width
- (6+BdWidth
) - SbWidth
+3;
331 if(PtInRect(pt
,rect
))
333 DrawVSbList(xobj
, NbCell
, NbVisCell
, 1);
336 FQueryPointer(dpy
, *xobj
->ParentWin
, &Win1
, &Win2
,
337 &x1
, &y1
, &x2
, &y2
, &modif
);
340 if (PtInRect(pt
,rect
))
346 if (xobj
->value2
< 1)
350 DrawCellule(xobj
, NbCell
, NbVisCell
, HeightCell
,
351 xobj
->Ffont
->ascent
, NULL
);
352 DrawVSbList(xobj
, NbCell
, NbVisCell
, 1);
358 DrawVSbList(xobj
, NbCell
, NbVisCell
, 1);
360 if (xobj
->value2
< 1)
363 DrawCellule(xobj
, NbCell
, NbVisCell
, HeightCell
,
364 xobj
->Ffont
->ascent
, NULL
);
372 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
376 FD_SET(x_fd
, &in_fdset
);
377 select(32, SELECT_FD_SET_CAST
&in_fdset
, NULL
, NULL
, NULL
);
379 while (!FCheckTypedEvent(dpy
, ButtonRelease
, &event
));
380 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
384 /* Clic flache basse asc vertical */
385 rect
.y
= xobj
->height
- 2*BdWidth
-16;
386 if(PtInRect(pt
,rect
))
388 DrawVSbList(xobj
, NbCell
, NbVisCell
, 2);
391 FQueryPointer(dpy
, *xobj
->ParentWin
, &Win1
, &Win2
,
392 &x1
, &y1
, &x2
, &y2
, &modif
);
395 if (PtInRect(pt
, rect
))
400 if (xobj
->value2
<= NbCell
-NbVisCell
)
403 DrawCellule(xobj
, NbCell
, NbVisCell
, HeightCell
,
404 xobj
->Ffont
->ascent
, NULL
);
405 DrawVSbList(xobj
, NbCell
, NbVisCell
, 2);
411 DrawVSbList(xobj
, NbCell
, NbVisCell
, 2);
412 if (xobj
->value2
<= NbCell
-NbVisCell
)
415 DrawCellule(xobj
, NbCell
, NbVisCell
, HeightCell
,
416 xobj
->Ffont
->ascent
, NULL
);
425 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
429 FD_SET(x_fd
, &in_fdset
);
430 select(32, SELECT_FD_SET_CAST
&in_fdset
, NULL
, NULL
, NULL
);
432 while (!FCheckTypedEvent(dpy
, ButtonRelease
, &event
));
433 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
437 /* clic sur la zone pouce de l'ascenseur de l'ascenseur */
438 rect
.y
= 17 + BdWidth
;
439 rect
.x
= xobj
->width
- (6+BdWidth
) - SbWidth
+ 2;
440 rect
.height
= xobj
->height
- rect
.y
- 19 - 2*BdWidth
;
441 rect
.width
= SbWidth
;
442 if(PtInRect(pt
,rect
))
444 /* Clic dans le pouce */
446 rectT
.y
= rect
.y
+ (xobj
->value2
- 1) * (rect
.height
- 8) / NbCell
;
447 if (NbVisCell
<NbCell
)
448 rectT
.height
= NbVisCell
* (rect
.height
-8) / NbCell
+8;
450 rectT
.height
= rect
.height
;
451 rectT
.width
= rect
.width
;
452 if(PtInRect(pt
,rectT
))
454 PosMouse
= pt
.y
- rectT
.y
- HeightCell
/ 2 + 2;
457 FQueryPointer(dpy
, *xobj
->ParentWin
, &Win1
, &Win2
,
458 &x1
, &y1
, &x2
, &y2
, &modif
);
459 /* Calcul de l'id de la premiere cellule */
460 pt
.y
= y2
-xobj
->y
- PosMouse
;
461 NPosCell
= (pt
.y
- rect
.y
)*NbCell
/ (rect
.height
);
463 if (NPosCell
< 1) NPosCell
= 1;
464 if (NbCell
> NbVisCell
)
466 if (NPosCell
> (NbCell
- NbVisCell
+ 1))
467 NPosCell
= NbCell
- NbVisCell
+ 1;
471 if (xobj
->value2
!= NPosCell
)
473 xobj
->value2
= NPosCell
;
475 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
,
477 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
480 FD_SET(x_fd
, &in_fdset
);
481 select(32, SELECT_FD_SET_CAST
&in_fdset
, NULL
, NULL
, NULL
);
483 while (!FCheckTypedEvent(dpy
, ButtonRelease
, &event
));
485 else if (pt
.y
< rectT
.y
)
487 NPosCell
= xobj
->value2
- NbVisCell
;
490 if (xobj
->value2
!= NPosCell
)
492 xobj
->value2
= NPosCell
;
494 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
495 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
498 else if (pt
.y
> rectT
.y
+ rectT
.height
)
500 NPosCell
= xobj
->value2
+NbVisCell
;
501 if (NbCell
>NbVisCell
)
503 if (NPosCell
> (NbCell
- NbVisCell
+ 1))
504 NPosCell
= NbCell
- NbVisCell
+ 1;
508 if (xobj
->value2
!= NPosCell
)
510 xobj
->value2
= NPosCell
;
512 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
513 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
519 void EvtKeyList(struct XObj
*xobj
, XKeyEvent
*EvtKey
)
522 unsigned char buf
[10];
523 int NbVisCell
,NbCell
,HeightCell
,NPosCell
;
530 HeightCell
= xobj
->Ffont
->height
+ 3;
531 NbVisCell
= (xobj
->height
- 6 - BdWidth
) / HeightCell
;
532 NbCell
= CountOption(xobj
->title
);
533 FQueryPointer(dpy
, xobj
->win
, &Win1
, &Win2
, &x1
, &y1
, &x2
, &y2
, &modif
);
536 rect
.x
= 4 + BdWidth
;
538 rect
.width
= xobj
->width
- rect
.x
-10 - 2*BdWidth
- SbWidth
;
539 rect
.height
= xobj
->height
- rect
.y
- 4 - 2*BdWidth
;
541 /* Recherche du charactere */
542 XLookupString(EvtKey
, (char *)buf
, sizeof(buf
), &ks
, NULL
);
546 if(PtInRect(pt
,rect
))
548 /* Determination de la cellule */
549 pt
.y
= pt
.y
- rect
.y
;
550 NPosCell
= xobj
->value2
+ (pt
.y
/(xobj
->Ffont
->height
+ 3));
551 if (NPosCell
> CountOption(xobj
->title
))
553 else if (NPosCell
>= xobj
->value2
+ NbVisCell
)
557 if (NPosCell
!= xobj
->value
)
559 xobj
->value
= NPosCell
;
562 SendMsg(xobj
, SingleClic
);
565 else if (ks
== XK_Up
)
567 if (xobj
->value2
== 1)
569 if(PtInRect(pt
,rect
))
571 /* Determination de la cellule */
573 NPosCell
= xobj
->value2
+(pt
.y
/(xobj
->Ffont
->height
+ 3));
574 if (NPosCell
> CountOption(xobj
->title
))
578 FWarpPointer(dpy
, None
, None
, 0, 0, 0, 0, 0, -HeightCell
);
586 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
587 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
590 else if (ks
== XK_Down
)
592 if (xobj
->value2
> NbCell
-NbVisCell
)
594 if(PtInRect(pt
,rect
))
596 /* Determination de la cellule */
597 pt
.y
= pt
.y
- rect
.y
;
598 NPosCell
= xobj
->value2
+ (pt
.y
/(xobj
->Ffont
->height
+ 3));
599 if (NPosCell
> CountOption(xobj
->title
))
601 if (NPosCell
< NbCell
&& NPosCell
> 0)
603 FWarpPointer(dpy
, None
, None
, 0, 0, 0, 0, 0, HeightCell
);
611 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
612 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
615 else if (ks
== XK_Prior
&& xobj
->value2
> 1)
617 xobj
->value2
= xobj
->value2
- NbVisCell
;
618 if (xobj
->value2
< 1)
621 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
622 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
624 else if (ks
== XK_Next
&& xobj
->value2
<= NbCell
-NbVisCell
)
626 xobj
->value2
= xobj
->value2
+ NbVisCell
;
627 if (xobj
->value2
> NbCell
- NbVisCell
+ 1)
628 xobj
->value2
= NbCell
- NbVisCell
+ 1;
630 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
631 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
633 else if (ks
== XK_Home
)
635 if (xobj
->value2
> 1)
639 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
640 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
643 else if (ks
== XK_End
)
645 if (xobj
->value2
< NbCell
- NbVisCell
+ 1)
647 xobj
->value2
= NbCell
- NbVisCell
+ 1;
649 xobj
, NbCell
, NbVisCell
, HeightCell
, xobj
->Ffont
->ascent
, NULL
);
650 DrawVSbList(xobj
, NbCell
, NbVisCell
, 0);
656 void ProcessMsgList(struct XObj
*xobj
, unsigned long type
, unsigned long *body
)