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