home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Enlightenment / enl_BETA-0.13.src.tar.gz / enl_BETA-0.13.src.tar / enl-0.13 / menus.c < prev    next >
C/C++ Source or Header  |  1997-11-17  |  14KB  |  516 lines

  1. #include "enlightenment.h"
  2.  
  3. void InitMenuList() {
  4.     mlist.next=NULL;
  5.     mlist.menu=NULL;
  6.     active_mlist.next=NULL;
  7.     active_mlist.menu=NULL;
  8. }
  9.  
  10. void AddMenuToList(Menu *menu) {
  11.     struct menulist *ptr;
  12.  
  13.     ptr=malloc(sizeof(struct menulist));
  14.     ptr->menu=menu;
  15.     ptr->next=mlist.next;
  16.     mlist.next=ptr;
  17. }
  18.  
  19. Menu *FindMenu(char *name) {
  20.    struct menulist *ptr;
  21.  
  22.     ptr=mlist.next;
  23.     while(ptr) {
  24.         if (!strcmp(name,ptr->menu->name)) return ptr->menu;
  25.             ptr=ptr->next;
  26.     }
  27.     return NULL;
  28. }
  29.  
  30. Menu *GetMenuWin(Window w) {
  31.     struct menulist *ptr;
  32.  
  33.     ptr=mlist.next;
  34.     while(ptr) {
  35.         if (w==ptr->menu->win) 
  36.             return ptr->menu;
  37.         ptr=ptr->next;
  38.     }
  39.     return NULL;
  40. }
  41.  
  42. void AddActiveMenuToList(Menu *menu) {
  43.     struct menulist *ptr;
  44.  
  45.     ptr=malloc(sizeof(struct menulist));
  46.     ptr->menu=menu;
  47.     ptr->next=active_mlist.next;
  48.     active_mlist.next=ptr;
  49.  
  50. }
  51.  
  52. void DeleteToActiveMenu(char *name) {
  53.     struct menulist *ptr;
  54.     struct menulist *pptr;
  55.  
  56.     ptr=active_mlist.next;
  57.     while(ptr) {
  58.         if (!strcmp(name,ptr->menu->name)) {
  59.             active_mlist.next=ptr;
  60.             return;
  61.         }
  62.         pptr=ptr;
  63.         HideMenu(ptr->menu);
  64.         ptr=ptr->next;
  65.         free(pptr);
  66.     }
  67.     active_mlist.next=NULL;
  68. }
  69.  
  70. Menu *GetActiveMenuWin(Window w) {
  71.     struct menulist *ptr;
  72.  
  73.     ptr=mlist.next;
  74.     while(ptr) {
  75.         if (w==ptr->menu->win) 
  76.             return ptr->menu;
  77.         ptr=ptr->next;
  78.     }
  79.     return NULL;
  80. }
  81.  
  82. Menu *CreateMenu(char *name, int type, int num_items) {
  83.     Menu *m;
  84.     int i;
  85.  
  86.     m=malloc(sizeof(Menu));
  87.     if (!m) return NULL;
  88.     m->type=type;
  89.     m->num_items=num_items;
  90.     m->width=0;
  91.     m->height=0;
  92.     if (name) 
  93.         strncpy(m->name,name,255);
  94.     else 
  95.         name[0]=0; 
  96.     m->popup_x=0;
  97.     m->popup_y=0;
  98.     m->win=0;
  99.     m->mask=0;
  100.     m->items=malloc(sizeof(MenuItem *)*num_items);
  101.     m->sel_item=-1;
  102.     for (i=0;i<num_items;i++) {
  103.         m->items[i]=NULL;
  104.     }
  105.     return m;
  106. }
  107.  
  108. void AddMenuItem(Menu *m, MenuItem* mi) {
  109.  
  110.     /* modified 07/21/97 Troy Pesola (trp@cyberoptics.com) */
  111.  
  112.     int i,found=0;
  113.     /* char ss[4096]; */
  114.     MenuItem **items;
  115.  
  116.     for (i=0;i<m->num_items;i++) {
  117.         if (!m->items[i]) {
  118.             m->items[i]=mi;
  119.             found=1;
  120.             break;
  121.         }
  122.     }
  123.     if(!found) {
  124.         items = (MenuItem**)malloc(sizeof(MenuItem*) * m->num_items+1);
  125.         memcpy(items,m->items, (sizeof(MenuItem*) * m->num_items));
  126.         items[m->num_items++] = mi;
  127.         free(m->items);
  128.         m->items = items;
  129.  
  130.         /* step up the size if needed */
  131.         if (m->width<(mi->x+mi->width))
  132.             m->width = mi->x+mi->width;
  133.         if (m->height<(mi->y+mi->height))
  134.             m->height = mi->y+mi->height;
  135.     }
  136. }
  137.  
  138. void RenderMenu(Menu *m) {
  139.     int i;
  140.     XGCValues gcv;
  141.     GC gc;
  142.     GC or;
  143.  
  144.     /* added 07/24/97 by Troy Pesola (trp@cyberoptics.com) */
  145.     if (m->static_num_items) {
  146.         /* map the window to the root */
  147.         for (i=0; i<m->static_num_items; i++)
  148.             XReparentWindow(disp,m->items[i]->win,root,0,0);
  149.     }
  150.  
  151.     if (m->mask) 
  152.         ImlibFreePixmap(imd,m->mask);
  153.     if (m->win) 
  154.         XDestroyWindow(disp,m->win);
  155.  
  156.     m->win=CreateBasicWin(root,0,0,m->width,m->height);
  157.     m->mask=XCreatePixmap(disp,m->win,m->width,m->height,1);
  158.  
  159.     gcv.function=GXor;
  160.     gc=XCreateGC(disp,m->mask,0,&gcv);
  161.     or=XCreateGC(disp,m->mask,GCFunction,&gcv);
  162.     XSetForeground(disp,gc,0);
  163.     XSetForeground(disp,or,1);
  164.     XFillRectangle(disp,m->mask,gc,0,0,m->width,m->height);
  165.     XSetForeground(disp,gc,1);
  166.     for(i=0;i<m->num_items;i++) {
  167.         if (m->items[i]) {
  168.             if (m->items[i]->unsel_mask)
  169.                 XCopyArea(disp,m->items[i]->unsel_mask,m->mask,or,
  170.                     0,0,m->items[i]->width,m->items[i]->height,
  171.                     m->items[i]->x,m->items[i]->y);
  172.             else
  173.                 XFillRectangle(disp,m->mask,gc,m->items[i]->x,
  174.                     m->items[i]->y,m->items[i]->width,
  175.                     m->items[i]->height);
  176.             XReparentWindow(disp,m->items[i]->win,m->win,
  177.                 m->items[i]->x,m->items[i]->y);
  178.                 XMapWindow(disp,m->items[i]->win);
  179.         }
  180.     }
  181.     XShapeCombineMask(disp,m->win,ShapeBounding,0,0,m->mask,ShapeSet);
  182.     XFreeGC(disp,gc);
  183.     XFreeGC(disp,or);
  184. }
  185.  
  186. MenuItem *CreateMenuItem(int type, 
  187.             int x, int y, int width, int height, char *text, 
  188.             int text_x, int text_y, int text_w, int text_h, 
  189.             char *unsel, ImColor *unsel_icl,
  190.             char *sel, ImColor *sel_icl) {
  191.     MenuItem *mi;
  192.     Image *im1,*im2;
  193.  
  194.     mi=malloc(sizeof(MenuItem));
  195.     mi->x=x;
  196.     mi->y=y;
  197.     mi->width=width;
  198.     mi->height=height;
  199.     mi->text=NULL;
  200.     mi->type=type;
  201.     mi->unsel_pmap=0;
  202.     mi->unsel_mask=0;
  203.     mi->sel_pmap=0;
  204.     mi->sel_mask=0;
  205.  
  206.     if (mi->type==DECOR)
  207.        sel=NULL;
  208.     mi->win=CreateWin(root,0,0,mi->width,mi->height);
  209.     im1=LoadImage(imd,unsel,unsel_icl);
  210.     ImlibRender(imd,im1,mi->width,mi->height);
  211.     mi->unsel_pmap=ImlibCopyImageToPixmap(imd,im1);
  212.     mi->unsel_mask=ImlibCopyMaskToPixmap(imd,im1);
  213.     ImlibDestroyPixmaps(imd,im1,mi->width,mi->height);
  214.     ImlibDestroyImage(imd,im1);
  215.     if (sel) {
  216.         im2=LoadImage(imd,sel,sel_icl);
  217.         ImlibRender(imd,im2,mi->width,mi->height);
  218.         mi->sel_pmap=ImlibCopyImageToPixmap(imd,im2);
  219.         mi->sel_mask=ImlibCopyMaskToPixmap(imd,im2);
  220.         ImlibDestroyImage(imd,im2);
  221.     }
  222.     if (text) {
  223.         mi->text=malloc(strlen(text)+1);
  224.         strcpy(mi->text,text);
  225.         DrawText(mi->unsel_pmap,mi->text,text_x,text_y,text_w,text_h);
  226.         if (mi->unsel_mask) 
  227.             DrawTextMask(mi->unsel_mask,mi->text,text_x,text_y,text_w,text_h);
  228.         if (mi->sel_pmap) 
  229.             DrawText(mi->sel_pmap,mi->text,text_x,text_y,text_w,text_h);
  230.         if (mi->sel_mask) 
  231.             DrawTextMask(mi->sel_mask,mi->text,text_x,text_y,text_w,text_h);
  232.     } 
  233.     XSetWindowBackgroundPixmap(disp,mi->win,mi->unsel_pmap);
  234.     if (mi->unsel_mask) 
  235.         XShapeCombineMask(disp,mi->win,ShapeBounding,0,0,mi->unsel_mask,ShapeSet);
  236.     return mi;
  237. }
  238.  
  239. MenuItem *CreateMenuWinlistItem(int type, 
  240.             int x, int y, int width, int height, char *text, 
  241.             int text_x, int text_y, int text_w, int text_h, 
  242.             char *unsel, ImColor *unsel_icl,
  243.             char *sel, ImColor *sel_icl) {
  244.     MenuItem *mi;
  245.     /* Image *im1,*im2; */
  246.     GC gc,gcm;
  247.     XGCValues gcv;
  248.  
  249.     if (!tmplt_mi) 
  250.         return NULL;
  251.     mi=malloc(sizeof(MenuItem));
  252.     mi->x=x;
  253.     mi->y=y;
  254.     mi->width=width;
  255.     mi->height=height;
  256.     mi->text=NULL;
  257.     mi->type=type;
  258.     mi->unsel_pmap=0;
  259.     mi->unsel_mask=0;
  260.     mi->sel_pmap=0;
  261.     mi->sel_mask=0;
  262.  
  263.     gc=XCreateGC(disp,tmplt_mi->unsel_pmap,0,&gcv);
  264.     if (tmplt_mi->unsel_mask) 
  265.         gcm=XCreateGC(disp,tmplt_mi->unsel_mask,0,&gcv);
  266.  
  267.     mi->win=CreateWin(root,0,0,mi->width,mi->height);
  268.     if (mi->type==DECOR) {
  269.         sel=NULL;
  270.     } else {
  271.         mi->unsel_pmap=XCreatePixmap(disp,root,mi->width,mi->height,depth);
  272.         XCopyArea(disp,tmplt_mi->unsel_pmap,mi->unsel_pmap,gc,0,0,
  273.             mi->width,mi->height,0,0);
  274.         mi->sel_pmap=XCreatePixmap(disp,root,mi->width,mi->height,depth);
  275.         XCopyArea(disp,tmplt_mi->sel_pmap,mi->sel_pmap,gc,0,0,
  276.             mi->width,mi->height,0,0);
  277.         if (tmplt_mi->unsel_mask) {
  278.             mi->unsel_mask=XCreatePixmap(disp,root,mi->width,mi->height,1);
  279.             XCopyArea(disp,tmplt_mi->unsel_mask,mi->unsel_mask,gcm,0,0,
  280.                 mi->width,mi->height,0,0);
  281.             mi->sel_mask=XCreatePixmap(disp,root,mi->width,mi->height,1);
  282.             XCopyArea(disp,tmplt_mi->sel_mask,mi->sel_mask,gcm,0,0,
  283.                 mi->width,mi->height,0,0);
  284.         }
  285.     }
  286.     if (text) {
  287.         mi->text=malloc(strlen(text)+1);
  288.         strcpy(mi->text,text);
  289.         DrawText(mi->unsel_pmap,mi->text,text_x,text_y,text_w,text_h);
  290.         if (mi->unsel_mask) 
  291.             DrawTextMask(mi->unsel_mask,mi->text,text_x,text_y,text_w,text_h);
  292.         if (mi->sel_pmap) 
  293.             DrawText(mi->sel_pmap,mi->text,text_x,text_y,text_w,text_h);
  294.         if (mi->sel_mask) 
  295.             DrawTextMask(mi->sel_mask,mi->text,text_x,text_y,text_w,text_h);
  296.     } 
  297.     XSetWindowBackgroundPixmap(disp,mi->win,mi->unsel_pmap);
  298.     if (mi->unsel_mask) 
  299.         XShapeCombineMask(disp,mi->win,ShapeBounding,0,0,
  300.                 mi->unsel_mask,ShapeSet);
  301.     XFreeGC(disp,gc);
  302.     if (tmplt_mi->unsel_mask) 
  303.         XFreeGC(disp,gcm);
  304.     return mi;
  305. }
  306.  
  307. void DrawMenuItem(Menu *m, int num, int state) {
  308.     XGCValues gcv;
  309.     GC gc;
  310.     GC or;
  311.     int i;
  312.     int in;
  313.     int inx,iny;
  314.     int xx1,xx2,yy1,yy2;
  315.  
  316.     gcv.function=GXor;
  317.     gc=XCreateGC(disp,m->mask,0,&gcv);
  318.     or=XCreateGC(disp,m->mask,GCFunction,&gcv);
  319.     XSetForeground(disp,gc,0);
  320.     XSetForeground(disp,or,1);
  321.     XFillRectangle(disp,m->mask,gc,m->items[num]->x,m->items[num]->y,
  322.             m->items[num]->width,m->items[num]->height);
  323.     XSetForeground(disp,gc,1);
  324.  
  325.     if (state==0) {
  326.         XSetWindowBackgroundPixmap(disp,m->items[num]->win,
  327.                 m->items[num]->unsel_pmap);
  328.         if (m->items[num]->unsel_mask) 
  329.             XShapeCombineMask(disp,m->items[num]->win,
  330.                     ShapeBounding,0,0,m->items[num]->unsel_mask,ShapeSet);
  331.     } else {
  332.         XSetWindowBackgroundPixmap(disp,m->items[num]->win,
  333.                 m->items[num]->sel_pmap);
  334.         if (m->items[num]->sel_mask) 
  335.             XShapeCombineMask(disp,m->items[num]->win,
  336.                     ShapeBounding,0,0,m->items[num]->sel_mask,ShapeSet);
  337.     }
  338.     XClearWindow(disp,m->items[num]->win);
  339.     xx1=m->items[num]->x;
  340.     xx2=m->items[num]->x+m->items[num]->width;
  341.     yy1=m->items[num]->y;
  342.     yy2=m->items[num]->y+m->items[num]->height;
  343.     for(i=0;i<m->num_items;i++) {
  344.         int x1,x2,y1,y2;
  345.         inx=0,iny=0;in=0;
  346.         x1=m->items[i]->x;
  347.         x2=m->items[i]->x+m->items[i]->width;
  348.         y1=m->items[i]->y;
  349.         y2=m->items[i]->y+m->items[i]->height;
  350.         if (((x1>=xx1)&&(x1<=xx2))|| ((x2>=xx1)&&(x2<=xx2))||
  351.                 ((xx1>=x1)&&(xx2<=x2))) 
  352.             inx=1;
  353.         if (((y1>=yy1)&&(y1<=yy2))|| ((y2>=yy1)&&(y2<=yy2))||
  354.                 ((yy1>=y1)&&(yy2<=y2))) 
  355.             iny=1;
  356.         if (inx&&iny) 
  357.             in=1;
  358.         if (in) {
  359.             if ((i==num)&&(m->items[i]->type!=DECOR)) {
  360.                 if (state==0) {
  361.                     if (m->items[i]->unsel_mask)
  362.                         XCopyArea(disp,m->items[i]->unsel_mask,m->mask,or,
  363.                                 0,0,m->items[i]->width,m->items[i]->height,
  364.                                 m->items[i]->x,m->items[i]->y);
  365.                     else
  366.                         XFillRectangle(disp,m->mask,gc,m->items[i]->x,
  367.                                 m->items[i]->y,m->items[i]->width,
  368.                                 m->items[i]->height);
  369.                 } else {
  370.                     if (m->items[i]->sel_mask)
  371.                         XCopyArea(disp,m->items[i]->sel_mask,m->mask,or,
  372.                                 0,0,m->items[i]->width,m->items[i]->height,
  373.                                 m->items[i]->x,m->items[i]->y);
  374.                     else if (m->items[i]->type==DECOR)
  375.                         XCopyArea(disp,m->items[i]->unsel_mask,m->mask,or,
  376.                                 0,0,m->items[i]->width,m->items[i]->height,
  377.                                 m->items[i]->x,m->items[i]->y);
  378.                     else
  379.                         XFillRectangle(disp,m->mask,gc,m->items[i]->x,
  380.                                 m->items[i]->y,m->items[i]->width,
  381.                                 m->items[i]->height);
  382.                 }
  383.             } else {
  384.                 if (m->items[i]->unsel_mask)
  385.                     XCopyArea(disp,m->items[i]->unsel_mask,m->mask,or,
  386.                             0,0,m->items[i]->width,m->items[i]->height,
  387.                             m->items[i]->x,m->items[i]->y);
  388.                 else
  389.                     XFillRectangle(disp,m->mask,gc,m->items[i]->x,
  390.                             m->items[i]->y,m->items[i]->width,
  391.                             m->items[i]->height);
  392.             }
  393.         }
  394.     }
  395.     XShapeCombineMask(disp,m->win,ShapeBounding,0,0,m->mask,ShapeSet);
  396.     XFreeGC(disp,gc);
  397.     XFreeGC(disp,or);
  398.     XSync(disp,False);
  399. }
  400.  
  401. void ShowMenu(Menu *menu) {
  402.  
  403.     /* modified 07/24/97 Troy Pesola (trp@cyberoptics.com) */
  404.     /*    --now use the window id instead of the title     */
  405.     /*    --supports having items from the loadcfg         */
  406.     /* modified 07/21/97 Troy Pesola (trp@cyberoptics.com) */
  407.  
  408.     /* int px,py; */
  409.     struct list *l;
  410.     MenuItem *mi;
  411.  
  412.     /* check for special types of menus */
  413.     if (menu->type==MENU_WINDOWLIST) {
  414.         if(!AlreadyWinListed) {
  415.         /* save the static menu items */
  416.             if (menu->num_items) {
  417.                 menu->static_items = 
  418.                     (MenuItem**)malloc(sizeof(MenuItem*) * menu->num_items);
  419.                 memcpy(menu->static_items,
  420.                         menu->items, sizeof(MenuItem*) * menu->num_items);
  421.             } else {
  422.                 menu->static_items=NULL;
  423.             }
  424.             menu->static_num_items = menu->num_items;
  425.             menu->item_x = menu->itemdelta_x * menu->num_items;
  426.             menu->item_y = menu->itemdelta_y * menu->num_items;
  427.             menu->static_item_x = menu->item_x;
  428.             menu->static_item_y = menu->item_y;
  429.             if (!tmplt_mi) {
  430.                 tmplt_mi=CreateMenuItem(ELEMENT,
  431.                         menu->item_x,menu->item_y,
  432.                         menu->item_w,menu->item_h,
  433.                         NULL, menu->itemtext_x,menu->itemtext_y,
  434.                         menu->itemtext_w,menu->itemtext_h,
  435.                         menu->item_unsel,&menu->item_unsel_icl,
  436.                         menu->item_sel,&menu->item_sel_icl);
  437.             }
  438.             /* create the menu in real time */
  439.             for (l=global_l->first; l; l=l->next) {
  440.                 if(!l->win->skip) {
  441.                     mi=CreateMenuWinlistItem(ELEMENT,
  442.                             menu->item_x,menu->item_y,
  443.                             menu->item_w,menu->item_h,
  444.                             l->win->title,
  445.                             menu->itemtext_x,menu->itemtext_y,
  446.                             menu->itemtext_w,menu->itemtext_h,
  447.                             menu->item_unsel,&menu->item_unsel_icl,
  448.                             menu->item_sel,&menu->item_sel_icl);
  449.                     menu->item_x += menu->itemdelta_x;
  450.                     menu->item_y += menu->itemdelta_y;
  451.                     mi->action.id=ACTION_RAISE;
  452.                     sprintf(mi->action.params,"%lu",l->win->frame_win);
  453.                     AddMenuItem(menu,mi);
  454.                 }
  455.             }
  456.             AlreadyWinListed=1;
  457.             RenderMenu(menu);
  458.  
  459.             /* position the menu */
  460.             XMoveWindow(disp,menu->win,menu->px,menu->py);
  461.         }
  462.     }
  463.     XRaiseWindow(disp,menu->win);
  464.     XMapWindow(disp,menu->win);
  465.     XSync(disp,False);
  466. }
  467.  
  468. void HideMenu(Menu *menu) {
  469.  
  470.     /* modified 07/24/97 Troy Pesola (trp@cyberoptics.com) */
  471.     /*   --added support for static items in the menu      */
  472.     /* modified 07/21/97 Troy Pesola (trp@cyberoptics.com) */
  473.  
  474.     XUnmapWindow(disp,menu->win);
  475.     if (menu->sel_item>=0) 
  476.         DrawMenuItem(menu,menu->sel_item,0);
  477.     menu->sel_item=-1;
  478.     XSync(disp,False);
  479.  
  480.     if (menu->type==MENU_WINDOWLIST) {
  481.         /* remove the menu items */
  482.         int i; /* cnt=0; */
  483.         for (i=menu->static_num_items; i<menu->num_items; i++) {
  484.             XDestroyWindow(disp,menu->items[i]->win);
  485.             ImlibFreePixmap(imd,menu->items[i]->unsel_pmap);
  486.             ImlibFreePixmap(imd,menu->items[i]->sel_pmap);
  487.             if (menu->items[i]->unsel_mask)
  488.                 ImlibFreePixmap(imd,menu->items[i]->unsel_mask);
  489.             if (menu->items[i]->sel_mask)
  490.                 ImlibFreePixmap(imd,menu->items[i]->sel_mask);
  491.             if (menu->items[i]->text) free(menu->items[i]->text);
  492.                 free(menu->items[i]);
  493.         }
  494.  
  495.         free(menu->items);
  496.  
  497.         /* restore the static menu items */
  498.         menu->items = menu->static_items;
  499.         menu->num_items = menu->static_num_items;
  500.         menu->item_x = menu->static_item_x;
  501.         menu->item_y = menu->static_item_y;
  502.         menu->static_items = NULL;
  503.         AlreadyWinListed=0;
  504.     }
  505. }
  506.  
  507. void HideAllMenus() {
  508.     struct menulist *ptr;
  509.  
  510.     ptr=mlist.next;
  511.     while(ptr) {
  512.         HideMenu(ptr->menu);
  513.         ptr=ptr->next;
  514.     }
  515. }
  516.