home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 05 / d_flat / menubar.c < prev    next >
Text File  |  1991-02-18  |  7KB  |  279 lines

  1. /* ---------------- menubar.c -------------- */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include "dflat.h"
  8.  
  9. static void reset_menubar(void);
  10. static void ClosePopDown(void);
  11. static int TestGlobalKeys(PARAM, PARAM);
  12.  
  13. static char *menubar;
  14.  
  15. static struct {
  16.     int x1, x2;        /* position in menu bar */
  17.     char sc;        /* shortcut key value   */
  18. } menu[10];
  19. static int mctr;
  20.  
  21. MENU *ActiveMenu;
  22. int ActiveSelection = -1;
  23.  
  24. static WINDOW mwnd = NULL;
  25.  
  26. #define MSPACE 2
  27.  
  28. int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  29. {
  30.     int offset = 3, wd, offset1, i, j;
  31.     int mx = (int) p1 - GetLeft(wnd);
  32.     MENU *mnu;
  33.  
  34.     switch (msg)    {
  35.         case CREATE_WINDOW:
  36.             reset_menubar();
  37.             PostMessage(wnd, PAINT, 0, 0);
  38.             break;
  39.         case COMMAND:
  40.             PostMessage(GetParent(wnd), msg, p1, p2);
  41.             return FALSE;
  42.         case SETFOCUS:
  43.             if (p1)    {
  44.                 if (!p2)
  45.                     return FALSE;
  46.                 else     {
  47.                     /* --- accept the focus only if there are no others --- */
  48.                     WINDOW wnd1 = Focus.FirstWindow;
  49.                     while (wnd1 != NULLWND)    {
  50.                         if (wnd != wnd1 && GetParent(wnd) == GetParent(wnd1))
  51.                             break;
  52.                         wnd1 = NextWindow(wnd1);
  53.                     }
  54.                     if (wnd1 != NULLWND)
  55.                         return FALSE;
  56.                 }
  57.             }
  58.             break;
  59.         case BUILDMENU:
  60.             reset_menubar();
  61.             mctr = 0;
  62.             ActiveMenu = (MENU *) p1;
  63.             while (ActiveMenu->Title != NULL)    {
  64.                 char *cp;
  65.                 menubar = realloc(menubar, strlen(menubar)+5);
  66.                 memmove(menubar + offset+4, menubar + offset, strlen(menubar)-offset+1);
  67.                 CopyCommand(menubar+offset, ActiveMenu->Title, FALSE, cfg.clr.MenuBarBG);
  68.                 menu[mctr].x1 = offset;
  69.                 offset += strlen(ActiveMenu->Title) + (3+MSPACE);
  70.                 menu[mctr].x2 = offset-MSPACE;
  71.                 cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
  72.                 if (cp)
  73.                     menu[mctr].sc = tolower(*(cp+1));
  74.                 ActiveMenu++;
  75.                 mctr++;
  76.             }
  77.             ActiveMenu = (MENU *) p1;
  78.             break;
  79.         case PAINT:
  80.             if (!isVisible(wnd))
  81.                 break;
  82.             SetStandardColor(wnd);
  83.             writefull(wnd, menubar, 0);
  84.             if (ActiveSelection != -1)    {
  85.                 char sel[80], *cp;
  86.                 offset = menu[ActiveSelection].x1;
  87.                 offset1 = menu[ActiveSelection].x2;
  88.                 menubar[offset1] = '\0';
  89.                 SetReverseColor(wnd);
  90.                 memset(sel, '\0', sizeof sel);
  91.                 strcpy(sel, menubar+offset);
  92.                 cp = strchr(sel, CHANGECOLOR);
  93.                 if (cp != NULL)
  94.                     *(cp + 2) = background | 0x80;
  95.                 wputs(wnd, sel, offset-ActiveSelection*(MSPACE+2), 0);
  96.                 menubar[offset1] = ' ';
  97.             }
  98.             return FALSE;
  99.         case KEYBOARD:
  100.             if (mwnd == NULL)    {
  101.                 /* ----- search for menu bar shortcut keys ---- */
  102.                 for (i = 0; i < 26; i++)
  103.                     if ((char) p1 == altconvert[i])
  104.                         break;
  105.                 if (i < 26)    {
  106.                     for (j = 0; j < mctr; j++)    {
  107.                         if (menu[j].sc == 'a' + i)    {
  108.                             SendMessage(wnd, SELECTION, j, 0);
  109.                             return FALSE;
  110.                         }
  111.                     }
  112.                 }
  113.             }
  114.             /* -------- search for accelerator keys -------- */
  115.             mnu = ActiveMenu;
  116.             while (mnu->Title != NULL)    {
  117.  
  118.                 struct PopDown *pd = mnu->Selections;
  119.                 if (mnu->PrepMenu)
  120.                     (*(mnu->PrepMenu))(GetParent(wnd), mnu);
  121.                 while (pd->SelectionTitle != NULL)    {
  122.                     if (pd->Accelerator == (int) p1)    {
  123.                         if (pd->Attrib & INACTIVE)
  124.                             beep();
  125.                         else
  126.                             PostMessage(GetParent(wnd),
  127.                                 COMMAND, pd->ActionId, 0);
  128.                         return TRUE;
  129.                     }
  130.                     pd++;
  131.                 }
  132.                 mnu++;
  133.             }
  134.             if (TestGlobalKeys(p1, p2))
  135.                 return FALSE;
  136.             if (mwnd == NULLWND)
  137.                 return FALSE;
  138.             switch ((int)p1)    {
  139.                 case FWD:
  140.                     ActiveSelection++;
  141.                     if (ActiveSelection == mctr)
  142.                         ActiveSelection = 0;
  143.                     SendMessage(wnd, SELECTION, ActiveSelection, 0);
  144.                     return FALSE;
  145.                 case BS:
  146.                     if (ActiveSelection == 0)
  147.                         ActiveSelection = mctr;
  148.                     --ActiveSelection;
  149.                     SendMessage(wnd, SELECTION, ActiveSelection, 0);
  150.                     return FALSE;
  151.                 default:
  152.                     break;
  153.             }
  154.             if (mwnd == (void *)-1)
  155.                 return FALSE;
  156.             break;
  157.         case LEFT_BUTTON:
  158.             for (i = 0; i < mctr; i++)
  159.                 if (mx >= menu[i].x1-(MSPACE+2)*i &&
  160.                         mx <= menu[i].x2-(MSPACE+2)*i-5)
  161.                     break;
  162.             if (i < mctr)    {
  163.                 if (i != ActiveSelection || mwnd == NULL)    {
  164.                     SendMessage(wnd, SELECTION, i, 0);
  165.                     SendMessage(NULLWND, WAITMOUSE, 0, 0);
  166.                 }
  167.             }
  168.             break;
  169.         case SELECTION:
  170.             if (mwnd && mwnd != (void *)-1)
  171.                 SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  172.             mwnd = NULL;
  173.  
  174.             ActiveSelection = (int) p1;
  175.  
  176.             offset = menu[ActiveSelection].x1 -
  177.                         (MSPACE+2) * ActiveSelection;
  178.  
  179.             mnu = ActiveMenu+ActiveSelection;
  180.  
  181.             if (mnu->PrepMenu != NULL)
  182.                 (*(mnu->PrepMenu))(GetParent(wnd), mnu);
  183.  
  184.             wd = MenuWidth(mnu->Selections);
  185.  
  186.             if (offset > WindowWidth(wnd)-wd)
  187.                 offset = WindowWidth(wnd)-wd;
  188.  
  189.             if (mnu->Selections[0].SelectionTitle != NULL)    {
  190.                 mwnd = CreateWindow(POPDOWNMENU, NULL,
  191.                             GetLeft(wnd)+offset, GetTop(wnd)+1,
  192.                             MenuHeight(mnu->Selections),
  193.                             wd,
  194.                             NULL,
  195.                             wnd,
  196.                             NULL,
  197.                             0);
  198.                 AddAttribute(mwnd, SHADOW);
  199.                 SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
  200.                 SendMessage(wnd, PAINT, 0, 0);
  201.                 SendMessage(mwnd, SHOW_WINDOW, 0, 0);
  202.             }
  203.             else
  204.                 mwnd = (void *)-1;
  205.             SendMessage(wnd, PAINT, 0, 0);
  206.             break;
  207.         case BORDER:
  208.             return TRUE;
  209.         case INSIDE_WINDOW:
  210.             return InsideRect(p1, p2, WindowRect(wnd));
  211.         case CLOSE_POPDOWN:
  212.             ClosePopDown();
  213.             SendMessage(wnd, PAINT, 0, 0);
  214.             break;
  215.         case CLOSE_WINDOW:
  216.             if (menubar != NULL)
  217.                 free(menubar);
  218.             mctr = 0;
  219.             ActiveSelection = -1;
  220.             ActiveMenu = NULL;
  221.             break;
  222.         default:
  223.             break;
  224.     }
  225.     return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  226. }
  227.  
  228. static void reset_menubar(void)
  229. {
  230.     menubar = realloc(menubar, SCREENWIDTH+5);
  231.     memset(menubar, ' ', SCREENWIDTH);
  232.     *(menubar+SCREENWIDTH) = '\0';
  233. }
  234.  
  235. static void ClosePopDown(void)
  236. {
  237.     ActiveSelection = -1;
  238.     mwnd = NULLWND;
  239. }
  240.  
  241. static int TestGlobalKeys(PARAM p1, PARAM p2)
  242. {
  243.     switch ((int)p1)    {
  244.         case ALT_F6:
  245.             if (GetClass(inFocus) != MENUBAR &&
  246.                     GetClass(inFocus) != POPDOWNMENU)
  247.                 SetNextFocus(inFocus, FALSE);
  248.             return TRUE;
  249.         case ALT_HYPHEN:
  250.             if (GetClass(inFocus) == POPDOWNMENU)
  251.                 SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
  252.             if (GetClass(GetParent(inFocus)) == APPLICATION)
  253.                 BuildSystemMenu(GetParent(inFocus));
  254.             return TRUE;
  255.         case ' ':
  256.             if (p2 & ALTKEY)    {
  257.                 if (GetClass(inFocus) == POPDOWNMENU)
  258.                     SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
  259.                 if (GetClass(inFocus) != MENUBAR &&
  260.                         TestAttribute(inFocus, TITLEBAR) &&
  261.                             TestAttribute(inFocus, CONTROLBOX))
  262.                     BuildSystemMenu(inFocus);
  263.                 return TRUE;
  264.             }
  265.             break;
  266.         case ALT_F4:
  267.             if (GetClass(inFocus) != MENUBAR)
  268.                 PostMessage(inFocus, CLOSE_WINDOW, 0, 0);
  269.             else 
  270.                 PostMessage(GetParent(inFocus), CLOSE_WINDOW, 0, 0);
  271.             return TRUE;
  272.         default:
  273.             break;
  274.     }
  275.     return FALSE;
  276. }
  277.  
  278.  
  279.