3 * Purpose: Implementation of the XForms object bmtable.
4 * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
5 * Created: November 1995
6 * Description: A bitmap table uses a single bitmap to simulate a 2d array
7 * of bitmap buttons. It can be used to build bitmap menus.
9 * Copyright 1995,1996 Alejandro Aguilar Sierra
11 * You are free to use and modify this code under the terms of
12 * the GNU General Public Licence version 2 or later.
20 #include XPM_H_LOCATION
23 int nx, ny; /* Dimensions of the table */
24 int dx, dy; /* Size of each item */
25 int bx, by; /* Bitmap's position */
26 int bw, bh; /* Bitmap dimensions */
27 char* bdata; /* Bitmap data */
28 int maxi; /* Number of items */
29 int i; /* Current position */
30 int mousebut; /* mouse button pushed */
31 Pixmap pix; /* Pixmap from data (temporal) */
35 extern "C" int handle_bitmaptable(FL_OBJECT *ob, int event, FL_Coord mx,
36 FL_Coord my, int key, void *xev);
39 FL_OBJECT *fl_create_bmtable(int type, FL_Coord x, FL_Coord y,
40 FL_Coord w, FL_Coord h, char const *label)
44 ob = fl_make_object(FL_BMTABLE, type, x, y, w, h, label, handle_bitmaptable);
45 ob->boxtype = FL_BMTABLE_BOXTYPE;
46 ob->spec = fl_calloc(1, sizeof(BMTABLE_SPEC));
47 ((BMTABLE_SPEC *)ob->spec)->pix = 0;
48 ((BMTABLE_SPEC *)ob->spec)->bdata= 0;
49 ((BMTABLE_SPEC *)ob->spec)->mousebut= -1;
54 FL_OBJECT *fl_add_bmtable(int type, FL_Coord x, FL_Coord y,
55 FL_Coord w, FL_Coord h, char const *label)
59 ob = fl_create_bmtable(type, x, y, w,h, label);
60 fl_add_object(fl_current_form, ob);
66 static void draw_bitmaptable(FL_OBJECT *ob)
70 FL_Coord xx, yy, ww, hh;
71 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
73 GC gc = fl_state[fl_get_vclass()].gc[0];
75 /* draw the bounding box first */
76 lx = sp->maxi % sp->nx;
77 fl_drw_box(ob->boxtype, ob->x, ob->y, ob->w, ob->h, ob->col1, ob->bw);
80 xx = ob->x+ sp->dx*lx + i;
81 yy = ob->y+ (sp->ny-1)*sp->dy+i;
82 ww = ob->x+ob->w - xx - i;
83 hh = ob->y+ob->h-yy-i;
84 fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
85 fl_rectf(xx, yy, ww+i, hh+i, ob->col1);
88 /* draw the background bitmap */
91 sp->pix = XCreatePixmapFromBitmapData(fl_display, fl_winget(),
92 sp->bdata, sp->bw, sp->bh,
93 fl_get_flcolor(ob->lcol), fl_get_flcolor(ob->col1),
94 DefaultDepth(fl_display, DefaultScreen(fl_display)));
100 if (sp->bx < FL_abs(ob->bw) + 1) {
101 xx = FL_abs(ob->bw) - sp->bx + 1;
102 mx = ob->x + FL_abs(ob->bw) + 1;
107 if (sp->by < FL_abs(ob->bw) + 1) {
108 yy = FL_abs(ob->bw) - sp->by + 1;
109 my = ob->y + FL_abs(ob->bw) + 1;
114 ww = (mx + sp->bw < ob->x + ob->w - FL_abs(ob->bw)) ?
115 sp->bw: ob->x + ob->w - FL_abs(ob->bw) - mx;
116 hh = (my + sp->bh < ob->y + ob->h - FL_abs(ob->bw)) ?
117 sp->bh: ob->y + ob->h - FL_abs(ob->bw) - my;
120 j = hh - ((lx) ? sp->dy+2*i: 0);
121 XCopyArea(fl_display, sp->pix, fl_winget(), gc, xx, yy, ww, j, mx, my);
124 XCopyArea(fl_display, sp->pix, fl_winget(), gc, xx,
125 yy+j, lx*sp->dx-2*i, hh-j, mx, my+j);
131 /* draw the grid if type > FLAT */
132 if (ob->type > FL_BMTABLE_FLAT) {
136 for (yy=ob->y; yy<=my; yy+=sp->dy) {
137 if (ob->boxtype!=FL_FLAT_BOX && (yy==ob->y || yy>my-sp->dy))
139 if (lx>0 && yy>=my-sp->dy - sp->dy/2)
141 fl_diagline(ob->x, yy, ww, 1, FL_BOTTOM_BCOL);
142 fl_diagline(ob->x, yy+1, ww-2, 1, FL_TOP_BCOL);
145 for (xx=ob->x; xx<=mx; xx+=sp->dx) {
146 if (ob->boxtype!=FL_FLAT_BOX && (xx==ob->x || xx>mx-sp->dx))
148 if (lx>0 && xx>=ob->x+lx*sp->dx)
149 hh = (sp->ny-1)*sp->dy;
150 fl_diagline(xx, ob->y, 1, hh, FL_RIGHT_BCOL);
151 fl_diagline(xx+1, ob->y+1, 1, hh-2, FL_LEFT_BCOL);
155 /* Simulate a pushed button */
156 if (ob->pushed && 0 <= sp->i && sp->i < sp->maxi) {
159 ww = sp->dx-2*FL_abs(ob->bw);
160 hh = sp->dy-2*FL_abs(ob->bw);
161 xx = ob->x + sp->dx*i + FL_abs(ob->bw);
162 yy = ob->y + sp->dy*j + FL_abs(ob->bw);
163 fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
168 extern "C" int handle_bitmaptable(FL_OBJECT *ob, int event, FL_Coord mx,
169 FL_Coord my, int key, void */*xev*/)
172 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
176 draw_bitmaptable(ob);
179 if (!ob->belowmouse) { /* This never happens. Why? */
181 fl_redraw_object(ob);
184 i = (mx - ob->x)/sp->dx; j = (my - ob->y)/sp->dy;
185 if (i>=0 && i< sp->nx && j>=0 && j< sp->ny) {
187 if (i >= sp->maxi) i = -1;
190 fl_redraw_object(ob);
196 i = (mx - ob->x)/sp->dx + ((my - ob->y)/sp->dy)*sp->nx;
197 if (0 <= i && i < sp->maxi) {
199 fl_redraw_object(ob);
204 fl_redraw_object(ob);
208 XFreePixmap(fl_display, sp->pix);
211 fl_free(((BMTABLE_SPEC*)ob->spec));
219 * The table has nx columns of dx width each and ny rows of dy height each.
220 * Initially the position of the firts item is supposed to be the same that
221 * the object position (x, y), and the number of items is supposed to be
224 * The user could change these later. See below.
226 void fl_set_bmtable_data(FL_OBJECT *ob, int nx, int ny, int bw, int bh,
229 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
233 sp->bx = FL_abs(ob->bw);
234 sp->by = FL_abs(ob->bw);
238 sp->maxi = sp->nx * sp->ny;
246 void fl_set_bmtable_pixmap_data(FL_OBJECT *ob, int nx, int ny,
249 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
250 extern Colormap color_map;
254 sp->bx = FL_abs(ob->bw);
255 sp->by = FL_abs(ob->bw);
259 sp->maxi = sp->nx * sp->ny;
261 Pixmap dummy_shapemask = 0;
262 XpmAttributes dumb_attributes= {0};
263 dumb_attributes.colormap = color_map;
264 dumb_attributes.closeness = 30000;
265 dumb_attributes.valuemask = XpmColormap | XpmCloseness;
266 if (XCreatePixmapFromData(fl_display, fl_winget(), pdata,
267 &(sp->pix), &dummy_shapemask,
268 &dumb_attributes) == XpmSuccess) {
269 sp->bw = dumb_attributes.width;
270 sp->bh = dumb_attributes.height;
271 XpmFreeAttributes(&dumb_attributes);
272 if (dummy_shapemask) {
273 XFreePixmap(fl_display, dummy_shapemask);
282 * This function works only for X11R6 or later
284 #if XlibSpecificationRelease > 5
286 void fl_set_bmtable_file(FL_OBJECT *ob, int nx, int ny, char const *filename)
291 if(XReadBitmapFileData(filename, (unsigned int *) &bw, (unsigned int *) &bh,
292 (unsigned char **) &bdata, &xh, &yh)==BitmapSuccess)
293 fl_set_bmtable_data(ob, nx, ny, bw, bh, bdata);
299 void fl_set_bmtable_file(FL_OBJECT *, int, int, char const *)
301 fprintf(stderr, "Set bmtable file: Sorry, I need X11 release 6 to do "
309 void fl_set_bmtable_pixmap_file(FL_OBJECT *ob, int nx, int ny, char const *filename)
311 extern Colormap color_map;
312 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
316 sp->bx = FL_abs(ob->bw);
317 sp->by = FL_abs(ob->bw);
321 sp->maxi = sp->nx * sp->ny;
324 Pixmap dummy_shapemask = 0;
325 XpmAttributes dumb_attributes= {0};
326 dumb_attributes.colormap = color_map;
327 dumb_attributes.closeness = 30000;
328 dumb_attributes.valuemask = XpmColormap | XpmCloseness;
330 if (XReadPixmapFile(fl_display, fl_winget(), (char *)filename,
331 &(sp->pix), &dummy_shapemask,
332 &dumb_attributes) == XpmSuccess) {
333 sp->bw = dumb_attributes.width;
334 sp->bh = dumb_attributes.height;
335 XpmFreeAttributes(&dumb_attributes);
336 if (dummy_shapemask) {
337 XFreePixmap(fl_display, dummy_shapemask);
346 * This function allows to adjust the position of the first item and its
347 * size (dx, dy). The input values are incremental, not absolute.
349 void fl_set_bmtable_adjust(FL_OBJECT *ob, int px, int py, int dx, int dy)
351 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
361 * This function returns the table's selected position.
363 int fl_get_bmtable(FL_OBJECT *ob)
365 if ((BMTABLE_SPEC *)ob->spec)
366 return ((BMTABLE_SPEC *)ob->spec)->i;
373 * You can change the max number of items if you want.
375 void fl_set_bmtable_maxitems(FL_OBJECT *ob, int i)
377 if (i>0 && (BMTABLE_SPEC *)ob->spec)
378 ((BMTABLE_SPEC *)ob->spec)->maxi = i;
382 int fl_get_bmtable_maxitems(FL_OBJECT *ob)
384 if ((BMTABLE_SPEC *)ob->spec)
385 return ((BMTABLE_SPEC *)ob->spec)->maxi;
391 void fl_replace_bmtable_item(FL_OBJECT */*ob*/, int /*id*/, int /*cw*/, int /*ch*/, char */*data*/)
393 fprintf(stderr, "Replace bmtable item: Sorry, not yet implemented!\n");
397 void fl_get_bmtable_item(FL_OBJECT */*ob*/, int /*id*/, int */*cw*/, int */*ch*/, char */*data*/)
399 fprintf(stderr, "Get bmtable item: Sorry, not yet implemented!\n");
402 void fl_set_bmtable(FL_OBJECT *ob, int pushed, int pos)
404 if ((BMTABLE_SPEC *)ob->spec)
405 ((BMTABLE_SPEC *)ob->spec)->i = (pushed) ? pos: -1;
409 int fl_get_bmtable_numb(FL_OBJECT *ob)
411 if ((BMTABLE_SPEC *)ob->spec)
412 return ((BMTABLE_SPEC *)ob->spec)->mousebut;
418 Pixmap fl_get_bmtable_pixmap(FL_OBJECT *ob)
420 if ((BMTABLE_SPEC *)ob->spec)
421 return ((BMTABLE_SPEC *)ob->spec)->pix;
427 void fl_draw_bmtable_item(FL_OBJECT *ob, int i, Drawable d, int xx, int yy)
430 GC gc = fl_state[fl_get_vclass()].gc[0];
431 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
434 x = (i % sp->nx)*sp->dx + FL_abs(ob->bw);
435 y = (i/sp->nx)*sp->dy + FL_abs(ob->bw);
436 w = sp->dx-2*FL_abs(ob->bw);
437 h = sp->dy-2*FL_abs(ob->bw);
438 XCopyArea(fl_display, sp->pix, d, gc, x, y, w, h, xx, yy);
443 /* Free the current bitmap and pixmap in preparation for installing a new one */
444 void fl_free_bmtable_bitmap(FL_OBJECT *ob)
446 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
448 /* dump the temporary pixmap */
450 XFreePixmap(fl_display, sp->pix);
455 /* and free the space taken by bdata etc. */
456 if (sp && sp->bdata) {
462 /* Free the current pixmap in preparation for installing a new one */
463 /* This is needed when using data instead of files to set bitmaps */
464 void fl_free_bmtable_pixmap(FL_OBJECT *ob)
466 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
468 /* dump the temporary pixmap */
470 XFreePixmap(fl_display, sp->pix);