(*---------------------------------------------------------------------------
 :Program.      GadToolsDemo.mod
 :Author.       Fridtjof Siebert
 :Address.      Nobileweg 67, D-7000 Stuttgart 40
 :Shortcut.     [fbs]
 :Copyright.    PD
 :Language.     Oberon
 :Translator.   Amiga Oberon Compiler V2.01
 :History.      V1.0 05-May-91: ported C-Demo to Oberon [fbs]
 :Contents.     demostrates use of gadtools.library in Oberon
---------------------------------------------------------------------------*)

MODULE GadToolsDemo;

IMPORT e  : Exec,
       I  : Intuition,
       g  : Graphics,
       u  : Utility,
       gt : GadTools,
       es : ExecSupport,
       d  : Dos,
            io,
       sys: SYSTEM;

CONST
  gadBUTTON      = 1;
  gadINTEGER     = 2;
  gadCHECKBOX1   = 3;
  gadCHECKBOX2   = 4;
  gadCYCLE       = 5;
  gadMX          = 6;
  gadSLIDER      = 7;
  gadSCROLLER    = 8;
  gadLVSTRING    = 9;
  gadLISTVIEW    = 10;
  gadPALETTE     = 11;

  menuFOOSET     = 1;
  menuFOOCLEAR   = 2;
  menuFOOTOGGLE  = 3;
  menuINCREASE   = 4;
  menuDECREASE   = 5;
  menuBY1        = 6;
  menuBY5        = 7;
  menuBY10       = 8;
  menuCONNECTED  = 9;
  menuNEVER      = 10;

TYPE
  TwentysixNewMenus = ARRAY 26 OF gt.NewMenu;

CONST
  myNewMenuConst = TwentysixNewMenus(
    gt.title, sys.ADR("Project"),       NIL,          {},                       LONGSET{}, NIL,
    gt.item , sys.ADR("Open..."),       sys.ADR("O"), {},                       LONGSET{}, NIL,
    gt.item,  sys.ADR("Save"),          NIL,          {},                       LONGSET{}, NIL,
    gt.item , sys.ADR("Save As..."),    NIL,          {},                       LONGSET{}, NIL,
    gt.item , gt.barLabel,              NIL,          {},                       LONGSET{}, NIL,
    gt.item , sys.ADR("Print"),         NIL,          {},                       LONGSET{}, NIL,
    gt.sub  , sys.ADR("NLQ"),           NIL,          {},                       LONGSET{}, NIL,
    gt.sub  , sys.ADR("Draft"),         NIL,          {},                       LONGSET{}, NIL,
    gt.item , gt.barLabel,              NIL,          {},                       LONGSET{}, NIL,
    gt.item , sys.ADR("Quit..."),       sys.ADR("Q"), {},                       LONGSET{}, NIL,

    gt.title, sys.ADR("Gadgets"),       NIL,          {},                       LONGSET{}, NIL,
    gt.item , sys.ADR("Foo"),           NIL,          {},                       LONGSET{}, NIL,
    gt.sub  , sys.ADR("Set"),           sys.ADR("S"), {},                       LONGSET{}, menuFOOSET,
    gt.sub  , sys.ADR("Clear"),         sys.ADR("C"), {},                       LONGSET{}, menuFOOCLEAR,
    gt.sub  , sys.ADR("Toggle"),        sys.ADR("T"), {},                       LONGSET{}, menuFOOTOGGLE,
    gt.item , sys.ADR("Slider"),        NIL,          {},                       LONGSET{}, NIL,
    gt.sub  , sys.ADR("Increase"),      sys.ADR("I"), {},                       LONGSET{}, menuINCREASE,
    gt.sub  , sys.ADR("Decrease"),      sys.ADR("D"), {},                       LONGSET{}, menuDECREASE,
    gt.sub  , gt.barLabel,              NIL,          {},                       LONGSET{}, NIL,
    gt.sub  , sys.ADR("By 1s"),         NIL,          {I.checkIt,I.checked},   -LONGSET{3},menuBY1,
    gt.sub  , sys.ADR("By 5s"),         NIL,          {I.checkIt},             -LONGSET{4},menuBY5,
    gt.sub  , sys.ADR("By 10s"),        NIL,          {I.checkIt},             -LONGSET{5},menuBY10,
    gt.item , sys.ADR("MX Gadgets"),    NIL,          {},                       LONGSET{}, NIL,
    gt.sub  , sys.ADR("Connected?"),    NIL,          {I.checkIt,I.menuToggle}, LONGSET{}, menuCONNECTED,
    gt.item , sys.ADR("Not Me!"),       NIL,          {gt.itemDisabled},        LONGSET{}, menuNEVER,

    gt.end  , NIL,                      NIL,          {},                       LONGSET{}, NIL);

  myNewWinConst = I.NewWindow(
    0, 0,               (*  LeftEdge, TopEdge *)
    600, 166,           (*  Width, Height *)
    -1, -1,             (*  DetailPen, BlockPen *)
    LONGSET{I.menuPick,I.mouseButtons,I.gadgetUp, I.gadgetDown, I.mouseMove,
        I.closeWindow,I.refreshWindow,I.intuiTicks}, (*  IDCMPFlags *)
    LONGSET{I.activate,I.windowDrag,I.windowSizing,I.windowDepth,
        I.windowClose}, (* Flags *)
    NIL,                (*  FirstGadget *)
    NIL,                (*  CheckMark *)
    sys.ADR("Fancy GadTools Demo"),      (*  Title *)
    NIL,                (*  Screen *)
    NIL,                (*  BitMap *)
    50, 50,             (*  MinWidth, MinHeight *)
    640, 200,           (*  MaxWidth, MaxHeight *)
    {I.wbenchScreen});  (*  Type *)

  Topaz80Const = g.TextAttr(
    sys.ADR("topaz.font"),       (*  Name *)
    8,                  (*  YSize *)
    SHORTSET{},         (*  Style *)
    SHORTSET{});        (*  Flags *)

TYPE
  ThirteenMonths = ARRAY 13 OF e.STRPTR;
  EightDays = ARRAY 8 OF e.STRPTR;

CONST
  monthLabels =  ThirteenMonths( sys.ADR("January"), sys.ADR("February"), sys.ADR("March"),
    sys.ADR("April"), sys.ADR("May"), sys.ADR("June"), sys.ADR("July"), sys.ADR("August"),
    sys.ADR("September"), sys.ADR("October"), sys.ADR("November"), sys.ADR("December"), NIL);

  dayLabels = EightDays(
    sys.ADR("Monday"), sys.ADR("Tuesday"), sys.ADR("Wednesday"), sys.ADR("Thursday"),
    sys.ADR("Friday"), sys.ADR("Saturday"), sys.ADR("Sunday"), NIL);

VAR lh: e.List;

  font: g.TextFontPtr;
  mysc: I.ScreenPtr;
  rkey: I.RememberPtr;
  glist: I.GadgetPtr;
  menu: I.MenuPtr;
  mywin: I.WindowPtr;
  vi: e.APTR;
  terminated: BOOLEAN;
  topaz80: g.TextAttr;
  myNewMenu: TwentysixNewMenus;
  myNewWin: I.NewWindow;

VAR
  sliderlevel: INTEGER;
  incr: INTEGER;
  integergad, mxgad, checkgad,
  slidergad, cyclegad, lvgad, stringgad: I.GadgetPtr;
  foochecked: BOOLEAN;
  connected: BOOLEAN;

  imsg: I.IntuiMessagePtr;
  gad: I.GadgetPtr;
  imsgClass: LONGSET;
  imsgCode: INTEGER;
  topborder: INTEGER;

CONST
  sliderMin = 0;
  sliderMax = 49;

PROCEDURE BailOut(error: ARRAY OF CHAR);

BEGIN
  d.PrintF("Error: %s\n", sys.ADR(error));
  HALT(20);
END BailOut;

PROCEDURE HandleMenuEvent(code: INTEGER): BOOLEAN;

TYPE
  MyProc = PROCEDURE(code: INTEGER): BOOLEAN;

VAR
  item: I.MenuItemPtr;
  terminated: BOOLEAN;
  fptr: MyProc;

BEGIN
  terminated := FALSE;

  d.PrintF("MENUPICK.  ");
  WHILE (code # I.menuNull) AND ~ terminated DO
    item := I.ItemAddress(menu^, code);
    IF I.MenuNum(code) = 0 THEN
      fptr := sys.VAL(MyProc,gt.MenuItemUserData(item));
      IF fptr # NIL THEN
        terminated := fptr(code);
      END;
    ELSE
      CASE gt.MenuItemUserData(item) OF
      menuFOOSET:
        d.PrintF("Foo Set.  ");
        gt.SetGadgetAttrs(checkgad^, mywin, NIL,
            gt.cbChecked, I.LTRUE,
            u.done);
        foochecked := TRUE |

      menuFOOCLEAR:
        d.PrintF("Foo Clear.  ");
        gt.SetGadgetAttrs(checkgad^, mywin, NIL,
            gt.cbChecked, I.LFALSE,
            u.done);
        foochecked := FALSE |

      menuFOOTOGGLE:
        d.PrintF("Foo Toggle.  ");
        foochecked := ~ foochecked;
        IF foochecked THEN
          gt.SetGadgetAttrs(checkgad^, mywin, NIL, gt.cbChecked, I.LTRUE, u.done)
        ELSE
          gt.SetGadgetAttrs(checkgad^, mywin, NIL, gt.cbChecked, I.LFALSE, u.done)
        END |

      menuINCREASE:
        d.PrintF("Slider Increase.  ");
        IF sliderlevel < sliderMax THEN
          INC(sliderlevel,incr);
          IF sliderlevel > sliderMax THEN
            sliderlevel := sliderMax;
          END;
          gt.SetGadgetAttrs(slidergad^, mywin, NIL, gt.slLevel, sliderlevel, u.done);
        END |

      menuDECREASE:
        d.PrintF("Slider Decrease.  ");
        IF sliderlevel > sliderMin THEN
          DEC(sliderlevel,incr);
          IF sliderlevel < sliderMin THEN
            sliderlevel := sliderMin
          END;
          gt.SetGadgetAttrs(slidergad^, mywin, NIL, gt.slLevel, sliderlevel, u.done);
        END |

      menuBY1:
        d.PrintF("Change Slider By 1's.  ");
        incr := 1 |

      menuBY5:
        d.PrintF("Change Slider By 5's.  ");
        incr := 5 |

      menuBY10:
        d.PrintF("Change Slider By 10's.  ");
        incr := 10 |

      menuCONNECTED:
        d.PrintF("MX Gadgets Connected?");
        connected := (I.checked IN item.flags) |

      menuNEVER:
        d.PrintF("Can't Get Me!  ") |

      ELSE END;

    END;
    code := item.nextSelect;

  END;

  d.PrintF("\n");

  RETURN terminated;

END HandleMenuEvent;

PROCEDURE * OpenFunc(code: INTEGER): BOOLEAN;

BEGIN
  d.PrintF("Called Open Function.  ");
  RETURN FALSE;
END OpenFunc;

PROCEDURE * SaveFunc(code: INTEGER): BOOLEAN;

BEGIN
  d.PrintF("Called Save Function.  ");
  RETURN FALSE;
END SaveFunc;

PROCEDURE * SaveAsFunc(code: INTEGER): BOOLEAN;

BEGIN
  d.PrintF("Called SaveAs Function.  ");
  RETURN FALSE;
END SaveAsFunc;

PROCEDURE * PrintFunc(code: INTEGER): BOOLEAN;

BEGIN
  d.PrintF("Called Print Function - ");
  IF I.SubNum(code)=0 THEN
    d.PrintF("NLQ.  ");
  ELSE
    d.PrintF("Draft.  ");
  END;
  RETURN FALSE;
END PrintFunc;

PROCEDURE * QuitFunc(code: INTEGER): BOOLEAN;

BEGIN
  d.PrintF("Called Quit Function.  ");
  RETURN TRUE;
END QuitFunc;

PROCEDURE HandleMouseMove(gad: I.GadgetPtr; code: INTEGER): BOOLEAN;

VAR
  terminated: BOOLEAN;

BEGIN

  terminated := FALSE;

  d.PrintF("MOUSEMOVE.  ");
  CASE gad.gadgetID OF

  gadSLIDER:
    d.PrintF("Slider Level: %ld\n", code);
    sliderlevel := code |

  gadSCROLLER:
    d.PrintF("Scroller Level: %ld\n", code) |

  ELSE END;

  RETURN terminated;

END HandleMouseMove;

PROCEDURE HandleGadgetEvent(gad: I.GadgetPtr; code: INTEGER): BOOLEAN;

VAR
  terminated: BOOLEAN;
  strinfo: I.StringInfoPtr;

BEGIN

  terminated := FALSE;


  CASE gad.gadgetID OF
  gadBUTTON:
      d.PrintF("Button 'ClickMe'.\n");
      gt.SetGadgetAttrs(integergad^, mywin, NIL,
          gt.inNumber, 271828,
          u.done) |

  gadINTEGER:
      strinfo := gad.specialInfo;
      d.PrintF("Integer gadget: %ld.\n",strinfo.longInt) |

  gadCHECKBOX1:
      d.PrintF("Foo is ");
      IF ~ (I.selected IN gad.flags) THEN

        foochecked := FALSE;
        d.PrintF("not ");

      ELSE

        foochecked := TRUE;

      END;

      d.PrintF("selected.\n") |

  gadCHECKBOX2:
      d.PrintF("Bar is ");
      IF ~ (I.selected IN gad.flags) THEN
        d.PrintF("not ")
      END;
      d.PrintF("selected.\n") |

  gadCYCLE:
      d.PrintF("Cycle: '%s'.\n", monthLabels[code]);
      IF connected AND (code < 7) THEN
        gt.SetGadgetAttrs(mxgad^, mywin, NIL, gt.mxActive, code, u.done)
      END |

  gadMX:
      d.PrintF("MX: Day-of-week '%s'\n", dayLabels[code]);
      IF connected THEN
          gt.SetGadgetAttrs(cyclegad^, mywin, NIL, gt.cyActive, code, u.done)
      END |

  gadSLIDER:
      d.PrintF("Slider Level: %ld\n", code);
      sliderlevel := code;
      IF (sliderlevel >= 0) AND (sliderlevel <= 12) THEN

        gt.SetGadgetAttrs(lvgad^, mywin, NIL, gt.lvSelected, code, u.done);

      END |

  gadSCROLLER:
      d.PrintF("Scroller Level: %ld\n", code) |

  gadPALETTE:
      d.PrintF("Palette:  selected color %ld\n", code) |

  gadLVSTRING:
      strinfo := gad.specialInfo;
      d.PrintF("LVString: '%s'.\n",strinfo.buffer) |

  gadLISTVIEW:
      d.PrintF("ListView: clicked on '%s'\n", monthLabels[code]) |

  ELSE END;

  RETURN terminated;

END HandleGadgetEvent;

PROCEDURE CreateAllGadgets(VAR glist: I.GadgetPtr; vi: e.APTR; topborder: INTEGER): BOOLEAN;

VAR
  ng: gt.NewGadget;
  gad: I.GadgetPtr;
  index: INTEGER;
  node: e.NodePtr;

BEGIN

  gad := gt.CreateContext(glist);
  ng.leftEdge := 300;
  ng.topEdge := 4+topborder;
  ng.width := 0;
  ng.height := 8;
  ng.gadgetText := sys.ADR("Gadget Toolkit Test");
  ng.textAttr := sys.ADR(topaz80);
  ng.gadgetID := 0;
  ng.flags := LONGSET{gt.placeTextIn,gt.highLabel};
  ng.visualInfo := vi;
  gad := gt.CreateGadget(gt.textKind, gad, ng, u.done);

  ng.leftEdge := 10;
  ng.topEdge := 19+topborder;
  ng.width := 100;
  ng.height := 12;
  ng.gadgetText := sys.ADR("ClickMe");
  ng.gadgetID := gadBUTTON;
  ng.flags := LONGSET{};
  gad := gt.CreateGadget(gt.buttonKind, gad, ng, u.done);

  ng.leftEdge := 400;
  ng.height := 14;
  ng.gadgetText := sys.ADR("Month:");
  ng.gadgetID := gadCYCLE;
  ng.flags := LONGSET{gt.highLabel};
  gad := gt.CreateGadget(gt.cycleKind, gad, ng,
                  gt.cyLabels, sys.ADR(monthLabels),
                  gt.cyActive, 3,
                  u.done);
  cyclegad := gad;

  ng.topEdge := 69+topborder;
  ng.leftEdge := 70;
  ng.gadgetText := sys.ADR("Foo:");
  ng.gadgetID := gadCHECKBOX1;
  gad := gt.CreateGadget(gt.checkBoxKind, gad, ng,
                  gt.cbChecked, sys.VAL(SHORTINT,foochecked), u.done);
  checkgad := gad;

  IF gad#NIL THEN
    INC(ng.topEdge,gad.height);
  END;

  ng.gadgetText := sys.ADR("Bar:");
  ng.gadgetID := gadCHECKBOX2;
  gad := gt.CreateGadget(gt.checkBoxKind, gad, ng, gt.cbChecked, I.LFALSE, u.done);

  ng.topEdge := 99+topborder;
  ng.width := 200;
  ng.gadgetText := sys.ADR("Type:");
  ng.gadgetID := gadINTEGER;
  gad := gt.CreateGadget(gt.integerKind, gad, ng,
                  gt.inNumber, 54321,
                  gt.inMaxChars, 10,
                  u.done);
  integergad := gad;

  ng.topEdge := 117+topborder;
  ng.height := 12;
  ng.gadgetText := sys.ADR("L:   ");
  ng.gadgetID := gadSLIDER;
  gad := gt.CreateGadget(gt.sliderKind, gad, ng,
                  gt.slMin, sliderMin,
                  gt.slMax, sliderMax,
                  gt.slLevel, sliderlevel,
                  gt.slLevelFormat, sys.ADR("%2ld"),
                  gt.slLevelPlace,sys.VAL(LONGINT,LONGSET{gt.placeTextLeft}),
                  gt.slMaxLevelLen, 2,
                  I.gaImmediate, I.LTRUE,
                  I.gaRelVerify, I.LTRUE,
                  u.done);
  slidergad := gad;

  ng.topEdge := 133+topborder;
  ng.gadgetText := sys.ADR("Scroll:");
  ng.gadgetID := gadSCROLLER;
  gad := gt.CreateGadget(gt.scrollerKind, gad, ng,
                  gt.scTop, 5,
                  gt.scTotal, 30,
                  gt.scVisible, 10,
                  gt.scArrows, 13,
                  I.gaRelVerify, I.LTRUE,
                  u.done);

  ng.topEdge := 149+topborder;
  ng.height := 8;
  ng.gadgetText := sys.ADR("Number:");
  gad := gt.CreateGadget(gt.numberKind, gad, ng,
                  gt.nmNumber, 314159,
                  u.done);

  ng.leftEdge := 400;
  ng.gadgetText := sys.ADR("Read:");
  gad := gt.CreateGadget(gt.textKind, gad, ng,
                  gt.txText, sys.ADR("Read-Only Field!"),
                  u.done);

  ng.leftEdge := 470;
  ng.topEdge := 49+topborder;
  ng.gadgetID := gadMX;
  gad := gt.CreateGadget(gt.mxKind, gad, ng,
                  gt.mxLabels, sys.ADR(dayLabels),
                  gt.mxActive, 0,
                  gt.mxSpacing, 4,
                  u.done);
  mxgad := gad;

  es.NewList(lh);
  index := 0;
  WHILE monthLabels[index]#NIL DO
    NEW(node);
    node.name := monthLabels[index];
    INC(index);
    e.AddTail(lh, node);
  END;

  ng.width := 150;
  ng.height := 14;
  ng.gadgetText := NIL;
  ng.gadgetID := gadLVSTRING;
  gad := gt.CreateGadget(gt.stringKind, gad, ng,
                  gt.stMaxChars, 50,
                  u.done);
  stringgad := gad;

  ng.leftEdge := 130;
  ng.topEdge := 19+topborder;
  ng.width := 150;
  ng.height := 57;
  ng.gadgetText := sys.ADR("Months:");
  ng.gadgetID := gadLISTVIEW;
  ng.flags := LONGSET{gt.highLabel,gt.placeTextLeft};
  gad := gt.CreateGadget(gt.listViewKind, gad, ng,
                  gt.lvLabels, sys.ADR(lh),
                  gt.lvTop, 1,
                  I.layoutaSpacing, 1,
                  gt.lvShowSelected, stringgad,
                  gt.lvSelected, 3,
                  gt.lvScrollWidth, 18,
                  u.done);
  lvgad := gad;

  ng.leftEdge := 320;
  ng.topEdge := 49+topborder;
  ng.width := 40;
  ng.height := 75;
  ng.gadgetText := sys.ADR("Colors");
  ng.gadgetID := gadPALETTE;
  ng.flags := LONGSET{gt.highLabel};

  gad := gt.CreateGadget(gt.paletteKind, gad, ng,
                  gt.paDepth, mysc.bitMap.depth,
                  gt.paColor, 1,
                  gt.paColorOffset, 0,
                  gt.paIndicatorHeight, 15,
                  u.done);

  RETURN gad#NIL;

END CreateAllGadgets;

BEGIN
  sliderlevel := 7;
  incr := 1;
  foochecked := TRUE;
  connected := FALSE;
  terminated := FALSE;
  topaz80 := Topaz80Const;
  myNewWin := myNewWinConst;
  myNewMenu := myNewMenuConst;
  myNewMenu[1].userData := sys.VAL(LONGINT,OpenFunc);
  myNewMenu[2].userData := sys.VAL(LONGINT,SaveFunc);
  myNewMenu[3].userData := sys.VAL(LONGINT,SaveAsFunc);
  myNewMenu[6].userData := sys.VAL(LONGINT,PrintFunc);
  myNewMenu[7].userData := sys.VAL(LONGINT,PrintFunc);
  myNewMenu[9].userData := sys.VAL(LONGINT,QuitFunc);
  IF (I.int.libNode.version<36) THEN BailOut("Requires KickStart V2.0") END;
  font := g.OpenFont(topaz80);
  IF font=NIL THEN BailOut("Failed to open font") END;

  mysc := I.LockPubScreen(NIL);
  IF mysc=NIL THEN BailOut("Couldn't lock default public screen") END;

  vi := gt.GetVisualInfo(mysc,u.done);
  IF vi=NIL THEN BailOut("GetVisualInfo() failed") END;

  topborder := mysc.wBorTop + mysc.font.ySize + 1;
  menu := gt.CreateMenus(myNewMenu,gt.mnFrontPen,0,u.done);
  IF menu=NIL THEN BailOut("CreateMenus() failed") END;

  IF ~ gt.LayoutMenus(menu, vi,u.done) THEN BailOut("LayoutMenus() failed") END;

  IF ~ CreateAllGadgets(glist,vi,topborder) THEN
    BailOut("CreateAllGadgets() failed");
  END;
  mywin := I.OpenWindowTags(myNewWin,
                            I.waInnerHeight,myNewWin.height,
                            I.waAutoAdjust, I.LTRUE,
                            I.waPubScreen,  mysc,
                            u.done);
  IF mywin = NIL THEN BailOut("OpenWindow() failed") END;
  IF I.AddGList(mywin, glist, -1, -1, NIL)=0 THEN END;
  I.RefreshGList(glist, mywin, NIL, -1);
  gt.RefreshWindow(mywin, NIL);

  IF I.SetMenuStrip(mywin, menu^) THEN END;

  WHILE ~ terminated DO
    REPEAT UNTIL e.Wait (LONGSET{mywin.userPort.sigBit})#LONGSET{};
    LOOP
      IF terminated THEN EXIT END;
      imsg := gt.GetIMsg(mywin.userPort);
      IF imsg=NIL THEN EXIT END;
      imsgClass := imsg.class;
      imsgCode := imsg.code;
      gad := imsg.iAddress;
      gt.ReplyIMsg(imsg);
      IF I.menuPick IN imsgClass THEN
        terminated := HandleMenuEvent(imsgCode);
      END;

      IF I.mouseMove IN imsgClass THEN
        terminated := HandleMouseMove(gad, imsgCode);
      END;

      IF I.gadgetUp IN imsgClass THEN
        d.PrintF("GADGETUP.  ");
        terminated := HandleGadgetEvent(gad, imsgCode);
      END;

      IF I.gadgetDown IN imsgClass THEN
        d.PrintF("GADGETDOWN.  ");
        terminated := HandleGadgetEvent(gad, imsgCode);
      END;

      IF I.closeWindow IN imsgClass THEN
        d.PrintF("CLOSEWINDOW.\n");
        terminated := TRUE;
      END;

      IF I.refreshWindow IN imsgClass THEN
        d.PrintF("REFRESHWINDOW.\n");
        gt.BeginRefresh(mywin);
        gt.EndRefresh(mywin, I.LTRUE);
      END;
    END;
  END;

CLOSE
  IF mywin#NIL THEN
    I.ClearMenuStrip(mywin);
    I.CloseWindow(mywin);
  END;

  gt.FreeMenus(menu);
  gt.FreeVisualInfo(vi);
  gt.FreeGadgets(glist);


  IF mysc#NIL THEN
    I.UnlockPubScreen(NIL, mysc);
  END;

  IF font#NIL THEN
    g.CloseFont(font);
  END;

END GadToolsDemo.

