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.
19 #pragma implementation
24 #include XPM_H_LOCATION
26 #if defined(__cplusplus)
32 int nx, ny; /* Dimensions of the table */
33 int dx, dy; /* Size of each item */
34 int bx, by; /* Bitmap's position */
35 int bw, bh; /* Bitmap dimensions */
36 unsigned char const * bdata; /* Bitmap data */
37 int maxi; /* Number of items */
38 int i; /* Current position */
39 int mousebut; /* mouse button pushed */
40 Pixmap pix; /* Pixmap from data (temporal) */
44 int handle_bitmaptable(FL_OBJECT * ob, int event, FL_Coord mx,
45 FL_Coord my, int key, void * xev);
48 FL_OBJECT * fl_create_bmtable(int type, FL_Coord x, FL_Coord y,
49 FL_Coord w, FL_Coord h, char const * label)
53 ob = fl_make_object(FL_BMTABLE, type, x, y, w, h, label, handle_bitmaptable);
54 ob->boxtype = FL_BMTABLE_BOXTYPE;
55 ob->spec = fl_calloc(1, sizeof(BMTABLE_SPEC));
56 ((BMTABLE_SPEC *)ob->spec)->pix = 0;
57 ((BMTABLE_SPEC *)ob->spec)->bdata= 0;
58 ((BMTABLE_SPEC *)ob->spec)->mousebut= -1;
63 FL_OBJECT *fl_add_bmtable(int type, FL_Coord x, FL_Coord y,
64 FL_Coord w, FL_Coord h, char const *label)
68 ob = fl_create_bmtable(type, x, y, w, h, label);
69 fl_add_object(fl_current_form, ob);
76 void draw_bitmaptable(FL_OBJECT *ob)
80 FL_Coord xx, yy, ww, hh;
81 BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
82 GC gc = fl_state[fl_get_vclass()].gc[0];
85 /* draw the bounding box first */
86 lx = sp->maxi % sp->nx;
87 fl_drw_box(ob->boxtype, ob->x, ob->y, ob->w, ob->h, ob->col1, ob->bw);
90 xx = ob->x+ sp->dx*lx + i;
91 yy = ob->y+ (sp->ny-1)*sp->dy+i;
92 ww = ob->x+ob->w - xx - i;
93 hh = ob->y+ob->h-yy-i;
94 fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
95 fl_rectf(xx, yy, ww+i, hh+i, ob->col1);
98 /* draw the background bitmap */
101 sp->pix = XCreatePixmapFromBitmapData(fl_get_display(), fl_winget(),
104 fl_get_flcolor(ob->lcol), fl_get_flcolor(ob->col1),
105 /*DefaultDepth(fl_get_display(), DefaultScreen(fl_get_display()))*/ fl_state[fl_get_vclass()].depth);
106 XFlush(fl_get_display());
110 /* Adjust position */
111 if (sp->bx < FL_abs(ob->bw) + 1) {
112 xx = FL_abs(ob->bw) - sp->bx + 1;
113 mx = ob->x + FL_abs(ob->bw) + 1;
118 if (sp->by < FL_abs(ob->bw) + 1) {
119 yy = FL_abs(ob->bw) - sp->by + 1;
120 my = ob->y + FL_abs(ob->bw) + 1;
125 ww = (mx + sp->bw < ob->x + ob->w - FL_abs(ob->bw)) ?
126 sp->bw: ob->x + ob->w - FL_abs(ob->bw) - mx;
127 hh = (my + sp->bh < ob->y + ob->h - FL_abs(ob->bw)) ?
128 sp->bh: ob->y + ob->h - FL_abs(ob->bw) - my;
131 j = hh - ((lx) ? sp->dy+2*i: 0);
132 XCopyArea(fl_get_display(), sp->pix, fl_winget(), gc, xx, yy, ww, j, mx, my);
133 XFlush(fl_get_display());
135 XCopyArea(fl_get_display(), sp->pix, fl_winget(), gc, xx,
136 yy+j, lx*sp->dx-2*i, hh-j, mx, my+j);
137 XFlush(fl_get_display());
142 /* draw the grid if type > FLAT */
143 if (ob->type > FL_BMTABLE_FLAT) {
147 for (yy= ob->y; yy<= my; yy+= sp->dy) {
148 if (ob->boxtype!= FL_FLAT_BOX && (yy == ob->y || yy>my-sp->dy))
150 if (lx>0 && yy>= my-sp->dy - sp->dy/2)
152 fl_diagline(ob->x, yy, ww, 1, FL_BOTTOM_BCOL);
153 fl_diagline(ob->x, yy+1, ww-2, 1, FL_TOP_BCOL);
156 for (xx= ob->x; xx<= mx; xx+= sp->dx) {
157 if (ob->boxtype!= FL_FLAT_BOX && (xx == ob->x || xx>mx-sp->dx))
159 if (lx>0 && xx>= ob->x+lx*sp->dx)
160 hh = (sp->ny-1)*sp->dy;
161 fl_diagline(xx, ob->y, 1, hh, FL_RIGHT_BCOL);
162 fl_diagline(xx+1, ob->y+1, 1, hh-2, FL_LEFT_BCOL);
166 /* Simulate a pushed button */
167 if (ob->pushed && 0 <= sp->i && sp->i < sp->maxi) {
170 ww = sp->dx-2*FL_abs(ob->bw);
171 hh = sp->dy-2*FL_abs(ob->bw);
172 xx = ob->x + sp->dx*i + FL_abs(ob->bw);
173 yy = ob->y + sp->dy*j + FL_abs(ob->bw);
174 fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
179 int handle_bitmaptable(FL_OBJECT * ob, int event, FL_Coord mx,
180 FL_Coord my, int key, void * xev)
183 BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
187 draw_bitmaptable(ob);
190 if (!ob->belowmouse) { /* This never happens. Why? */
192 fl_redraw_object(ob);
195 i = (mx - ob->x)/sp->dx; j = (my - ob->y)/sp->dy;
196 if (i>= 0 && i< sp->nx && j>= 0 && j< sp->ny) {
198 if (i >= sp->maxi) i = -1;
201 fl_redraw_object(ob);
207 i = (mx - ob->x)/sp->dx + ((my - ob->y)/sp->dy)*sp->nx;
208 if (0 <= i && i < sp->maxi) {
210 fl_redraw_object(ob);
215 fl_redraw_object(ob);
219 XFreePixmap(fl_get_display(), sp->pix);
220 XFlush(fl_get_display());
222 fl_free(((BMTABLE_SPEC*)ob->spec));
230 * The table has nx columns of dx width each and ny rows of dy height each.
231 * Initially the position of the firts item is supposed to be the same that
232 * the object position (x, y), and the number of items is supposed to be
235 * The user could change these later. See below.
237 void fl_set_bmtable_data(FL_OBJECT * ob, int nx, int ny, int bw, int bh,
238 unsigned char const * bdata)
240 BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
244 sp->bx = FL_abs(ob->bw);
245 sp->by = FL_abs(ob->bw);
249 sp->maxi = sp->nx * sp->ny;
257 void fl_set_bmtable_pixmap_data(FL_OBJECT * ob, int nx, int ny,
260 BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
262 Pixmap dummy_shapemask = 0;
263 XpmAttributes dumb_attributes = { 0 };
266 sp->bx = FL_abs(ob->bw);
267 sp->by = FL_abs(ob->bw);
271 sp->maxi = sp->nx * sp->ny;
273 dumb_attributes.colormap = fl_state[fl_get_vclass()].colormap;
274 dumb_attributes.closeness = 30000;
275 dumb_attributes.valuemask = XpmColormap | XpmCloseness;
276 if (XCreatePixmapFromData(fl_get_display(), fl_winget(), pdata,
277 &(sp->pix), &dummy_shapemask,
278 &dumb_attributes) == XpmSuccess) {
279 sp->bw = dumb_attributes.width;
280 sp->bh = dumb_attributes.height;
281 XpmFreeAttributes(&dumb_attributes);
282 if (dummy_shapemask) {
283 XFreePixmap(fl_get_display(), dummy_shapemask);
291 * This function works only for X11R6 or later
293 #if XlibSpecificationRelease > 5
295 void fl_set_bmtable_file(FL_OBJECT * ob, int nx, int ny, char const * filename)
299 unsigned char * bdata;
301 if (XReadBitmapFileData(filename, &bw, &bh,
302 &bdata, &xh, &yh) == BitmapSuccess)
303 fl_set_bmtable_data(ob, nx, ny, bw, bh, bdata);
304 XFlush(fl_get_display());
309 void fl_set_bmtable_file(FL_OBJECT * ob, int nx, int ny, char const * filename)
311 fprintf(stderr, "Set bmtable file: Sorry, I need X11 release 6 to do "
319 void fl_set_bmtable_pixmap_file(FL_OBJECT *ob, int nx, int ny, char const *filename)
321 /* extern Colormap color_map; */
322 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
324 Pixmap dummy_shapemask = 0;
325 XpmAttributes dumb_attributes = { 0 };
328 sp->bx = FL_abs(ob->bw);
329 sp->by = FL_abs(ob->bw);
333 sp->maxi = sp->nx * sp->ny;
336 dumb_attributes.colormap = fl_state[fl_get_vclass()].colormap;
337 dumb_attributes.closeness = 30000;
338 dumb_attributes.valuemask = XpmColormap | XpmCloseness;
340 if (XReadPixmapFile(fl_get_display(), fl_winget(), (char *)filename,
341 &(sp->pix), &dummy_shapemask,
342 &dumb_attributes) == XpmSuccess) {
343 sp->bw = dumb_attributes.width;
344 sp->bh = dumb_attributes.height;
345 XpmFreeAttributes(&dumb_attributes);
346 if (dummy_shapemask) {
347 XFreePixmap(fl_get_display(), dummy_shapemask);
350 /* XFlush(fl_get_display()); */
356 * This function allows to adjust the position of the first item and its
357 * size (dx, dy). The input values are incremental, not absolute.
359 void fl_set_bmtable_adjust(FL_OBJECT *ob, int px, int py, int dx, int dy)
361 BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
371 * This function returns the table's selected position.
373 int fl_get_bmtable(FL_OBJECT *ob)
375 if ((BMTABLE_SPEC *)ob->spec)
376 return ((BMTABLE_SPEC *)ob->spec)->i;
383 * You can change the max number of items if you want.
385 void fl_set_bmtable_maxitems(FL_OBJECT * ob, int i)
387 if (i > 0 && (BMTABLE_SPEC *)ob->spec)
388 ((BMTABLE_SPEC *)ob->spec)->maxi = i;
392 int fl_get_bmtable_maxitems(FL_OBJECT * ob)
394 if ((BMTABLE_SPEC *)ob->spec)
395 return ((BMTABLE_SPEC *)ob->spec)->maxi;
401 void fl_replace_bmtable_item(FL_OBJECT * ob, int id, int cw, int ch, char * data)
403 fprintf(stderr, "Replace bmtable item: Sorry, not yet implemented!\n");
407 void fl_get_bmtable_item(FL_OBJECT * ob, int id, int * cw, int * ch, char * data)
409 fprintf(stderr, "Get bmtable item: Sorry, not yet implemented!\n");
412 void fl_set_bmtable(FL_OBJECT * ob, int pushed, int pos)
414 if ((BMTABLE_SPEC *)ob->spec)
415 ((BMTABLE_SPEC *)ob->spec)->i = (pushed) ? pos: -1;
419 int fl_get_bmtable_numb(FL_OBJECT *ob)
421 if ((BMTABLE_SPEC *)ob->spec)
422 return ((BMTABLE_SPEC *)ob->spec)->mousebut;
428 Pixmap fl_get_bmtable_pixmap(FL_OBJECT * ob)
430 if ((BMTABLE_SPEC *)ob->spec)
431 return ((BMTABLE_SPEC *)ob->spec)->pix;
437 void fl_draw_bmtable_item(FL_OBJECT * ob, int i, Drawable d, int xx, int yy)
440 GC gc = fl_state[fl_get_vclass()].gc[0];
441 BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
444 x = (i % sp->nx)*sp->dx + FL_abs(ob->bw);
445 y = (i/sp->nx)*sp->dy + FL_abs(ob->bw);
446 w = sp->dx-2*FL_abs(ob->bw);
447 h = sp->dy-2*FL_abs(ob->bw);
448 XCopyArea(fl_get_display(), sp->pix, d, gc, x, y, w, h, xx, yy);
449 XFlush(fl_get_display());
453 /* Free the current bitmap and pixmap in preparation for installing a new one */
454 void fl_free_bmtable_bitmap(FL_OBJECT * ob)
456 BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
458 /* dump the temporary pixmap */
460 XFreePixmap(fl_get_display(), sp->pix);
461 XFlush(fl_get_display());
465 /* and free the space taken by bdata etc. */
466 if (sp && sp->bdata) {
467 fl_free((void*)sp->bdata);
472 /* Free the current pixmap in preparation for installing a new one */
473 /* This is needed when using data instead of files to set bitmaps */
474 void fl_free_bmtable_pixmap(FL_OBJECT *ob)
476 BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
478 /* dump the temporary pixmap */
480 XFreePixmap(fl_get_display(), sp->pix);
481 XFlush(fl_get_display());
486 #if defined(__cplusplus)