/* CLASS:  Button or ToolBar style window:

   REQUIRE: PRJINFO.CLS, EVENTS.H
   This window consists of a menu, labels, and BitMapButtons.
 */!!

inherit(Window, #ButtonWindow, #(buttonActionDict  /* id->invocation-action */
buttonPressDict  /* id->bitmap-button */
tmWidth
tmHeight
groupWidthDict
inClose? /* closing app semaphore */
eventDescSet /* events descriptor set */
eventRespSet /* events Response set */
timerCallBackFun
afterFIrstCallback /* nil the 1st time */
TimerEventID
saveLayoutOnExit
initComplete  /* true when init complete */), 2, nil)!!

now(class(ButtonWindow))!!

/* Return the default window style. */
Def style(self)
{ ^(WS_SYSMENU bitOr WS_MINIMIZEBOX bitOr WS_OVERLAPPED);
}!!

/* PUBLIC - Define class */
Def wndClass(self)
{
  ^"ButtonBarPresenter";
}!!

/* Return the name of this class's Windows window icon
  either for registration or new window creation. */
Def wndIcon(self)
{ ^"ButtonB";
}!!

now(ButtonWindow)!!

/* 3/4/1997 8:43 */
 
Def menuRelink(self)
{
  /* 04/25/94 - Nghia
  ** Move Warning message to MemServLib 
  */
  if (MapLibClass$Inst) then
    RelinkEP(MapLibClass$Inst);
  endif;  
}!!

/* 3/4/1997 8:31 */
 
Def initSetupMButtons(self, topPos, leftPos)
{
  if (getSystemType(ProcLibClass$Inst) <> PROC_POWERSCOPE) then
    addButton(self, "Overlay",
                  TB_OVERLAY_ID, TB_OVERLAY_SELECTED_ID,
                  #actionOverlay,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */
  else
    addButton(self, "Overlay",
                  TB_NO_OVERLAY_ID, TB_NO_OVERLAY_ID,
                  #actionOverlay,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */
  endif;

  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  addButton(self, "Load Code",
                  TB_LOAD_ID, TB_LOAD_SELECTED_ID,
                  #actionLoadCode,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;

  ^leftPos
}!!

/* WINDOWS
  timer event
*/
Def WM_TIMER(self, wP, lP)
{
   if afterFIrstCallback
     hitSharedDataServer(SharedDataLibClass$Inst); /* force a comm read */
   else
     afterFIrstCallback := #true;
     startupScript(PreLauncher);
     openAllSavedWindows( PreLauncher );
  endif;

  ^0
}!!

/* WINDOWS -- keep constant size based on cRect -- see also WM_MOVE */
Def WM_SIZE(self, wP, lP)
{
  if cRect cand (Call IsIconic(hWnd(self)) = 0)
  then
    moveWindow(self);
    invalidate(self);
  endif ;
}!!

/* End MS-Windows message.  If self is the main
  window, then go through Actor shutdown so that users
  can save their work.  They can cancel ending the
  session, according to the return value of the
  shouldClose method.  Returning a 0 cancels.  Every
  non-main window returns 1. */
Def WM_QUERYENDSESSION(self, wP, lP)
{ if shouldClose(self)
  then
    setOkToClose( TheApp:late ) ;
    ^1 /* OK */
  else
    ^0 /* not OK */
  endif ;
}!!

/* WINDOWS
  MS-Window's message to paint self -- sends a
  paint(self) message.  This overrides Window:WM_PAINT
  so that TextWindow and its descendants use the
  System Fixed Font instead of the System Font. */
Def WM_PAINT(self, wP, lP | hdc)
{ hdc := Call BeginPaint(getHWnd(self), paintStruct);
  Call SelectObject(hdc, Call GetStockObject(SYSTEM_FIXED_FONT));
  paint(self, hdc);
  Call SelectObject(hdc, Call GetStockObject(SYSTEM_FONT));
  Call EndPaint(getHWnd(self), paintStruct);
  ^0;
}!!

/* WINDOWS -- keep constant size -- see also WM_SIZE */
Def WM_MOVE(self, wP, lP | oldRect fixup)
{ setLocRect( self ) ;

  if  (Call IsIconic(hWnd(self)) <> 0) /* iconized? */
  then ^self
  endif ;

  oldRect := cRect( self ) ;
  cRect := windowRect( self ) ;

  if not( cRect and oldRect )
  then ^self
  endif ;

  if (width(oldRect) <> width(cRect))
  then
    fixup := #true ;
    setRight( cRect, left(cRect) + width(oldRect) ) ;
  endif ;
  if (height(oldRect) <> height(cRect))
  then
    fixup := #true ;
    setBottom( cRect, top(cRect) + height(oldRect) ) ;
  endif ;

  if fixup
  then moveWindow( self ) ;
  endif ;

}
!!

/* WINDOWS */
Def WM_INITMENU(self, wp, lp)
{
  ^WM_INITMENU( PreLauncher, wp, lp ) ;
}
!!

/* 7/20/1992 14:50 - WINDOWS (Tbird's message)
  Sent by event manager (evNoteLib)
*/
Def WM_EVENT(self, ignored, event)
{
  if event cand at(eventRespSet, event) then
    perform(self, at(eventRespSet, event));
  else
    /* Impossible case, unless Windows failed to delivery private messages */
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_UNKNOWN_EVENT, FORCE_POPUP, asciiz(asHex(event)), nil, nil);
  endif;
  ^0
}
!!

/* WINDOWS -- propagate to ownerdraw buttons */
Def WM_DRAWITEM(self, wP, lP)
{
  WM_DRAWITEM(at(buttonPressDict,wP), wP, lP)
}
!!

/* WINDOWS */
Def WM_CLOSE(self, wP, lP)
{
  if shouldClose( self )
  then close( self ) ;
  endif ;
}!!

Def shouldClose(self | setClose?)
{
  if inClose?
  then
    ^#true
  else
    /* check windows 1st */
    do(presenterNames(PreLauncher),
    {using(key | win)
      if (win := at(Actor, key))
        if (win <> self) cand not(shouldClose(win))
          ^nil;
        endif;
      endif;
    });
    setClose? :=
        (errMessageBox(ErrorTextLibClass$Inst, "MICEpack/SLD",
              "Exit MICEpack/SLD?",
              MB_YESNO bitOr MB_ICONQUESTION bitOr 0x2000,
              HE_DLGM_BUTTONWI_1) = IDYES);
     if setClose?
       setOkToClose(TheApp:late);
     endif;


     ^setClose?
  endif;
}
!!

/* WINDOWS (PUBLIC) */
Def paint(self, hDC)
{
  initTextColors( self, hDC ) ;
  drawLabels( self, hDC ) ;
}!!

/* BUTTON */
Def menuSaveAll(self)
{
}
!!

/* BUTTON */
Def menuRestoreAll(self)
{
}
!!

/* BUTTON */
Def menuHelpHelp(self)
{
  help( TheHelpObject, hWnd(self) ) ;
}
!!

/* BUTTON */
Def menuHelpContents(self)
{
  contents( TheHelpObject, hWnd(self) ) ;
}
!!

/* BUTTON */
Def menuExitApplication(self)
{
  if shouldClose( self )
  then
    close( self ) ;
  endif ;
}
!!

/* BUTTON */
Def menuAbout(self)
{
  if not(CLIULibraryClass$Inst) then
     ^nil;
  else
     showAboutBox(CLIULibraryClass$Inst);
  endif;
}
!!

Def initUtilityButtons(self, topPos, leftPos)
{
  addButton(self, "Shell",
                  TB_SHELL_ID, TB_SHELL_SELECTED_ID,
                  #actionCliPresenter,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;

  ^leftPos
}
!!

/* 7/20/1992 14:29 - PRIVATE
  Save the StartPC and set the current PC position for the system.
*/
Def getStartPC(self | addrDesc, cloneDesc)
{
  /* Save the startup PC and set the current PC to it */
  if (addrDesc := getStartPCAddr(LoaderLibClass$Inst)) then
    setLoadStartPC(currentLoadFile(TheProjectInfoObj), addrDesc);
    /* Make a clone descriptor of the PC address descriptor */
    if (cloneDesc := duplicateAddress(AddressLibClass$Inst, addrDesc)) then
      /* Set the startup PC for current loadfile */
      setProgramCounter(CpuLibClass$Inst, cloneDesc);
    endif;
  endif;
  /* Let Event Notification update the data display */
  ^GOOD;
}

!!

/* 12/3/1992 15:48 - PRIVATE
  Set stepMask mode on/off.
*/
Def menuStepMask(self)
{
  /* Set stepMask if stepMask is not ON, else clear it */
  if (getStepMask(HLBreakLibClass$Inst) <> BOOL_TRUE) then
      setStepMask(HLBreakLibClass$Inst, BOOL_TRUE);
      checkMenuItem(self, 513);
  else
    setStepMask(HLBreakLibClass$Inst, BOOL_FALSE);
    unCheckMenuItem(self, 513);
  endif;
}
!!

/* Got this from window.cls; modified to add shortcuts on Exit, About. */
Def addAbout(self | hMenu, appName)
{ hMenu := Call GetSystemMenu(hWnd, 0);
  appName := loadString(IDSNAME);
  Call ModifyMenu(hMenu, SC_CLOSE, MF_BYCOMMAND,
    SC_CLOSE, asciiz("E&xit MP/SLD..."));
}!!

/* menu action */
Def menuRestCS(self | dlg inputstr)
{
  dlg := new(FileDialog, "*.cs");
  setHelpEntry(dlg, HE_DLGF_RESTORECS);
  if runModal(dlg, FILE_BOX, ThePort) = IDOK
    inputstr := loadFile(dlg);
    restoreCS(MapLibClass$Inst, inputstr);
  endif;
}
!!

/* menu action */
Def menuSaveCS(self | dlg inputstr)
{
  dlg := new(SaveFileDialog, "*.cs");
  setHelpEntry(dlg, HE_DLGF_SAVECS);
  if runModal(dlg, FILE_BOX, ThePort) = IDOK
    inputstr := loadFile(dlg);
    saveCS(MapLibClass$Inst, inputstr);
  endif;
}!!

/* menu action */
Def menuConfCS(self)
{
  configCS(MapLibClass$Inst);
}
!!

/* menu entry: reset the CPU. */
Def menuReset(self)
{
  /* 04/25/94 - Nghia
  ** Move Warning message to CpuLib 
  */
  if (CpuLibClass$Inst) then
    reset(CpuLibClass$Inst);
  endif;
}
!!

/* menu entry: reset the CPU only. */
Def menuResetOnly(self)
{
  /* 04/25/94 - Nghia
  ** Move Warning message to CpuLib 
  */
  if (CpuLibClass$Inst) then
    resetCpuOnly(CpuLibClass$Inst);
  endif;  
}
!!

/* menu selection Save Layout on Exit. */
Def menuLayoutExit(self)
{

/* returns 1 if TRUE, 0 if false */
  saveLayoutOnExit := getIniSaveLayoutOnExit(PreLauncher);

  if saveLayoutOnExit=1
    unCheckMenuItem(self, 520);
    putIniSaveLayoutOnExit(PreLauncher, 0);
  else
    checkMenuItem(self, 520);
    putIniSaveLayoutOnExit(PreLauncher, 1);
  endif;
}
!!

/* Save Layout Now. */
Def menuLayoutNow(self)
{
   saveAllPresenterPos(PreLauncher);
}
!!

/* process menu selection */
Def menuSymDasm(self | dasmSymbols)
{
  dasmSymbols := getDasmSymbol(DisAsmLibClass$Inst);
  if dasmSymbols = 0  /* off */
    setDasmSymbol(DisAsmLibClass$Inst,1);
    checkMenuItem(self, 507);
  else
    setDasmSymbol(DisAsmLibClass$Inst,0);
    unCheckMenuItem(self, 507);
  endif;
}
!!

/* process menu selection */
Def menuShowCycles(self | cycles lastError)
{
  /* invert show cycles (1 = on, 0 = off, nil = error) */
  cycles := showCycles?(memoryServer(MemServLibClass$Inst));

  if ((lastError := getLastSdError(SharedDataLibClass$Inst)) 
                                                    <> ER_SIM_UNREADABLE)
    displayError(ErrorTextLibClass$Inst, lastError, CHECK_MODE);
  endif;

  select
    case cycles = 1
    is
      showCyclesOff(memoryServer(MemServLibClass$Inst));
      unCheckMenuItem(self, 506);    
    endCase
    case cycles = 0
    is
      showCyclesOn(memoryServer(MemServLibClass$Inst));
      checkMenuItem(self, 506);
    endCase
    case not(cycles)
    is
      unCheckMenuItem(self, 506);
      grayMenuItem(self, 506);
    endCase
  endSelect;
  
}
!!

/* toolbar got focus */
Def gotFocus(self, hWndPrev)
{
  checkMenuItems(self);
  ^gotFocus(self:ancestor, hWndPrev);
}
!!

/* toolbar got focus */
Def checkMenuItems(self | cycles lastError)
{
  /* don't do it until initialization complete, DLLs hooked up */
  if not(initComplete)
    ^nil;
  endif;

  /* make sure run access properly checked */
  if (getRunAccess(HLBrkRootLibClass$Inst) = BOOL_TRUE)
    checkMenuItem(self, 505);
  else
    unCheckMenuItem(self, 505);
  endif;
  
  /* make sure stepMask properly checked */
  if (getStepMask(HLBreakLibClass$Inst) = BOOL_TRUE)
    checkMenuItem(self, 513);
  else
    unCheckMenuItem(self, 513);
  endif;

  /* make sure show cycles properly checked (1 = on, 0 = off, nil = error) */
  cycles := showCycles?(memoryServer(MemServLibClass$Inst));

  if (((lastError := getLastSdError(SharedDataLibClass$Inst)) <> GOOD) cand
    (lastError <> ER_SIM_UNREADABLE)) 
    if (lastError)
      displayError(ErrorTextLibClass$Inst, lastError, CHECK_MODE);
    endif;
  endif;

  select
    case cycles = 0 is 
      enableMenuItem(self, 506);
      unCheckMenuItem(self, 506);
    endCase
    case cycles = 1 is 
      enableMenuItem(self, 506);
      checkMenuItem(self, 506);
    endCase
    case not(cycles) is
      unCheckMenuItem(self, 506);
      grayMenuItem(self, 506);
    endCase
  endSelect;


  /* make sure dasm symbols properly checked (0 = off, 1 = on) */
  if getDasmSymbol(DisAsmLibClass$Inst) = 0
    unCheckMenuItem(self, 507);
  else
    checkMenuItem(self, 507);
  endif;

  /* make sure save layout now properly checked (0 = off, 1 = on) */
  saveLayoutOnExit := getIniSaveLayoutOnExit(PreLauncher);
  if saveLayoutOnExit=1
    checkMenuItem(self, 520);
  else
    unCheckMenuItem(self, 520);
  endif;
}
!!


/* 12/3/1992 15:46 - PRIVATE
  Init layout menu
*/
Def initMenuLayout(self | aMenu)
{
 /* layout menu */
 aMenu := newPopup(MenuItem, "&Layout");
 addItem(aMenu, new(MenuItem, "Save Layout On E&xit", 520, #menuLayoutExit));
 addItem(aMenu, new(MenuItem, "Save Layout &Now",     521, #menuLayoutNow));
 ^aMenu;

}
!!

/* 12/3/1992 15:46 - PRIVATE
  Init configure menu
*/
Def initMenuConfigure(self | aMenu)
{
 /* configure menu */
 aMenu := newPopup(MenuItem, "&Configure");
 addItem(aMenu, new(MenuItem, "&Map...",            504, #actionOverlay));
 addItem(aMenu, new(MenuItem, "Run &Access",        505, #menuRunAccess));
 addItem(aMenu, new(MenuItem, "&Show Cycles",       506, #menuShowCycles));
 addItem(aMenu, new(MenuItem, "S&ymbolic Disassembly", 507, #menuSymDasm));
/* addItem(aMenu, new(MenuItem, "Mas&k Interrupts For Step", 513, #menuStepMask)); */
 addItem(aMenu, nil);
 addItem(aMenu, new(MenuItem, "Sa&ve Chip Selects...", 508, #menuSaveCS));
 addItem(aMenu, new(MenuItem, "&Restore Chip Selects...", 509, #menuRestCS));
/*
 addItem(aMenu, new(MenuItem, "&Configure Chip Selects", 510, #menuConfCS));
*/
 addItem(aMenu, nil);
 addItem(aMenu, new(MenuItem, "R&eset",             511, #menuReset));
 addItem(aMenu, new(MenuItem, "Reset CPU &Only",    512, #menuResetOnly));
 addItem(aMenu, new(MenuItem, "Re&link",             514, #menuRelink));
 ^aMenu;

}
!!

/* Redefine minimize and restore so they affect all windows in product.
   Model to follow is that of Visual Basic.
   All others messages are passed through to the default window proc. */
Def WM_SYSCOMMAND(self, wP, lP | wParam )
{
/* Four low-order bits of WM_SYSCOMMAND(wP) are used internally by Windows.
 * They need to be set to 0 before comparison.
 * see WM_SYSCOMMAND entry in SDK manual */
 wParam := wP bitAnd 0xFFF0;

 if (wParam = 0xF020)   /* SC_MINIMIZE: 0xF020 */
 then
    hideAllPresenters(PreLauncher);
 endif;

 if (wParam = 0xF120)   /* SC_RESTORE: 0xF120 */
 then
     showAllPresenters(PreLauncher);
 endif;

  ^asInt(execWindowProc(self, #WM_SYSCOMMAND, wP, lP));
}!!

/* 12/9/1992 11:17 - PRIVATE
  When user change RunAccess status from the CLI, event will generate to notify
  the presenter. Change the menu status accordingly.
*/
Def eventRunAccessOff(self)
{
  unCheckMenuItem(self, 504); /* 504 - menu command ID */
}
!!

/* 12/9/1992 11:17 - PRIVATE
  When user change RunAccess status from the CLI, event will generate to notify
  the presenter. Change the menu status accordingly.
*/
Def eventRunAccessOn(self)
{
  checkMenuItem(self, 504); /* 504 - menu command ID */
}
!!

/* 12/3/1992 15:48 - PRIVATE
  Set runAccess mode on/off.
*/
Def menuRunAccess(self)
{
  /* Set runAccess if RunAccess is not ON, else clear it */
  if (getRunAccess(HLBrkRootLibClass$Inst) <> BOOL_TRUE) then
      setRunAccess(HLBrkRootLibClass$Inst);
      checkMenuItem(self, 505);
  else
    clearRunAccess(HLBrkRootLibClass$Inst);
    unCheckMenuItem(self, 505);
  endif;
}
!!

/* BUTTON */
Def actionCliPresenter(self)
{
  launchCLIPresenter( PreLauncher, nil, SW_NORMAL ) ;
}
!!

/* BUTTON */
Def actionCPU(self)
{
  launchCPUPresenter( PreLauncher, nil, SW_NORMAL  ) ;
}
!!

/* BUTTON */
Def actionEmuGo(self)
{
  HLBreakLibClass$Inst cor requireWithPath( HLBreakLib, "bkptexec.dll" ) ;

  if HLBreakLibClass$Inst
  then
    showWaitCurs();
    go( HLBreakLibClass$Inst ) ;
    showOldCurs();
  else
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_CANT_DO_COMMAND, FORCE_POPUP, asciiz("Go"), nil, nil);
  endif ;
}
!!

/* BUTTON */
Def actionEmuHalt(self)
{
  HLBreakLibClass$Inst cor requireWithPath( HLBreakLib, "bkptexec.dll" ) ;

  if HLBreakLibClass$Inst
  then
    showWaitCurs();
    if TheSourcePresenter then
      stopAnimating(TheSourcePresenter);
    endif;
    halt( HLBreakLibClass$Inst ) ;
    showOldCurs();
  else
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_CANT_DO_COMMAND, FORCE_POPUP, asciiz("Halt"), nil, nil);
  endif ;
}
!!

/* BUTTON */
Def actionLoadCode(self)
{
  requireWithPath(ProcLib,     "proc.dll"      );
  requireWithPath(SymbolLib,   "symbl.dll"     );
  requireWithPath(AddressLib,  "addr.dll"      );
  requireWithPath(MemServLib,  "mem.dll"       );
  requireWithPath(CpuLib,      "cpu.dll"       );
  requireWithPath(LoaderLib,   "ld695.dll"     );
  ^invokeLoader(LoaderLibClass$Inst, self);
}
!!

/* BUTTON */
Def actionMemory(self)
{
  launchMemoryPresenter( PreLauncher, nil, SW_NORMAL  ) ;
}
!!

/* BUTTON */
Def actionOverlay(self)
{
  if (getSystemType(ProcLibClass$Inst) = PROC_POWERSCOPE) then
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_NOT_IN_POWERSCOPE, FORCE_POPUP, asciiz("Overlay memory"), nil, nil);
    ^nil;
  endif;
  launchOverlayPresenter( PreLauncher, self ) ;
}!!

/* BUTTON */
Def actionSourceCode(self)
{
  launchSourcePresenter( PreLauncher, nil, SW_NORMAL  ) ;
}
!!

/* BUTTON */
Def actionStack(self)
{
  launchStackPresenter( PreLauncher, nil, SW_NORMAL  ) ;
}
!!

/* BUTTON */
Def actionPeripheral(self)
{
  launchPeripheralPresenter(PreLauncher, nil, SW_NORMAL );
}
!!

/* BUTTON */
Def actionTracePresenter(self)
{
  if (getSystemType(ProcLibClass$Inst) = PROC_POWERSCOPE) then
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_NOT_IN_POWERSCOPE, FORCE_POPUP, asciiz("Trace display"), nil, nil);
    ^nil;
  endif;
  launchTracePresenter( PreLauncher, nil, SW_NORMAL  ) ;
}
!!

/* BUTTON */
Def actionTraceStart(self)
{
  if (getSystemType(ProcLibClass$Inst) = PROC_POWERSCOPE) then
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_NOT_IN_POWERSCOPE, FORCE_POPUP, asciiz("Trace"), nil, nil);
    ^nil;
  endif;

  select
    case TraceLibClass$Inst
    is trcTracingSet(TraceLibClass$Inst,1);
    endCase

    default
      showWaitCurs();
      requireWithPath( EvttmpltLib, "evttmplt.dll"  );
      requireWithPath( EventLib,    "event.dll"     );
      requireWithPath( TriggerLib,  getTriggerDLLName(PreLauncher));
      requireWithPath( TraceLib,    getTraceDLLName(PreLauncher));
      requireWithPath( DisAsmLib,   getDasmDLLName(PreLauncher));
      showOldCurs();
      if not(TraceLibClass$Inst)
      then ^nil ;
      else ^actionTraceStart( self ) ;
      endif ;
  endSelect;
}
!!

/* BUTTON */
Def actionTraceStop(self)
{
  if (getSystemType(ProcLibClass$Inst) = PROC_POWERSCOPE) then
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_NOT_IN_POWERSCOPE, FORCE_POPUP, asciiz("Trace"), nil, nil);
    ^nil;
  endif;

  select
    case TraceLibClass$Inst
    is trcTracingSet(TraceLibClass$Inst,0);
    endCase

    default
      showWaitCurs();
      requireWithPath( EvttmpltLib, "evttmplt.dll"  );
      requireWithPath( EventLib,    "event.dll"     );
      requireWithPath( TriggerLib,  getTriggerDLLName(PreLauncher));
      requireWithPath( TraceLib,    getTraceDLLName(PreLauncher));
      requireWithPath( DisAsmLib,   getDasmDLLName(PreLauncher));
      showOldCurs();
      if not(TraceLibClass$Inst)
      then ^nil ;
      else ^actionTraceStart( self ) ;
      endif ;
  endSelect;
}
!!

/* BUTTON */
Def actionTriggerPresenter(self)
{
  if (getSystemType(ProcLibClass$Inst) = PROC_POWERSCOPE) then
    displayFormattedError(ErrorTextLibClass$Inst,
       ER_NOT_IN_POWERSCOPE, FORCE_POPUP, asciiz("Trigger definition"), nil, nil);
    ^nil;
  endif;
  launchTriggerPresenter( PreLauncher, nil, SW_NORMAL  ) ;
}
!!

/* PRIVATE -- as a button to dictionaries as specified.
 Nota Bene: selected bitmap is shared between buttons.
*/
Def addButton(self, buttonName, buttonID, selectedButtonID,
              actionSymbol, positionRect | aButton)
{
  aButton := new(BitMapButton, buttonID, self,
        buttonName, asString(buttonID), asString(selectedButtonID));
  add(buttonPressDict, buttonID, aButton);

  add(buttonActionDict, buttonID, actionSymbol);
  setCRect(aButton, positionRect);
  moveWindow(aButton);

  ^aButton
}
!!

/* termination processing */
Def close(self | temp)
{
  if inClose? then ^nil; endif ;

  inClose? := #true ;
  /* Destroy TheProjectInfoObj which contains address desc */
  if TheProjectInfoObj cand isDirty(TheProjectInfoObj) then
    saveProjectProfile(TheProjectInfoObj);
    if isLoaded(currentLoadFile(TheProjectInfoObj)) then
      /* Remove the old loadfile Info */
      deleteLoadFile(currentLoadFile(TheProjectInfoObj));
      deleteLoadFileAddr(currentLoadFile(TheProjectInfoObj));
    endif;
    TheProjectInfoObj := nil;
  endif;
  /* Close and destroy the CL server */
  if TheCursorLinkServer then
    close(TheCursorLinkServer);
    TheCursorLinkServer := nil;
  endif;

  if TimerEventID
  then
    Call KillTimer( hWnd(self), TimerEventID ) ;
    timerCallBackFun cand free( timerCallBackFun ) ;
  endif ;
  closeEvents(EvNoteLibClass$Inst, eventDescSet);
  eventRespSet := nil;
  if TheToolBarPresenter then
    saveWindowPos(TheToolBarPresenter, "TheToolBarPresenter");
    TheToolBarPresenter := nil
  else
    clearLayoutEntry(Window, "TheToolBarPresenter");
  endif;

  /*  removeWindowMenu( self ) -- really do need to delete this here */
  close(TheHelpObject, hWnd(self)); /* Close PwrViews WindowHelp */
  closeAllPresenters(PreLauncher);
  /* Force the Stack server to terminate itself */
  terminateServer(StackLibClass$Inst);
  /* All libraries are gone - do not access library */
  removeAllLibs(ProvidedLibs);

  close(self:ancestor);
}!!

/* WINDOWS */
Def command(self, wP, lP | msg)
{
  if (msg := at(buttonActionDict, wP))
  then
    perform( self, msg ) ;
    if ((wP = TB_TRACE_START_ID) cor (wP = TB_TRACE_STOP_ID) cor
        (wP = TB_EMU_GO_ID) cor (wP = TB_EMU_HALT_ID)) then
      Call SetFocus(getHWnd(self));
    endif;
  else if (msg := action(menu, wP))
    then
      perform( self, msg ) ;
    else
      if not( doAction(PreLauncher, wP) )
      then
        command( self:ancestor, wP, lP ) ;
      endif ;
    endif ;
  endif ;
}
!!

/* WINDOWS */
Def destroy(self)
{
  if not(inClose?)
  then
    inClose? := #true ;
    closeEvents(EvNoteLibClass$Inst, eventDescSet);
    eventRespSet := nil;
    if TheToolBarPresenter then TheToolBarPresenter := nil endif ;
    closeAllPresenters( PreLauncher ) ;
    removeAllLibs( ProvidedLibs ) ;
    nilifyPowerViews( PreLauncher ) ;  /* needed in development only */
  endif ;

  do(buttonPressDict,
    {using(aButton) destroy(aButton);}
  );

  destroy( self:ancestor ) ;
}
!!

/* PRIVATE -- use buttonActionDict to draw labels */
Def drawLabels(self, hDC | hPen, hPenOld)
{
  hPen := Call CreatePen( 0 /* SP_SOLID */,
                          2, /* width */
                          Call GetSysColor(COLOR_WINDOWTEXT) );
  hPenOld := Call SelectObject( hDC, hPen ) ;

  assocsDo(groupWidthDict, /* symbol->rect */
  {using(a | k v mid textStart)
    mid := ( width(v := value(a)) / 2 ) ;
    textStart := mid + left(v) - (((size(k := key(a)) +1) * tmWidth) / 2);
    Call TextOut( hDC, textStart,                             /* X */
                      (top(v) - (2*TB_TO_BORDER + tmHeight)), /* Y */
                      asciiz(asString(k)), size(k) ) ;
    Call Rectangle( hDC, left(v), top(v)-(TB_TO_BORDER+2),
                         right(v), top(v)-TB_TO_BORDER ) ;
  });

  Call SelectObject( hDC, hPenOld ) ;
  Call DeleteObject( hPen ) ;
}!!

/* PUBLIC EVENT */
Def eventCloseApplication(self)
{
  close( self ) ;
}!!

/* 7/20/1992 14:12 - PRIVATE
  OPERATION NOTES:
    The Event_Symbol_Deleted will destroy the old loadfile info, if any.
    This method respond to both Window or CLI loading event to retrieve the information.
*/
Def eventLoadingCompleted(self | loadInfo, newLoadFile, symInfo, string, i)
{
  if not(loadInfo := getLoadOptions(LoaderLibClass$Inst))
    ^nil;
  endif;
  /* Code loaded, get code and data address ranges */
  if ((loadInfo[2]  bitAnd 0x2) <> 0) then
    /* Get load region addresses of the current LoadFile */
    getAddressRange(currentLoadFile(TheProjectInfoObj));
  endif;

  /* Save loadfile info to the current loadfile */
  if isLoaded(currentLoadFile(TheProjectInfoObj)) then
    setLoadFileName(currentLoadFile(TheProjectInfoObj), loadInfo[0]);
    setLoadStatus(currentLoadFile(TheProjectInfoObj), #true);
  else
    setCurrentLoadFile(TheProjectInfoObj, init(currentLoadFile(TheProjectInfoObj),
      loadInfo[0], #true));
  endif;
  /* Added the new last loadfile to the collections */
  if TheSourcePresenter cand
     setLastLoadFile(TheProjectInfoObj, loadInfo[0]) then
     /* Rebuild the last loadfiles list in File Menu */
     rebuildSourceLastLoadFileList(TheSourcePresenter, lastLoadFiles(TheProjectInfoObj));
  endif;
  /* Store project info */
  setLoadFlags(TheProjectInfoObj, loadInfo[2]); /* load flags encoded */
    /*find path and add to .INI <Judy 7/15/97>*/
  string := loadInfo[0];
  i := size(string)-1;
  loop
  while i > 0
    if (string[i] = '\')
    then
        string := subString(string,0,i+1);
        i := 0;
    else
        i := i - 1;
    endif;
  endLoop;
  addAliasPath(TheProjectInfoObj,string);

  setOnDemand(TheProjectInfoObj, loadInfo[1]);  /* onDemand */
  /* Symbol loading */
  if (((loadInfo[2]  bitAnd 0x1) <> 0) cand
     ((symInfo := getSymbolsInfo(SymbolLibClass$Inst)) cand
     (symInfo[0] > 0) cand (symInfo[1] > 0))) then 
    /* NOTES: symInfo = #(numSymbols, numModules, numTypes) */ 
    setNumberOfModules(currentLoadFile(TheProjectInfoObj), symInfo[1]);  
    /* Source Window opened, update it current view and menu */
    if TheSourcePresenter then
      eventDasmSymChanged(TheSourcePresenter);
      validateSourceCommands(TheSourcePresenter);
    endif;  
  endif;
  setPrjDirty(TheProjectInfoObj, #true);
  /* Event CPU_CHANGES will update the Source Presenter */
  getStartPC(self);
  beep();
  ^GOOD;
}

!!

/* 7/20/1992 14:33 - PRIVATE
  When symbol_deleted event occurred, remove all symbolic information of the
  Project Info's CurrentLoadFile.
*/
Def eventSymbolDeleted(self)
{
  if isLoaded(currentLoadFile(TheProjectInfoObj)) then
    /* Remove the old loadfile Info */
    deleteLoadFile(currentLoadFile(TheProjectInfoObj));
    /* Update the Source Presenter and its commands */
    if TheSourcePresenter then
      /* Reset the Source Presenter display */
      removeSourceSymbols(TheSourcePresenter);
    endif;
    ^GOOD;
  endif;
  ^nil;
}

!!

/* 7/20/1992 14:33 - PRIVATE
  When symbol_initLoad event occurred, remove all symbolic information of the
  Project Info's CurrentLoadFile.
*/
Def eventSymbolInitLoad(self)
{
  if isLoaded(currentLoadFile(TheProjectInfoObj)) then
    /* Remove the old loadfile Info */
    deleteLoadFile(currentLoadFile(TheProjectInfoObj));
    /* Update the Source Presenter and its commands */
    if TheSourcePresenter then
      removeSourceSymbols(TheSourcePresenter);
    endif;
    ^GOOD;
  endif;
  ^nil;
}

!!

/* PRIVATE -- N.B. initButtons() must be called before drawLabels() */
Def init(self)
{
  init(self:ancestor);
  initTextMetrics(self);
  initButtons(self,
     (2 * TB_TO_BORDER) + tmHeight
  );
  initMenuBar(self);
  addAbout(self);              /* About box & Exit app */
  TheProjectInfoObj := init(new(PrjInfo));
  TheCursorLinkServer := new(CLServer, 1);
  initComplete := 0;
 /*  initialize ext in number and active logic state value 
   in Ext In Select dialog box; Added by Jimmy 11/11/94 */   
  extInSel := 1;
  logicState := 111;
  tmpExtInSel := 1;
  tmpLogicState := 111;
  /* Winky 3/5/98 add isBoth flag */
  isBoth := 0;
  checkMenuItems(self);
}
!!

/* PRIVATE
   Set up BitMapButtons
*/
Def initButtons(self, topPos | leftPos tmpPos, mt2Flag)
{
  /* Create child controls for execution buttons */
  buttonPressDict  := new(Dictionary, 15) ;
  buttonActionDict := new(Dictionary, 15) ;
  groupWidthDict   := new(Dictionary, 5) ;
  leftPos := tmpPos := ( 0 + TB_TO_BORDER ) ;
  if (getTraceModule(ProcLibClass$Inst) <> nil) then
     mt2Flag:=1;
  else
     mt2Flag:=0;
  endif; 
  if (mt2Flag=1) then
     tmpPos  := initSetupButtons( self, topPos, leftPos ) ;
  else
     tmpPos  := initSetupMButtons( self, topPos, leftPos ) ;
  endif;
 
  add( groupWidthDict, #Setup,
       rect(leftPos, topPos, tmpPos, topPos+TB_BUTTON_WIDTH) ) ;

  leftPos := tmpPos + TB_BETWEEN_GROUPS ;
  tmpPos  := initTargetButtons( self, topPos, leftPos ) ;
  add( groupWidthDict, #Target,
       rect(leftPos, topPos, tmpPos, topPos+TB_BUTTON_WIDTH) ) ;

  leftPos := tmpPos + TB_BETWEEN_GROUPS ;
  tmpPos  := initEmulationButtons( self, topPos, leftPos ) ;
  add( groupWidthDict, #Emulation,
       rect(leftPos, topPos, tmpPos, topPos+TB_BUTTON_WIDTH) ) ;

  if (mt2Flag=1) then
     leftPos := tmpPos + TB_BETWEEN_GROUPS ;
     tmpPos  := initTraceButtons( self, topPos, leftPos ) ;
     add( groupWidthDict, #Trace,
          rect(leftPos, topPos, tmpPos, topPos+TB_BUTTON_WIDTH) ) ;
  else
  endif;

  leftPos := tmpPos + TB_BETWEEN_GROUPS ;
  tmpPos  := initUtilityButtons( self, topPos, leftPos ) ;
  add( groupWidthDict, #Misc,
       rect(leftPos, topPos, tmpPos, topPos+TB_BUTTON_WIDTH) ) ;

  /* Fuzz is required because Windows does not give the number of
     pixels asked for.  Ask uSoft why...  8^( */
  leftPos := ( tmpPos + TB_TO_BORDER + TB_MS_FUZZ ) ;

  /* set up client rect for window (left, top, right, bottom) */
  /* put at 10@10, upper left corner */
  setCRect( self, rect(0, 0, leftPos, 
           (4*tmHeight) + (tmHeight/3) + TB_BUTTON_WIDTH + TB_TO_BORDER) ) ;
  moveWindow( self ) ;
}!!

Def initEmulationButtons(self, topPos, leftPos)
{
  addButton(self, "Go!",
                  TB_EMU_GO_ID, TB_EMU_GO_SELECTED_ID,
                  #actionEmuGo,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  addButton(self, "Halt!",
                  TB_EMU_HALT_ID, TB_EMU_HALT_SELECTED_ID,
                  #actionEmuHalt,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;

  ^leftPos
}!!

/* 7/20/1992 14:06 - PRIVATE */
Def initEvents(self | events)
{
  /* REGISTER with Event Notification for
   *       Loading LoadFiles events,
   *       Whatever...
   */

  eventRespSet := new(Dictionary, 8);

  /* dynamic to pick up current values */
  events := tuple(
                  EVENT_BKROOT_RUNACCESS_ON,
                  EVENT_BKROOT_RUNACCESS_OFF,
                  EVENT_SYMBOL_INIT_LOAD,
                  EVENT_SYMBOL_DELETED,
                  EVENT_LDR_LOAD_COMPLETE,
                  EVENT_CLOSE_APPLICATION
                 ) ;
  /* Setup events respond messages */
  add(eventRespSet, EVENT_BKROOT_RUNACCESS_ON   , #eventRunAccessOn);
  add(eventRespSet, EVENT_BKROOT_RUNACCESS_OFF  , #eventRunAccessOff);
  add(eventRespSet, EVENT_SYMBOL_INIT_LOAD      , #eventSymbolInitLoad);
  add(eventRespSet, EVENT_SYMBOL_DELETED        , #eventSymbolDeleted);
  add(eventRespSet, EVENT_LDR_LOAD_COMPLETE     , #eventLoadingCompleted);
  add(eventRespSet, EVENT_CLOSE_APPLICATION     , #eventCloseApplication);

  /* register with Event Notification library */
  requireWithPath( EvNoteLib, "enlib.dll");
  ^(eventDescSet := registerEvents( EvNoteLibClass$Inst, hWnd(self), events));
}


!!

/* PRIVATE */
Def initMenuBar(self)
{
 menu := create(new(Menu), self);
 hMenu := handle(menu);

 addItem(menu, initMenuFile(self));
 addItem(menu, initMenuConfigure(self));
 addItem(menu, initMenuLayout(self));

 if (getSystemType(ProcLibClass$Inst) = PROC_POWERSCOPE)
   grayMenuItem(menu, 504);  /* map */
   grayMenuItem(menu, 510);  /* configure chip selects */
 endif;

 Call AppendMenu(hMenu,
                 MF_POPUP,
                 windowsMenu(PreLauncher),
                 asciiz("&Windows"));

 addItem(menu, initMenuHelp(self));
 /* Check for Options Menu */
 if (getRunAccess(HLBrkRootLibClass$Inst) = BOOL_TRUE) then
   checkMenuItem(self, 504);
 endif;

/* returns 1 if TRUE, 0 if false */
  saveLayoutOnExit := getIniSaveLayoutOnExit(PreLauncher);
  if saveLayoutOnExit=1
    unCheckMenuItem(self, 520);
  else
    putIniSaveLayoutOnExit(PreLauncher, 0);  /* create it */
    checkMenuItem(self, 520);
  endif;

 drawMenu(self);
}
!!

/* PRIVATE */
Def initMenuFile(self | aMenu)
{
 /* FILE menu */
 aMenu := newPopup(MenuItem, "&File");
 addItem(aMenu, new(MenuItem,
                    "E&xit MP/SLD...",
                     503,
                     #menuExitApplication));
 ^aMenu;
}
!!

/* BUTTON */
Def initMenuHelp(self | aMenu)
{
 /* HELP menu */
 aMenu := newPopup(MenuItem, "&Help");
 addItem(aMenu, new(MenuItem,
                    "Help &Index",
                     INDEX_HELP,
                     #menuHelpContents));
 addItem(aMenu, new(MenuItem,
                    "&Help With Help",
                     USING_HELP,
                     #menuHelpHelp));
 addItem(aMenu, nil);
 addItem(aMenu, new(MenuItem,
                    "About &MP/SLD...",
                     IDSABOUT,
                     #menuAbout));
 ^aMenu;

 ^aMenu
}
!!

Def initSetupButtons(self, topPos, leftPos | systemType)
{
  systemType := getSystemType(ProcLibClass$Inst);
  if (systemType = PROC_POWERPACK) cor (systemType = PROC_MICEPACK)
    addButton(self, "Overlay",
                  TB_OVERLAY_ID, TB_OVERLAY_SELECTED_ID,
                  #actionOverlay,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */
  else
    addButton(self, "Overlay",
                  TB_NO_OVERLAY_ID, TB_NO_OVERLAY_ID,
                  #actionOverlay,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */
  endif;

  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  addButton(self, "Load Code",
                  TB_LOAD_ID, TB_LOAD_SELECTED_ID,
                  #actionLoadCode,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  if (systemType = PROC_POWERPACK) cor (systemType = PROC_MICEPACK)
    addButton(self, "Setup Trigger",
                  TB_TRACE_SETUP_ID, TB_TRACE_SETUP_SELECTED_ID,
                  #actionTriggerPresenter,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */
  else
    addButton(self, "Setup Trigger",
                  TB_NO_TRACE_SETUP_ID, TB_NO_TRACE_SETUP_ID,
                  #actionTriggerPresenter,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */
  endif;

  leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;

  ^leftPos
}!!

Def initTargetButtons(self, topPos, leftPos)
{
  addButton(self, "Code", /* source code */
                  TB_SOURCE_ID, TB_SOURCE_SELECTED_ID,
                  #actionSourceCode,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  addButton(self, "Stack",
                  TB_STACK_ID, TB_STACK_SELECTED_ID,
                  #actionStack,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  addButton(self, "CPU",
                  TB_CPU_ID, TB_CPU_SELECTED_ID,
                  #actionCPU,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */

  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  addButton(self, "Mem",
                  TB_MEMORY_ID, TB_MEMORY_SELECTED_ID,
                  #actionMemory,
                  rect( leftPos, /* (left, top, right, bottom) */
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) ); /* width=height */


  leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

  addButton(self, "Periph",
                  TB_PERIPHERAL_ID, TB_PERIPHERAL_SELECTED_ID,
                  #actionPeripheral,
                  rect( leftPos,
                        topPos,
                        leftPos+TB_BUTTON_WIDTH,
                        topPos+TB_BUTTON_WIDTH) );

  leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;

  ^leftPos
}!!

/* PRIVATE
  Initialize text metrics data for this window.  Load the font data
  into textMetrics, set the text width and height instance variables.
*/
Def initTextMetrics(self | hdc, tm)
{ tm := new(Struct, 32);
  Call GetTextMetrics(hdc := getContext(self), tm);
  Call SelectObject(hdc, Call GetStockObject(SYSTEM_FIXED_FONT));
  tmWidth  := asInt(wordAt(tm, 10));
  tmHeight := asInt(wordAt(tm, 8)) + asInt(wordAt(tm, 0));
  Call SelectObject(hdc, Call GetStockObject(SYSTEM_FONT));
  releaseContext(self, hdc);
}!!

/* PRIVATE to PreLauncher
 -- initialize a timer and provide a callback function
*/
Def initTimer(self)
{
  if TimerEventID then ^TimerEventID; endif ; /* already called */

  /* create a window callback function to service timer ticks */
/*@@{
  timerCallBackFun :=
    create( Callback,
            tuple(0,0,0,1),
            {using(hWnd,winMsg,IDEvent,sysTime)
              if afterFIrstCallback
              then
                getBkptCause(HLBreakLibClass$Inst); /* force a comm read *@
                printNewLine("Timer Tick: " + asHex(sysTime)) ;
              else
                afterFIrstCallback := #true ;
                /*@@ startupScript( PreLauncher ) ; @@*@
                printNewLine("first timer tick " +asHex(sysTime));
              endif ;
              1;  /* return value -- of interest?? *@
            }
          ) ;
                     /* 1/2 second = 500 milliSeconds *@
   TimerEventID := Call SetTimer(0,0,1000,lock(timerCallBackFun)) ;
}@@*/

   TimerEventID := 0 ;

   if ((Call SetTimer(hWnd(self),TimerEventID,1000,0)) = 0)  /* error! */
   then TimerEventID := nil ;
   endif ;

   ^TimerEventID  /* N.B. Caller must check! */
}
!!

Def initTraceButtons(self, topPos, leftPos | systemType)
{
  systemType := getSystemType(ProcLibClass$Inst);
  if (systemType = PROC_POWERPACK)
    addButton(self, "Start!",
       TB_TRACE_START_ID, TB_TRACE_START_SELECTED_ID,
       #actionTraceStart, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

    addButton(self, "Stop!",
       TB_TRACE_STOP_ID, TB_TRACE_STOP_SELECTED_ID,
       #actionTraceStop, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

    addButton(self, "Show",
       TB_TRACE_SHOW_ID, TB_TRACE_SHOW_SELECTED_ID,
       #actionTracePresenter, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;
  else if (systemType = PROC_MICEPACK)
    addButton(self, "Start!",
       TB_TRACE_START_ID, TB_TRACE_START_SELECTED_ID,
       #actionTraceStart, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

    addButton(self, "Stop!",
       TB_TRACE_STOP_ID, TB_TRACE_STOP_SELECTED_ID,
       #actionTraceStop, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

    addButton(self, "Show",
       TB_TRACE_SHOW_ID, TB_TRACE_SHOW_SELECTED_ID,
       #actionTracePresenter, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;
  else
    addButton(self, "Start!",
       TB_NO_TRACE_START_ID, TB_NO_TRACE_START_ID,
       #actionTraceStart, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

    addButton(self, "Stop!",
       TB_NO_TRACE_STOP_ID, TB_NO_TRACE_STOP_ID,
       #actionTraceStop, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH + TB_BETWEEN_BUTTONS ) ;

    addButton(self, "Show",
       TB_NO_TRACE_SHOW_ID, TB_NO_TRACE_SHOW_ID,
       #actionTracePresenter, rect( leftPos, /* (left, top, right, bottom) */
       topPos, leftPos+TB_BUTTON_WIDTH,
       topPos+TB_BUTTON_WIDTH) ); /* width=height */

    leftPos := ( leftPos + TB_BUTTON_WIDTH ) ;
  endif;
  endif;

  ^leftPos
}!!
