home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / bmtable.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  12KB  |  475 lines

  1. /*
  2.  *  File:        bmtable.c
  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.
  8.  *               
  9.  *  Copyright (C) 1995,1996 Alejandro Aguilar Sierra 
  10.  *
  11.  *  You are free to use and modify this code under the terms of
  12.  *  the GNU General Public Licence version 2 or later. 
  13.  *  
  14.  */ 
  15.  
  16. #include <config.h>
  17.  
  18. //     $Id: bmtable.C,v 1.1.1.1 1998/04/23 16:02:48 larsbj Exp $    
  19.  
  20. #if !defined(lint) && !defined(WITH_WARNINGS)
  21. static char vcid[] = "$Id: bmtable.C,v 1.1.1.1 1998/04/23 16:02:48 larsbj Exp $";
  22. #endif /* lint */
  23.  
  24. #include <stdlib.h>
  25. #include "bmtable.h"
  26. #include XPM_H_LOCATION
  27.  
  28. typedef struct   {   
  29.    int nx, ny;   /* Dimensions of the table */
  30.    int dx, dy;   /* Size of each item */ 
  31.    int bx, by;   /* Bitmap's position */
  32.    int bw, bh;   /* Bitmap dimensions */
  33.    char* bdata;  /* Bitmap data */
  34.    int maxi;     /* Number of items */
  35.    int i;        /* Current position */
  36.    int mousebut; /* mouse button pushed */  
  37.    Pixmap pix;   /* Pixmap from data (temporal) */
  38. } BMTABLE_SPEC;
  39.                  
  40.  
  41. static int handle_bitmaptable(FL_OBJECT *ob, int event, FL_Coord mx, 
  42.                   FL_Coord my, int key, void *xev);
  43.  
  44.  
  45. FL_OBJECT *fl_create_bmtable(int type, FL_Coord x, FL_Coord y, 
  46.                  FL_Coord w, FL_Coord h, char const *label)
  47. {
  48.    FL_OBJECT *ob;
  49.    
  50.    ob = fl_make_object(FL_BMTABLE, type, x, y, w, h, label, handle_bitmaptable);
  51.    ob->boxtype = FL_BMTABLE_BOXTYPE;
  52.    ob->spec = fl_calloc(1, sizeof(BMTABLE_SPEC));
  53.    ((BMTABLE_SPEC *)ob->spec)->pix = 0;
  54.    ((BMTABLE_SPEC *)ob->spec)->bdata= 0;
  55.    ((BMTABLE_SPEC *)ob->spec)->mousebut= -1;
  56.    return ob;
  57. }
  58.  
  59.  
  60. FL_OBJECT *fl_add_bmtable(int type, FL_Coord x, FL_Coord y, 
  61.                   FL_Coord w, FL_Coord h, char const *label)
  62. {
  63.    FL_OBJECT *ob;
  64.    
  65.    ob = fl_create_bmtable(type, x, y, w,h, label);  
  66.    fl_add_object(fl_current_form, ob); 
  67.    
  68.    return ob;
  69. }
  70.  
  71.  
  72. static void draw_bitmaptable(FL_OBJECT *ob)
  73. {
  74.     int i, j, lx;
  75.     FL_Coord mx, my;
  76.     FL_Coord xx, yy, ww, hh;
  77.     BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  78.     if (!sp) return;
  79.     GC gc = fl_state[fl_get_vclass()].gc[0];
  80.    
  81.     /* draw the bounding box first */
  82.     lx = sp->maxi % sp->nx;
  83.     fl_drw_box(ob->boxtype, ob->x, ob->y, ob->w, ob->h, ob->col1, ob->bw);
  84.     if (lx) {
  85.         i = FL_abs(ob->bw);
  86.         xx = ob->x+ sp->dx*lx + i;
  87.         yy = ob->y+ (sp->ny-1)*sp->dy+i;
  88.         ww = ob->x+ob->w - xx - i;
  89.         hh = ob->y+ob->h-yy-i;
  90.         fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
  91.         fl_rectf(xx, yy, ww+i, hh+i, ob->col1);
  92.     }
  93.     
  94.     /* draw the background bitmap */
  95.     if (sp->bdata)  {
  96.         if (!sp->pix) {
  97.             sp->pix =  XCreatePixmapFromBitmapData(fl_display, fl_winget(), 
  98.                     sp->bdata, sp->bw, sp->bh,
  99.                     fl_get_flcolor(ob->lcol), fl_get_flcolor(ob->col1),
  100.                     DefaultDepth(fl_display, DefaultScreen(fl_display)));
  101.             XFlush(fl_display);
  102.         }
  103.     }
  104.     if (sp->pix) {
  105.         /* Adjust position */ 
  106.         if (sp->bx < FL_abs(ob->bw) + 1) {
  107.             xx = FL_abs(ob->bw) - sp->bx + 1;
  108.             mx = ob->x + FL_abs(ob->bw) + 1;
  109.         } else  {
  110.             xx =0;
  111.             mx = ob->x + sp->bx;
  112.         }
  113.         if (sp->by < FL_abs(ob->bw) + 1)  {     
  114.             yy = FL_abs(ob->bw) - sp->by + 1;
  115.             my = ob->y + FL_abs(ob->bw) + 1;
  116.         } else   {
  117.             yy =0;
  118.             my = ob->y + sp->by;
  119.         }                 
  120.         ww = (mx + sp->bw < ob->x + ob->w - FL_abs(ob->bw)) ? 
  121.             sp->bw: ob->x + ob->w - FL_abs(ob->bw) - mx;
  122.         hh = (my + sp->bh < ob->y + ob->h - FL_abs(ob->bw)) ?
  123.             sp->bh: ob->y + ob->h - FL_abs(ob->bw) - my; 
  124.       
  125.         i = FL_abs(ob->bw);
  126.         j = hh - ((lx) ? sp->dy+2*i: 0);
  127.         XCopyArea(fl_display, sp->pix, fl_winget(), gc, xx, yy, ww, j, mx, my);
  128.         XFlush(fl_display);
  129.         if (lx) {
  130.             XCopyArea(fl_display, sp->pix, fl_winget(), gc, xx,
  131.                       yy+j, lx*sp->dx-2*i, hh-j, mx, my+j);
  132.             XFlush(fl_display);
  133.         }
  134.     }
  135.    
  136.    
  137.     /* draw the grid if type > FLAT */
  138.     if (ob->type > FL_BMTABLE_FLAT)  {
  139.         mx = ob->x + ob->w; 
  140.         my = ob->y + ob->h; 
  141.         ww = ob->w; 
  142.         for (yy=ob->y; yy<=my; yy+=sp->dy) {
  143.             if (ob->boxtype!=FL_FLAT_BOX && (yy==ob->y || yy>my-sp->dy)) 
  144.                 continue;
  145.             if (lx>0 && yy>=my-sp->dy - sp->dy/2)
  146.                 ww = lx*sp->dx;
  147.             fl_diagline(ob->x, yy, ww, 1, FL_BOTTOM_BCOL); 
  148.             fl_diagline(ob->x, yy+1, ww-2, 1, FL_TOP_BCOL); 
  149.         }       
  150.         hh = ob->h;
  151.         for (xx=ob->x; xx<=mx; xx+=sp->dx)  {
  152.             if (ob->boxtype!=FL_FLAT_BOX && (xx==ob->x || xx>mx-sp->dx))
  153.                 continue;
  154.             if (lx>0 && xx>=ob->x+lx*sp->dx)
  155.                 hh = (sp->ny-1)*sp->dy;
  156.             fl_diagline(xx, ob->y, 1, hh, FL_RIGHT_BCOL);
  157.             fl_diagline(xx+1, ob->y+1, 1, hh-2, FL_LEFT_BCOL);
  158.         }     
  159.     }  
  160.    
  161.     /* Simulate a pushed button */
  162.     if (ob->pushed && 0 <= sp->i && sp->i < sp->maxi)  {  
  163.         i = sp->i % sp->nx;
  164.         j = sp->i/sp->nx;
  165.         ww = sp->dx-2*FL_abs(ob->bw);
  166.         hh = sp->dy-2*FL_abs(ob->bw);
  167.         xx = ob->x + sp->dx*i + FL_abs(ob->bw);
  168.         yy = ob->y + sp->dy*j + FL_abs(ob->bw);
  169.         fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
  170.     }
  171. }
  172.  
  173.  
  174. static int handle_bitmaptable(FL_OBJECT *ob, int event, FL_Coord mx, 
  175.                   FL_Coord my, int key, void */*xev*/)
  176. {
  177.     int i, j;
  178.     BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  179.    
  180.     switch (event)  {
  181.     case FL_DRAW: 
  182.         draw_bitmaptable(ob);
  183.         break;
  184.     case FL_MOUSE:
  185.         if (!ob->belowmouse) {    /* This never happens. Why? */
  186.             sp->i = -1;
  187.             fl_redraw_object(ob);
  188.             break;
  189.         }
  190.         i = (mx - ob->x)/sp->dx;  j = (my - ob->y)/sp->dy;
  191.         if (i>=0 && i< sp->nx && j>=0 && j< sp->ny)   {
  192.             i += j*sp->nx;
  193.             if (i >= sp->maxi) i = -1;
  194.             if (sp->i !=  i)  {
  195.                 sp->i = i;
  196.                 fl_redraw_object(ob);
  197.             }
  198.         }
  199.         break;        
  200.     case FL_PUSH:
  201.         sp->mousebut = key;
  202.         i = (mx - ob->x)/sp->dx + ((my - ob->y)/sp->dy)*sp->nx; 
  203.         if (0 <= i && i < sp->maxi)  {
  204.             sp->i =  i;
  205.             fl_redraw_object(ob);
  206.         } else
  207.             sp->i =  -1; 
  208.         break;
  209.     case FL_RELEASE:    
  210.         fl_redraw_object(ob);
  211.         return 1;
  212.     case FL_FREEMEM:
  213.         if (sp->pix) {
  214.             XFreePixmap(fl_display, sp->pix);
  215.             XFlush(fl_display);
  216.         }
  217.         fl_free(((BMTABLE_SPEC*)ob->spec));      
  218.         break;
  219.     }
  220.     return 0;
  221. }
  222.  
  223.  
  224. /*
  225.  * The table has nx columns of dx width each and ny rows of dy height each. 
  226.  * Initially the position of the firts item is supposed to be the same that
  227.  * the object position (x, y), and the number of items is supposed to be
  228.  * exactly nx*ny.
  229.  * 
  230.  * The user could change these later. See below.
  231.  */ 
  232. void fl_set_bmtable_data(FL_OBJECT *ob, int nx, int ny, int bw, int bh, 
  233.             unsigned char *bdata)
  234. {
  235.    BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  236.    if (sp) {
  237.      sp->nx = nx;
  238.      sp->ny = ny; 
  239.      sp->bx = FL_abs(ob->bw);
  240.      sp->by = FL_abs(ob->bw);
  241.      sp->dx = ob->w/nx; 
  242.      sp->dy = ob->h/ny;
  243.      sp->i = -1;
  244.      sp->maxi = sp->nx * sp->ny;
  245.      sp->bw = bw;
  246.      sp->bh = bh;
  247.      sp->bdata = (char*)bdata;
  248.    }
  249. }
  250.  
  251.  
  252. void fl_set_bmtable_pixmap_data(FL_OBJECT *ob, int nx, int ny,
  253.             char **pdata)
  254. {
  255.     BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  256.     if (sp) {
  257.         sp->nx = nx;
  258.         sp->ny = ny; 
  259.         sp->bx = FL_abs(ob->bw);
  260.         sp->by = FL_abs(ob->bw);
  261.         sp->dx = ob->w/nx; 
  262.         sp->dy = ob->h/ny;
  263.         sp->i = -1;
  264.         sp->maxi = sp->nx * sp->ny;
  265.         sp->bdata = 0;
  266.         Pixmap dummy_shapemask = 0;
  267.         XpmAttributes dummy_attributes= {0};
  268.         if (XCreatePixmapFromData(fl_display, fl_winget(), pdata,
  269.                                   &(sp->pix), &dummy_shapemask,
  270.                                   &dummy_attributes) == XpmSuccess) {
  271.             sp->bw = dummy_attributes.width;
  272.             sp->bh = dummy_attributes.height;
  273.             XpmFreeAttributes(&dummy_attributes);
  274.             if (dummy_shapemask) {
  275.                 XFreePixmap(fl_display, dummy_shapemask);
  276.             }
  277.         }
  278.         XFlush(fl_display);
  279.     }
  280. }
  281.  
  282.  
  283. /*
  284.  *  This function works only for X11R6 or later
  285.  */
  286. #if XlibSpecificationRelease > 5 
  287.  
  288. void fl_set_bmtable_file(FL_OBJECT *ob, int nx, int ny, char const *filename)
  289. {    
  290.    int bw, bh, xh, yh;
  291.    char *bdata;
  292.    
  293.    if(XReadBitmapFileData(filename, (unsigned int *) &bw, (unsigned int *) &bh,
  294.         (unsigned char **) &bdata, &xh, &yh)==BitmapSuccess)
  295.      fl_set_bmtable_data(ob, nx, ny, bw, bh, bdata);
  296.    XFlush(fl_display);
  297. }
  298.  
  299. #else
  300.  
  301. void fl_set_bmtable_file(FL_OBJECT *, int, int, char const *) 
  302. {
  303.   fprintf(stderr, "Set bmtable file: Sorry, I need X11 release 6 to do " 
  304.        "work!\n");
  305. }
  306.  
  307. #endif
  308.  
  309.  
  310.  
  311. void fl_set_bmtable_pixmap_file(FL_OBJECT *ob, int nx, int ny, char const *filename)
  312. {    
  313.     BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  314.     if (sp) {
  315.         sp->nx = nx;
  316.         sp->ny = ny; 
  317.         sp->bx = FL_abs(ob->bw);
  318.         sp->by = FL_abs(ob->bw);
  319.         sp->dx = ob->w/nx; 
  320.         sp->dy = ob->h/ny;
  321.         sp->i = -1;
  322.         sp->maxi = sp->nx * sp->ny;
  323.         sp->bdata = 0;
  324.  
  325.         Pixmap dummy_shapemask = 0;
  326.         XpmAttributes dummy_attributes = {0};
  327.    
  328.         if (XReadPixmapFile(fl_display, fl_winget(), (char *)filename,
  329.                             &(sp->pix), &dummy_shapemask,
  330.                             &dummy_attributes) == XpmSuccess) {
  331.             sp->bw = dummy_attributes.width;
  332.             sp->bh = dummy_attributes.height;
  333.             XpmFreeAttributes(&dummy_attributes);
  334.             if (dummy_shapemask) {
  335.                 XFreePixmap(fl_display, dummy_shapemask);
  336.             }
  337.         }
  338.         XFlush(fl_display);
  339.     }
  340. }
  341.  
  342.  
  343. /*
  344.  * This function allows to adjust the position of the first item and its
  345.  * size (dx, dy). The input values are incremental, not absolute.
  346.  */
  347. void fl_set_bmtable_adjust(FL_OBJECT *ob, int px, int py, int dx, int dy)
  348. {
  349.    BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;   
  350.    if (sp) {
  351.      sp->bx += px;
  352.      sp->by += py;                         
  353.      sp->dx += dx;
  354.      sp->dy += dy;
  355.    }
  356. }
  357.  
  358. /* 
  359.  * This function returns the table's selected position.
  360.  */
  361. int fl_get_bmtable(FL_OBJECT *ob)
  362.    if ((BMTABLE_SPEC *)ob->spec)
  363.      return  ((BMTABLE_SPEC *)ob->spec)->i;
  364.    else 
  365.      return 0;
  366. }
  367.  
  368.  
  369. /* 
  370.  * You can change the max number of items if you want.
  371.  */
  372. void fl_set_bmtable_maxitems(FL_OBJECT *ob, int i)
  373. {
  374.    if (i>0 && (BMTABLE_SPEC *)ob->spec)
  375.      ((BMTABLE_SPEC *)ob->spec)->maxi = i;
  376. }   
  377.  
  378.  
  379. int fl_get_bmtable_maxitems(FL_OBJECT *ob)
  380. {
  381.    if ((BMTABLE_SPEC *)ob->spec)
  382.      return  ((BMTABLE_SPEC *)ob->spec)->maxi;
  383.    else
  384.      return 0;
  385. }
  386.  
  387.  
  388. void fl_replace_bmtable_item(FL_OBJECT */*ob*/, int /*id*/, int  /*cw*/, int /*ch*/, char */*data*/)
  389. {
  390.    fprintf(stderr, "Replace bmtable item: Sorry, not yet implemented!\n");
  391. }
  392.  
  393.  
  394. void fl_get_bmtable_item(FL_OBJECT */*ob*/, int /*id*/, int */*cw*/, int */*ch*/, char */*data*/)
  395. {
  396.    fprintf(stderr, "Get bmtable item: Sorry, not yet implemented!\n");
  397. }  
  398.  
  399. void fl_set_bmtable(FL_OBJECT *ob, int pushed, int pos)
  400. {
  401.    if ((BMTABLE_SPEC *)ob->spec)
  402.      ((BMTABLE_SPEC *)ob->spec)->i = (pushed) ? pos: -1;
  403. }
  404.  
  405.  
  406. int fl_get_bmtable_numb(FL_OBJECT *ob)
  407. {
  408.    if ((BMTABLE_SPEC *)ob->spec)
  409.      return ((BMTABLE_SPEC *)ob->spec)->mousebut;
  410.    else
  411.      return 0;
  412. }
  413.  
  414.  
  415. Pixmap fl_get_bmtable_pixmap(FL_OBJECT *ob)
  416. {
  417.    if ((BMTABLE_SPEC *)ob->spec)
  418.      return ((BMTABLE_SPEC *)ob->spec)->pix;
  419.    else
  420.      return 0;
  421. }
  422.  
  423.  
  424. void fl_draw_bmtable_item(FL_OBJECT *ob, int i, Drawable d, int xx, int yy)
  425. {
  426.    int x, y, w, h;
  427.    GC gc = fl_state[fl_get_vclass()].gc[0];
  428.    BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  429.    
  430.    if (sp && sp->pix) {
  431.       x = (i % sp->nx)*sp->dx + FL_abs(ob->bw);
  432.       y = (i/sp->nx)*sp->dy + FL_abs(ob->bw);
  433.       w = sp->dx-2*FL_abs(ob->bw);
  434.       h = sp->dy-2*FL_abs(ob->bw);     
  435.       XCopyArea(fl_display, sp->pix, d, gc, x, y, w, h, xx, yy);
  436.       XFlush(fl_display);
  437.    }
  438. }
  439.  
  440. /* Free the current bitmap and pixmap in preparation for installing a new one */
  441. void fl_free_bmtable_bitmap(FL_OBJECT *ob)
  442. {
  443.   BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  444.  
  445.   /* dump the temporary pixmap */
  446.   if (sp && sp->pix) { 
  447.     XFreePixmap(fl_display, sp->pix);
  448.     XFlush(fl_display);
  449.     sp->pix = 0;
  450.   }
  451.  
  452.   /* and free the space taken by bdata etc. */
  453.   if (sp && sp->bdata) {
  454.     fl_free(sp->bdata);
  455.     sp->bdata = 0;
  456.   }
  457. }
  458.  
  459. /* Free the current pixmap in preparation for installing a new one */
  460. /* This is needed when using data instead of files to set bitmaps  */
  461. void fl_free_bmtable_pixmap(FL_OBJECT *ob)
  462. {
  463.   BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
  464.  
  465.   /* dump the temporary pixmap */
  466.   if (sp && sp->pix) { 
  467.     XFreePixmap(fl_display, sp->pix);
  468.     XFlush(fl_display);
  469.     sp->pix = 0;
  470.   }
  471. }
  472.  
  473.  
  474.