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