home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / dflt20.zip / MENUBAR.C < prev    next >
Text File  |  1994-12-23  |  13KB  |  412 lines

  1. /* ---------------- menubar.c ------------------ */
  2.  
  3. #include "dflat.h"
  4.  
  5. static void reset_menubar(WINDOW);
  6.  
  7. static struct {
  8.     int x1, x2;     /* position in menu bar */
  9.     char sc;        /* shortcut key value   */
  10. } menu[10];
  11. static int mctr;
  12.  
  13. MBAR *ActiveMenuBar;
  14. static MENU *ActiveMenu;
  15.  
  16. static WINDOW mwnd;
  17. static BOOL Selecting;
  18.  
  19. static WINDOW Cascaders[MAXCASCADES];
  20. static int casc;
  21. static WINDOW GetDocFocus(void);
  22.  
  23. /* ----------- SETFOCUS Message ----------- */
  24. static int SetFocusMsg(WINDOW wnd, PARAM p1)
  25. {
  26.     int rtn;
  27.     rtn = BaseWndProc(MENUBAR, wnd, SETFOCUS, p1, 0);
  28.     if (!(int)p1)
  29.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  30.     else
  31.         SendMessage(NULL, HIDE_CURSOR, 0, 0);
  32.     return rtn;
  33. }
  34.  
  35. /* --------- BUILDMENU Message --------- */
  36. static void BuildMenuMsg(WINDOW wnd, PARAM p1)
  37. {
  38.     int offset = 3;
  39.     reset_menubar(wnd);
  40.     mctr = 0;
  41.     ActiveMenuBar = (MBAR *) p1;
  42.     ActiveMenu = ActiveMenuBar->PullDown;
  43.     while (ActiveMenu->Title != NULL &&
  44.             ActiveMenu->Title != (void*)-1)    {
  45.         char *cp;
  46.         if (strlen(GetText(wnd)+offset) <
  47.                 strlen(ActiveMenu->Title)+3)
  48.             break;
  49.         GetText(wnd) = DFrealloc(GetText(wnd),
  50.             strlen(GetText(wnd))+5);
  51.         memmove(GetText(wnd) + offset+4, GetText(wnd) + offset,
  52.                 strlen(GetText(wnd))-offset+1);
  53.         CopyCommand(GetText(wnd)+offset,ActiveMenu->Title,FALSE,
  54.                 wnd->WindowColors [STD_COLOR] [BG]);
  55.         menu[mctr].x1 = offset;
  56.         offset += strlen(ActiveMenu->Title) + (3+MSPACE);
  57.         menu[mctr].x2 = offset-MSPACE;
  58.         cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
  59.         if (cp)
  60.             menu[mctr].sc = tolower(*(cp+1));
  61.         mctr++;
  62.         ActiveMenu++;
  63.     }
  64.     ActiveMenu = ActiveMenuBar->PullDown;
  65. }
  66.  
  67. /* ---------- PAINT Message ---------- */
  68. static void PaintMsg(WINDOW wnd)
  69. {
  70.     if (Selecting)
  71.         return;
  72.     if (wnd == inFocus)
  73.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  74.     SetStandardColor(wnd);
  75.     wputs(wnd, GetText(wnd), 0, 0);
  76.     if (ActiveMenuBar->ActiveSelection != -1 &&
  77.             (wnd == inFocus || mwnd != NULL))    {
  78.         char *sel, *cp;
  79.         int offset, offset1;
  80.  
  81.         sel = DFmalloc(200);
  82.         offset=menu[ActiveMenuBar->ActiveSelection].x1;
  83.         offset1=menu[ActiveMenuBar->ActiveSelection].x2;
  84.         GetText(wnd)[offset1] = '\0';
  85.         SetReverseColor(wnd);
  86.         memset(sel, '\0', 200);
  87.         strcpy(sel, GetText(wnd)+offset);
  88.         cp = strchr(sel, CHANGECOLOR);
  89.         if (cp != NULL)
  90.             *(cp + 2) = background | 0x80;
  91.         wputs(wnd, sel,
  92.             offset-ActiveMenuBar->ActiveSelection*4, 0);
  93.         GetText(wnd)[offset1] = ' ';
  94.         if (mwnd == NULL && wnd == inFocus) {
  95.             char *st = ActiveMenu
  96.                 [ActiveMenuBar->ActiveSelection].StatusText;
  97.             if (st != NULL)
  98.                 SendMessage(GetParent(wnd), ADDSTATUS,
  99.                     (PARAM)st, 0);
  100.         }
  101.         free(sel);
  102.     }
  103. }
  104.  
  105. /* ------------ KEYBOARD Message ------------- */
  106. static void KeyboardMsg(WINDOW wnd, PARAM p1)
  107. {
  108.     MENU *mnu;
  109.     int sel;
  110.     if (mwnd == NULL)    {
  111.         /* ----- search for menu bar shortcut keys ---- */
  112.         int c = tolower((int)p1);
  113.         int a = AltConvert((int)p1);
  114.         int j;
  115.         for (j = 0; j < mctr; j++)    {
  116.             if ((inFocus == wnd && menu[j].sc == c) ||
  117.                     (a && menu[j].sc == a))    {
  118.                 SendMessage(wnd, SETFOCUS, TRUE, 0);
  119.                 SendMessage(wnd, MB_SELECTION, j, 0);
  120.                 return;
  121.             }
  122.         }
  123.     }
  124.     /* -------- search for accelerator keys -------- */
  125.     mnu = ActiveMenu;
  126.     while (mnu->Title != (void *)-1)    {
  127.         struct PopDown *pd = mnu->Selections;
  128.         if (mnu->PrepMenu)
  129.             (*(mnu->PrepMenu))(GetDocFocus(), mnu);
  130.         while (pd->SelectionTitle != NULL)    {
  131.             if (pd->Accelerator == (int) p1)    {
  132.                 if (pd->Attrib & INACTIVE)
  133.                     beep();
  134.                 else    {
  135.                     if (pd->Attrib & TOGGLE)
  136.                         pd->Attrib ^= CHECKED;
  137.                     SendMessage(GetDocFocus(),
  138.                         SETFOCUS, TRUE, 0);
  139.                     PostMessage(GetParent(wnd),
  140.                         COMMAND, pd->ActionId, 0);
  141.                 }
  142.                 return;
  143.             }
  144.             pd++;
  145.         }
  146.         mnu++;
  147.     }
  148.     switch ((int)p1)    {
  149.         case F1:
  150.             if (ActiveMenu == NULL || ActiveMenuBar == NULL)
  151.                 break;
  152.             sel = ActiveMenuBar->ActiveSelection;
  153.             if (sel == -1)    {
  154.                 BaseWndProc(MENUBAR, wnd, KEYBOARD, F1, 0);
  155.                 return;
  156.             }
  157.             mnu = ActiveMenu+sel;
  158.             if (mwnd == NULL ||
  159.                     mnu->Selections[0].SelectionTitle == NULL) {
  160.                    DisplayHelp(wnd,mnu->Title);
  161.                 return;
  162.             }
  163.             break;
  164.         case '\r':
  165.             if (mwnd == NULL &&
  166.                     ActiveMenuBar->ActiveSelection != -1)
  167.                 SendMessage(wnd, MB_SELECTION,
  168.                     ActiveMenuBar->ActiveSelection, 0);
  169.             break;
  170.         case F10:
  171.             if (wnd != inFocus && mwnd == NULL)    {
  172.                 SendMessage(wnd, SETFOCUS, TRUE, 0);
  173.                 if ( ActiveMenuBar->ActiveSelection == -1)
  174.                     ActiveMenuBar->ActiveSelection = 0;
  175.                 SendMessage(wnd, PAINT, 0, 0);
  176.                 break;
  177.             }
  178.             /* ------- fall through ------- */
  179.         case ESC:
  180.             if (inFocus == wnd && mwnd == NULL)    {
  181.                 ActiveMenuBar->ActiveSelection = -1;
  182.                 SendMessage(GetDocFocus(),SETFOCUS,TRUE,0);
  183.                 SendMessage(wnd, PAINT, 0, 0);
  184.             }
  185.             break;
  186.         case FWD:
  187.             ActiveMenuBar->ActiveSelection++;
  188.             if (ActiveMenuBar->ActiveSelection == mctr)
  189.                 ActiveMenuBar->ActiveSelection = 0;
  190.             if (mwnd != NULL)
  191.                 SendMessage(wnd, MB_SELECTION,
  192.                     ActiveMenuBar->ActiveSelection, 0);
  193.             else 
  194.                 SendMessage(wnd, PAINT, 0, 0);
  195.             break;
  196.         case BS:
  197.             if (ActiveMenuBar->ActiveSelection == 0 ||
  198.                     ActiveMenuBar->ActiveSelection == -1)
  199.                 ActiveMenuBar->ActiveSelection = mctr;
  200.             --ActiveMenuBar->ActiveSelection;
  201.             if (mwnd != NULL)
  202.                 SendMessage(wnd, MB_SELECTION,
  203.                     ActiveMenuBar->ActiveSelection, 0);
  204.             else 
  205.                 SendMessage(wnd, PAINT, 0, 0);
  206.             break;
  207.         default:
  208.             break;
  209.     }
  210. }
  211.  
  212. /* --------------- LEFT_BUTTON Message ---------- */
  213. static void LeftButtonMsg(WINDOW wnd, PARAM p1)
  214. {
  215.     int i;
  216.     int mx = (int) p1 - GetLeft(wnd);
  217.     /* --- compute the selection that the left button hit --- */
  218.     for (i = 0; i < mctr; i++)
  219.         if (mx >= menu[i].x1-4*i &&
  220.                 mx <= menu[i].x2-4*i-5)
  221.             break;
  222.     if (i < mctr)
  223.         if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL)
  224.             SendMessage(wnd, MB_SELECTION, i, 0);
  225. }
  226.  
  227. /* -------------- MB_SELECTION Message -------------- */
  228. static void SelectionMsg(WINDOW wnd, PARAM p1, PARAM p2)
  229. {
  230.     int wd, mx, my;
  231.     MENU *mnu;
  232.  
  233.     if (!p2)    {
  234.         ActiveMenuBar->ActiveSelection = -1;
  235.         SendMessage(wnd, PAINT, 0, 0);
  236.     }
  237.     Selecting = TRUE;
  238.     mnu = ActiveMenu+(int)p1;
  239.     if (mnu->PrepMenu != NULL)
  240.         (*(mnu->PrepMenu))(GetDocFocus(), mnu);
  241.     wd = MenuWidth(mnu->Selections);
  242.     if (p2)    {
  243.         int brd = GetRight(wnd);
  244.         mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1;
  245.         if (mx + wd > brd)
  246.             mx = brd - wd;
  247.         my = GetTop(mwnd) + mwnd->selection;
  248.     }
  249.     else    {
  250.         int offset = menu[(int)p1].x1 - 4 * (int)p1;
  251.         if (mwnd != NULL)
  252.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  253.         ActiveMenuBar->ActiveSelection = (int) p1;
  254.         if (offset > WindowWidth(wnd)-wd)
  255.             offset = WindowWidth(wnd)-wd;
  256.         mx = GetLeft(wnd)+offset;
  257.         my = GetTop(wnd)+1;
  258.     }
  259.     mwnd = CreateWindow(POPDOWNMENU, NULL,
  260.                 mx, my,
  261.                 MenuHeight(mnu->Selections),
  262.                 wd,
  263.                 NULL,
  264.                 wnd,
  265.                 NULL,
  266.                 SHADOW);
  267.     if (!p2)    {
  268.         Selecting = FALSE;
  269.         SendMessage(wnd, PAINT, 0, 0);
  270.         Selecting = TRUE;
  271.     }
  272.     if (mnu->Selections[0].SelectionTitle != NULL)    {
  273.         SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
  274.         SendMessage(mwnd, SETFOCUS, TRUE, 0);
  275.         SendMessage(mwnd, SHOW_WINDOW, 0, 0);
  276.     }
  277.     Selecting = FALSE;
  278. }
  279.  
  280. /* --------- COMMAND Message ---------- */
  281. static void CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
  282. {
  283.     if (p1 == ID_HELP)    {
  284.         BaseWndProc(MENUBAR, wnd, COMMAND, p1, p2);
  285.         return;
  286.     }
  287.     if (isCascadedCommand(ActiveMenuBar, (int)p1))    {
  288.         /* find the cascaded menu based on command id in p1 */
  289.         MENU *mnu = ActiveMenu+mctr;
  290.         while (mnu->Title != (void *)-1)    {
  291.             if (mnu->CascadeId == (int) p1)    {
  292.                 if (casc < MAXCASCADES)    {
  293.                     Cascaders[casc++] = mwnd;
  294.                     SendMessage(wnd, MB_SELECTION,
  295.                         (PARAM)(mnu-ActiveMenu), TRUE);
  296.                 }
  297.                 break;
  298.             }
  299.             mnu++;
  300.         }
  301.     }
  302.     else     {
  303.         if (mwnd != NULL)
  304.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  305.         SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
  306.         PostMessage(GetParent(wnd), COMMAND, p1, p2);
  307.     }
  308. }
  309.  
  310. /* --------------- CLOSE_POPDOWN Message --------------- */
  311. static void ClosePopdownMsg(WINDOW wnd)
  312. {
  313.     if (casc > 0)
  314.         SendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0);
  315.     else     {
  316.         mwnd = NULL;
  317.         ActiveMenuBar->ActiveSelection = -1;
  318.         if (!Selecting)    {
  319.             SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
  320.             SendMessage(wnd, PAINT, 0, 0);
  321.         }
  322.     }
  323. }
  324.  
  325. /* ---------------- CLOSE_WINDOW Message --------------- */
  326. static void CloseWindowMsg(WINDOW wnd)
  327. {
  328.     if (GetText(wnd) != NULL)    {
  329.         free(GetText(wnd));
  330.         GetText(wnd) = NULL;
  331.     }
  332.     mctr = 0;
  333.     ActiveMenuBar->ActiveSelection = -1;
  334.     ActiveMenu = NULL;
  335.     ActiveMenuBar = NULL;
  336. }
  337.  
  338. /* --- Window processing module for MENUBAR window class --- */
  339. int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  340. {
  341.     int rtn;
  342.  
  343.     switch (msg)    {
  344.         case CREATE_WINDOW:
  345.             reset_menubar(wnd);
  346.             break;
  347.         case SETFOCUS:
  348.             return SetFocusMsg(wnd, p1);
  349.         case BUILDMENU:
  350.             BuildMenuMsg(wnd, p1);
  351.             break;
  352.         case PAINT:    
  353.             if (!isVisible(wnd) || GetText(wnd) == NULL)
  354.                 break;
  355.             PaintMsg(wnd);
  356.             return FALSE;
  357.         case BORDER:
  358.             if (mwnd == NULL)
  359.                 SendMessage(wnd, PAINT, 0, 0);
  360.             return TRUE;
  361.         case KEYBOARD:
  362.             KeyboardMsg(wnd, p1);
  363.             return TRUE;
  364.         case LEFT_BUTTON:
  365.             LeftButtonMsg(wnd, p1);
  366.             return TRUE;
  367.         case MB_SELECTION:
  368.             SelectionMsg(wnd, p1, p2);
  369.             break;
  370.         case COMMAND:
  371.             CommandMsg(wnd, p1, p2);
  372.             return TRUE;
  373.         case INSIDE_WINDOW:
  374.             return InsideRect(p1, p2, WindowRect(wnd));
  375.         case CLOSE_POPDOWN:
  376.             ClosePopdownMsg(wnd);
  377.             return TRUE;
  378.         case CLOSE_WINDOW:
  379.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  380.             CloseWindowMsg(wnd);
  381.             return rtn;
  382.         default:
  383.             break;
  384.     }
  385.     return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  386. }
  387.  
  388. /* ------------- reset the MENUBAR -------------- */
  389. static void reset_menubar(WINDOW wnd)
  390. {
  391.     GetText(wnd) = DFrealloc(GetText(wnd), SCREENWIDTH+5);
  392.     memset(GetText(wnd), ' ', SCREENWIDTH);
  393.     *(GetText(wnd)+WindowWidth(wnd)) = '\0';
  394. }
  395.  
  396. static WINDOW GetDocFocus(void)
  397. {
  398.     WINDOW wnd = ApplicationWindow;
  399.     if (wnd != NULL)    {
  400.         wnd = LastWindow(wnd);
  401.         while (wnd != NULL && (GetClass(wnd) == MENUBAR ||
  402.                             GetClass(wnd) == STATUSBAR))
  403.             wnd = PrevWindow(wnd);
  404.         if (wnd != NULL)
  405.             while (wnd->childfocus != NULL)
  406.                 wnd = wnd->childfocus;
  407.     }
  408.     return wnd ? wnd : ApplicationWindow;
  409. }
  410.  
  411. 
  412.