home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ftes46b5.zip / ftes46b5 / src / menu_text.cpp < prev    next >
C/C++ Source or Header  |  1997-05-30  |  21KB  |  667 lines

  1. /*    menu_text.cpp
  2.  *
  3.  *    Copyright (c) 1994-1996, Marko Macek
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <assert.h>
  14. #include <signal.h>
  15. #include <ctype.h>
  16. #include <stdarg.h>
  17. #include "console.h"
  18. #include "gui.h"
  19. #include "c_mode.h"
  20. #include "c_color.h"
  21.  
  22. class UpMenu {
  23. public:
  24.     class UpMenu *up;
  25.     int id;
  26.     int vert;
  27.     int x, y, w, h;
  28. };
  29.  
  30. int GetHOfsItem(int id, int cur) {
  31.     int pos = 2;
  32.     int i, len;
  33.     
  34.     for (i = 0; i < Menus[id].Count; i++) {
  35.         if (i == cur) return pos;
  36.         if (Menus[id].Items[i].Name) {
  37.             len = CStrLen(Menus[id].Items[i].Name);
  38.             pos += len + 2;
  39.         } else
  40.             pos++;
  41.     }
  42.     return -1;
  43. }
  44.  
  45. int GetHPosItem(int id, int X) {
  46.     int pos = 1;
  47.     int i, len;
  48.     
  49.     for (i = 0; i < Menus[id].Count; i++) {
  50.         if (Menus[id].Items[i].Name) {
  51.             len = CStrLen(Menus[id].Items[i].Name);
  52.             if (X >= pos && X <= pos + len + 1) return i;
  53.             pos += len + 2;
  54.         } else 
  55.             pos++;
  56.     }
  57.     return -1;
  58. }
  59.  
  60. int DrawHMenu(int x, int y, int id, int active) {
  61.     int pos = 1;
  62.     TDrawBuffer B;
  63.     int i, len;
  64.     TAttr color1, color2;
  65.     int Cols, Rows;
  66.     
  67.     ConQuerySize(&Cols, &Rows);
  68.     
  69.     MoveChar(B, 0, Cols, ' ', hcMenu_Background, Cols);
  70.     if (id != -1) {
  71.         for (i = 0; i < Menus[id].Count; i++) {
  72.             if (i == active) {
  73.                 color1 = hcMenu_ActiveItem;
  74.                 color2 = hcMenu_ActiveChar;
  75.             } else {
  76.                 color1 = hcMenu_NormalItem;
  77.                 color2 = hcMenu_NormalChar;
  78.             }
  79.             
  80.             if (Menus[id].Items[i].Name) {
  81.                 len = CStrLen(Menus[id].Items[i].Name);
  82.                 MoveChar(B, pos, Cols, ' ', color1, len + 2);
  83.                 MoveCStr(B, pos + 1, Cols, Menus[id].Items[i].Name, color1, color2, len);
  84.                 pos += len + 2;
  85.             } else {
  86.                 MoveChar(B, pos, Cols, ConGetDrawChar(DCH_V), hcMenu_Background, 1);
  87.                 pos++;
  88.             }
  89.         }
  90.     }
  91.     ConPutBox(x, y, Cols - x, 1, B);
  92.     return 1;
  93. }
  94.  
  95. int GetVPosItem(int id, int w, int X, int Y) {
  96.     if (Y <= 0 || Y > Menus[id].Count) return -1;
  97.     if (Menus[id].Items[Y - 1].Name == 0) return -1;
  98.     if (X <= 0 || X >= w - 1) return -1;
  99.     return Y - 1;
  100. }
  101.  
  102. int GetVSize(int id, int &X, int &Y) {
  103.     int xsize = 0;
  104.     int len;
  105.     
  106.     Y = Menus[id].Count;
  107.     for (int i = 0; i < Y; i++) {
  108.         len = 0;
  109.         if (Menus[id].Items[i].Name)
  110.             len = CStrLen(Menus[id].Items[i].Name);
  111.         if (len > xsize)
  112.             xsize = len;
  113.     }
  114.     X = xsize;
  115.     return 0;
  116. }
  117.  
  118.  
  119. int DrawVMenu(int x, int y, int id, int active) {
  120.     TDrawBuffer B;
  121.     int i, len;
  122.     TAttr color1, color2;
  123.     int w, h;
  124.     
  125.     if (id == -1) return -1;
  126.     
  127.     GetVSize(id, w, h);
  128.     w += 4;
  129.     h += 2;
  130.     
  131.     MoveChar(B, 0, w, ConGetDrawChar(DCH_H), hcMenu_Background, w);
  132.     MoveCh(B, ConGetDrawChar(DCH_C1), hcMenu_Background, 1);
  133.     MoveCh(B + w - 1, ConGetDrawChar(DCH_C2), hcMenu_Background, 1);
  134.     ConPutBox(x, y, w, 1, B);
  135.     for (i = 0; i < Menus[id].Count; i++) {
  136.         if (i == active) {
  137.             color1 = hcMenu_ActiveItem;
  138.             color2 = hcMenu_ActiveChar;
  139.         } else {
  140.             color1 = hcMenu_NormalItem;
  141.             color2 = hcMenu_NormalChar;
  142.         }
  143.         if (Menus[id].Items[i].Name) {
  144.             char name[128];
  145.             char *arg = 0;
  146.             int len2 = 0;
  147.             
  148.             strcpy(name, Menus[id].Items[i].Name);
  149.             arg = strchr(name, '\t');
  150.             if (arg)
  151.                 *arg++ = 0;
  152.  
  153.             len = CStrLen(name);
  154.             if (arg) 
  155.                 len2 = CStrLen(arg);
  156.             
  157.             MoveChar(B, 0, w, ' ', color1, w);
  158.             MoveCh(B, ConGetDrawChar(DCH_V), hcMenu_Background, 1);
  159.             MoveCh(B + w - 1, ConGetDrawChar(DCH_V), hcMenu_Background, 1);
  160.  
  161.             MoveCStr(B, 2, len + 2, Menus[id].Items[i].Name, color1, color2, len);
  162.             if (arg)
  163.                 MoveCStr(B, w - len2 - 2, w + 4, arg, color1, color2, len2);
  164.             
  165.             if (Menus[id].Items[i].SubMenu != -1) {
  166.                 MoveCh(B + w - 2, ConGetDrawChar(DCH_RPTR), color1, 1);
  167.             }
  168.         } else {
  169.             MoveChar(B, 0, w, ConGetDrawChar(DCH_H), hcMenu_Background, w);
  170.             MoveCh(B, ConGetDrawChar(DCH_V), hcMenu_Background, 1);
  171.             MoveCh(B + w - 1, ConGetDrawChar(DCH_V), hcMenu_Background, 1);
  172.         }
  173.         ConPutBox(x, y + i + 1, w, 1, B);
  174.     }
  175.     MoveChar(B, 0, w, ConGetDrawChar(DCH_H), hcMenu_Background, w);
  176.     MoveCh(B, ConGetDrawChar(DCH_C3), hcMenu_Background, 1);
  177.     MoveCh(B + w - 1, ConGetDrawChar(DCH_C4), hcMenu_Background, 1);
  178.     ConPutBox(x, y + Menus[id].Count + 1, w, 1, B);
  179.     return 1;
  180. }
  181.  
  182. int ExecVertMenu(int x, int y, int id, TEvent &E, UpMenu *up) {
  183.     int cur = 0;
  184.     int abort;
  185.     int w, h;
  186.     PCell c;
  187.     PCell SaveC = 0;
  188.     int SaveX, SaveY, SaveW, SaveH;
  189.     int wasmouse = 0;
  190.     UpMenu here;
  191.     int dovert = 0;
  192.     int rx;
  193.     int Cols, Rows;
  194.     
  195.     ConQuerySize(&Cols, &Rows);
  196.     
  197.     here.up = up;
  198.     
  199.     if (x < 0) x = 0;
  200.     if (y < 0) y = 0;
  201.  
  202.     GetVSize(id, w, h);
  203.     w += 4;
  204.     h += 2;
  205.     
  206.     if (w > Cols) w = Cols;
  207.     if (h > Rows) h = Rows;
  208.     
  209.     if (x + w > Cols)
  210.         if (up && up->x == 0 && up->y == 0 && up->h == 1) {
  211.             x = Cols - w;
  212.         } else {
  213.             if (up)
  214.                 x = up->x - w + 1;
  215.             else
  216.                 x = x - w + 1;
  217.         }
  218.     if (y + h > Rows)
  219.         if (up)
  220.             y = y - h + 3;
  221.         else {
  222.             y = y - h + 1;
  223.         }
  224.     if (x < 0) x = 0;
  225.     if (y < 0) y = 0;
  226.     
  227.     here.x = x;
  228.     here.y = y;
  229.     here.w = w;
  230.     here.h = h;
  231.     here.id = id;
  232.     here.vert = 1;
  233.     
  234.     c = (PCell) malloc(w * h * sizeof(TCell));
  235.     if (c)
  236.         ConGetBox(x, y, w, h, c);
  237.     
  238.     SaveC = c;
  239.     SaveX = x;
  240.     SaveY = y;
  241.     SaveW = w;
  242.     SaveH = h;
  243.     
  244.     if (E.What == evMouseMove || E.What == evMouseDown) {
  245.     }
  246.     if (E.What & evMouse) {
  247.         cur = GetVPosItem(id, w, E.Mouse.X - x, E.Mouse.Y - y);
  248.         dovert = 0;
  249.         wasmouse = 1;
  250.         E.What = evNone;
  251.     }
  252.     abort = -2;
  253.     while (abort == -2) {
  254.         DrawVMenu(x, y, id, cur);
  255.         if (dovert) {
  256.             if (cur != -1) {
  257.                 if (Menus[id].Items[cur].SubMenu != -1) {
  258.                     rx = ExecVertMenu(x + w - 1, y + cur,
  259.                                       Menus[id].Items[cur].SubMenu, E, &here);
  260.                     if (rx == 1) {
  261.                         abort = 1;
  262.                         continue;
  263.                     } else if (rx == -3) {
  264.                         abort = -3;
  265.                         break;
  266.                     } else
  267.                         abort = -2;
  268.  
  269.                 }
  270.             }
  271.         }
  272.         ConHideCursor();
  273.         do {
  274.             ConGetEvent(evCommand | evMouseDown | evMouseMove | evMouseUp | evKeyDown | evNotify, &E, -1, 1);
  275.             if (E.What & evNotify)
  276.                 gui->DispatchEvent(frames, frames->Active, E);
  277.         } while (E.What & evNotify);
  278.         if (E.What & evMouse) {
  279.             //fprintf(stderr, "Mouse: %d %d %d\n", E.What, E.Mouse.X, E.Mouse.Y);
  280.         }
  281.         dovert = 0;
  282.         switch (E.What) {
  283.         case evCommand:
  284.             if (E.Msg.Command == cmResize) abort = -3;
  285.             break;
  286.         case evKeyDown:
  287.             switch (kbCode(E.Key.Code)) {
  288.             case kbPgDn:
  289.             case kbEnd: cur = Menus[id].Count;
  290.             case kbUp: 
  291.                 {
  292.                     int x = cur;
  293.                     
  294.                     do {
  295.                         cur--;
  296.                         if (cur < 0) cur = Menus[id].Count - 1;
  297.                     } while (cur != x && Menus[id].Items[cur].Name == 0);
  298.                 }
  299.                 break;
  300.             case kbPgUp:
  301.             case kbHome: cur = -1;
  302.             case kbDown: 
  303.                 {
  304.                     int x = cur;
  305.                     do {
  306.                         cur++;
  307.                         if (cur >= Menus[id].Count) cur = 0;
  308.                     } while (cur != x && Menus[id].Items[cur].Name == 0);
  309.                 }
  310.                 break;
  311.             case kbEsc: abort = -1; break;
  312.             case kbEnter:
  313.                 if (cur != -1) {
  314.                     if (Menus[id].Items[cur].SubMenu < 0) {
  315.                         E.What = evCommand;
  316.                         E.Msg.View = frames->Active;
  317.                         E.Msg.Command = Menus[id].Items[cur].Cmd;
  318.                         abort = 1;
  319.                     } else {
  320.                         dovert = 1;
  321.                     }
  322.                 }
  323.                 break;
  324.             case kbLeft:
  325.             case kbRight:
  326.                 gui->ConPutEvent(E);
  327.                 abort = -1;
  328.                 break;
  329.             default:
  330.                 if (isAscii(E.Key.Code)) {
  331.                     char cc;
  332.                     int i;
  333.                     
  334.                     cc = char(toupper(char(E.Key.Code & 0xFF)));
  335.                     
  336.                     for (i = 0; i < Menus[id].Count; i++) {
  337.                         if (Menus[id].Items[i].Name) {
  338.                             char *o = strchr(Menus[id].Items[i].Name, '&');
  339.                             if (o)
  340.                                 if (toupper(o[1]) == cc) {
  341.                                     cur = i;
  342.                                     if (cur != -1) {
  343.                                         if (Menus[id].Items[cur].SubMenu == -1) {
  344.                                             E.What = evCommand;
  345.                                             E.Msg.View = frames->Active;
  346.                                             E.Msg.Command = Menus[id].Items[cur].Cmd;
  347.                                             abort = 1;
  348.                                         } else {
  349.                                             dovert = 1;
  350.                                         }
  351.                                     }
  352.                                     break;
  353.                                 }
  354.                         }
  355.                     }
  356.                 }
  357.             }
  358.             break;
  359.         case evMouseDown:
  360.             if (E.Mouse.X >= x && E.Mouse.Y >= y &&
  361.                 E.Mouse.X < x + w && E.Mouse.Y < y + h) 
  362.             {
  363.                 cur = GetVPosItem(id, w, E.Mouse.X - x, E.Mouse.Y - y);
  364.             } else {
  365.                 if (up) 
  366.                     gui->ConPutEvent(E);
  367.                 abort = -1;
  368.             }
  369.             wasmouse = 1;
  370.             dovert = 1;
  371.             break;
  372.         case evMouseMove:
  373.             if (E.Mouse.Buttons)  {
  374.                 dovert = 1;
  375.                 if (E.Mouse.X >= x && E.Mouse.Y >= y &&
  376.                     E.Mouse.X < x + w && E.Mouse.Y < y + h)
  377.                 {
  378.                     cur = GetVPosItem(id, w, E.Mouse.X - x, E.Mouse.Y - y);
  379.                 } else {
  380.                     UpMenu *p = up;
  381.                     int first = 1;
  382.                     
  383.                     if (wasmouse) {
  384.                         while (p) {
  385.                             if (E.Mouse.X >= p->x && E.Mouse.Y >= p->y &&
  386.                                 E.Mouse.X < p->x + p->w && E.Mouse.Y < p->y + p->h)
  387.                             {
  388.                                 if (first == 1) {
  389.                                     if (p->vert) {
  390.                                         int i = GetVPosItem(p->id, p->w, E.Mouse.X - p->x, E.Mouse.Y - p->y);
  391.                                         if (i != -1)
  392.                                             if (Menus[p->id].Items[i].SubMenu == id) break;
  393.                                     } else {
  394.                                         int i = GetHPosItem(p->id, E.Mouse.X);
  395.                                         if (i != -1)
  396.                                             if (Menus[p->id].Items[i].SubMenu == id) break;
  397.                                     }
  398.                                     first = 0;
  399.                                 }
  400.                                 gui->ConPutEvent(E);
  401.                                 abort = -1;
  402.                                 break;
  403.                             }
  404.                             first = 0;
  405.                             p = p->up;
  406.                         }
  407.                         cur = -1;
  408.                     } else
  409.                         cur = -1;
  410.                 }
  411.             }
  412.             break;
  413.         case evMouseUp:
  414.             if (E.Mouse.X >= x && E.Mouse.Y >= y &&
  415.                 E.Mouse.X < x + w && E.Mouse.Y < y + h)
  416.             {
  417.                 cur = GetVPosItem(id, w, E.Mouse.X - x, E.Mouse.Y - y);
  418.             }
  419.             if (cur == -1) {
  420.                 if (up) {
  421.                     UpMenu *p = up;
  422.                     cur = 0;
  423.                     if (E.Mouse.X >= p->x && E.Mouse.Y >= p->y &&
  424.                         E.Mouse.X < p->x + p->w && E.Mouse.Y < p->y + p->h)
  425.                     {
  426.                         if (p->vert) {
  427.                             int i = GetVPosItem(p->id, p->w, E.Mouse.X - p->x, E.Mouse.Y - p->y);
  428.                             if (i != -1)
  429.                                 if (Menus[p->id].Items[i].SubMenu == id) break;
  430.                         } else {
  431.                             int i = GetHPosItem(p->id, E.Mouse.X);
  432.                             if (i != -1)
  433.                                 if (Menus[p->id].Items[i].SubMenu == id) break;
  434.                         }
  435.                         abort = -1;
  436.                     }
  437.                 } else
  438.                     abort = -1;
  439.                 if (E.Mouse.X >= x && E.Mouse.Y >= y &&
  440.                     E.Mouse.X < x + w && E.Mouse.Y < y + h);
  441.                 else {
  442.                     gui->ConPutEvent(E);
  443.                     abort = -3;
  444.                 }
  445.             } else {
  446.                 if (Menus[id].Items[cur].Name != 0 &&
  447.                     Menus[id].Items[cur].SubMenu == -1)
  448.                 {
  449.                     E.What = evCommand;
  450.                     E.Msg.View = frames->Active;
  451.                     E.Msg.Command = Menus[id].Items[cur].Cmd;
  452.                     //fprintf(stderr, "Command set = %d %d %d\n", id, cur, Menus[id].Items[cur].Cmd);
  453.                     abort = 1;
  454.                 }
  455.             }
  456.             break;
  457.         }
  458.     }
  459.     if (SaveC) {
  460.         ConPutBox(SaveX, SaveY, SaveW, SaveH, SaveC);
  461.         free(SaveC);
  462.         SaveC = 0;
  463.     }
  464.     ConShowCursor();
  465.     if (up && abort == -3) return -3;
  466.     return (abort == 1) ? 1 : -1;
  467. }
  468.  
  469. int ExecMainMenu(TEvent &E, char sub) {
  470.     int cur = 0;
  471.     int id = GetMenuId(frames->Menu);
  472.     int abort;
  473.     int dovert = 1;
  474.     int rx;
  475.     static UpMenu top = { 0, 0, 0, 0, 0, 0, 1 };
  476.     PCell topline[ConMaxCols];
  477.     int Cols, Rows;
  478.     
  479.     ConQuerySize(&Cols, &Rows);
  480.     
  481.     top.x = 0;
  482.     top.y = 0;
  483.     top.h = 1;
  484.     top.w = Cols;
  485.     top.id = id;
  486.     top.vert = 0;
  487.     
  488.     ConGetBox(0, 0, Cols, 1, (PCell) topline);
  489.     
  490.     if (sub != 0) {
  491.         int i;
  492.         
  493.         for (i = 0; i < Menus[id].Count; i++) {
  494.             if (Menus[id].Items[i].Name) {
  495.                 char *o = strchr(Menus[id].Items[i].Name, '&');
  496.                 if (o)
  497.                     if (toupper(o[1]) == toupper(sub)) {
  498.                         cur = i;
  499.                         break;
  500.                     }
  501.             }
  502.         }
  503.     }
  504.  
  505.     if (E.What == evMouseDown) {
  506.         cur = GetHPosItem(id, E.Mouse.X);
  507.         dovert = 1;
  508.     }
  509.     abort = -2;
  510.     while (abort == -2) {
  511.         DrawHMenu(0, 0, id, cur);
  512.         if (dovert) {
  513.             if (cur != -1) {
  514.                 if (Menus[id].Items[cur].SubMenu != -1) {
  515.                     rx = ExecVertMenu(GetHOfsItem(id, cur) - 2, 1,
  516.                                       Menus[id].Items[cur].SubMenu, E, &top);
  517.                     if (rx == 1) {
  518.                         abort = 1;
  519.                         continue;
  520.                     } else if (rx == -3) {
  521.                         abort = -1;
  522.                         break;
  523.                     } else
  524.                         abort = -2;
  525.                 }
  526.             }
  527.         }
  528.         ConHideCursor();
  529.         do {
  530.             ConGetEvent(evCommand | evMouseDown | evMouseMove | evMouseUp | evKeyDown | evNotify, &E, -1, 1);
  531.             if (E.What & evNotify)
  532.                 gui->DispatchEvent(frames, frames->Active, E);
  533.         } while (E.What & evNotify);
  534.         dovert = 0;
  535.         switch (E.What) {
  536.         case evCommand:
  537.             if (E.Msg.Command == cmResize) abort = -1;
  538.             break;
  539.         case evKeyDown:
  540.             switch (kbCode(E.Key.Code)) {
  541.             case kbEnd: cur = Menus[id].Count;
  542.             case kbLeft:
  543.                 dovert = 1;
  544.                 {
  545.                     int x = cur;
  546.                     do {
  547.                         cur--;
  548.                         if (cur < 0) cur = Menus[id].Count - 1;
  549.                     } while (cur != x && Menus[id].Items[cur].Name == 0);
  550.                 }
  551.                 break;
  552.             case kbHome: cur = -1;
  553.             case kbRight:
  554.                 dovert = 1;
  555.                 {
  556.                     int x = cur;
  557.                     do {
  558.                         cur++;
  559.                         if (cur >= Menus[id].Count) cur = 0;
  560.                     } while (cur != x && Menus[id].Items[cur].Name == 0);
  561.                 }
  562.                 break;
  563.             case kbEsc: abort = -1; dovert = 0; break;
  564.             case kbEnter:
  565.                 if (cur != -1) {
  566.                     if (Menus[id].Items[cur].SubMenu == -1) {
  567.                         E.What = evCommand;
  568.                         E.Msg.View = frames->Active;
  569.                         E.Msg.Command = Menus[id].Items[cur].Cmd;
  570.                         abort = 1;
  571.                     } else {
  572.                         dovert = 1;
  573.                     }
  574.                 }
  575.                 break;
  576.             default:
  577.                 if (isAscii(E.Key.Code)) {
  578.                     char cc;
  579.                     int i;
  580.                     
  581.                     cc = char(toupper(char(E.Key.Code & 0xFF)));
  582.                     
  583.                     for (i = 0; i < Menus[id].Count; i++) {
  584.                         if (Menus[id].Items[i].Name) {
  585.                             char *o = strchr(Menus[id].Items[i].Name, '&');
  586.                             if (o)
  587.                                 if (toupper(o[1]) == cc) {
  588.                                     cur = i;
  589.                                     if (cur != -1) {
  590.                                         if (Menus[id].Items[cur].SubMenu == -1) {
  591.                                             E.What = evCommand;
  592.                                             E.Msg.View = frames->Active;
  593.                                             E.Msg.Command = Menus[id].Items[cur].Cmd;
  594.                                             abort = 1;
  595.                                         } else {
  596.                                             dovert = 1;
  597.                                         }
  598.                                     }
  599.                                     break;
  600.                                 }
  601.                         }
  602.                     }
  603.                 }
  604.                 break;
  605.             }
  606.             break;
  607.         case evMouseDown:
  608.             if (E.Mouse.Y == 0) {
  609.                 int oldcur = cur;
  610.                 cur = GetHPosItem(id, E.Mouse.X);
  611.                 if (cur == oldcur) {
  612.                     abort = -1;
  613.                 }
  614.             } else {
  615.                 cur = -1;
  616.                 abort = -1;
  617.             }
  618.             dovert = 1;
  619.             break;
  620.         case evMouseMove:
  621.             if (E.Mouse.Buttons) {
  622.                 if (E.Mouse.Y == 0)
  623.                     cur = GetHPosItem(id, E.Mouse.X);
  624.                 else
  625.                     cur = -1;
  626.                 dovert = 1;
  627.             }
  628.             break;
  629.         case evMouseUp:
  630.             if (E.Mouse.Y == 0)
  631.                 cur = GetHPosItem(id, E.Mouse.X);
  632.             if (cur == -1)
  633.                 abort = -1;
  634.             else {
  635.                 if (Menus[id].Items[cur].Name != 0 &&
  636.                     Menus[id].Items[cur].SubMenu == -1) 
  637.                 {
  638.                     E.What = evCommand;
  639.                     E.Msg.View = frames->Active;
  640.                     E.Msg.Command = Menus[id].Items[cur].Cmd;
  641.                     abort = 1;
  642.                 }
  643.             }
  644.             break;
  645.         }
  646.     }
  647.     DrawHMenu(0, 0, id, -1);
  648.     ConPutBox(0, 0, Cols, 1, (PCell) topline);
  649.     ConShowCursor();
  650.     return (abort == 1) ? 1 : -1;
  651. }
  652.  
  653. void GFrame::DrawMenuBar() {
  654.     int id = GetMenuId(Menu);
  655.  
  656.     DrawHMenu(0, 0, id, -1);
  657. }
  658.  
  659. extern TEvent NextEvent;
  660.  
  661. int GFrame::PopupMenu(char *Name) {
  662.     NextEvent.What = evCommand;
  663.     NextEvent.Msg.Command = cmPopupMenu;
  664.     NextEvent.Msg.Param1 = GetMenuId(Name);
  665.     return 0;
  666. }
  667.