home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / IOC / MMREMOTE / MMREMOTE.CPP < prev    next >
Text File  |  1995-05-01  |  47KB  |  1,132 lines

  1. /******************************************************************************/
  2. /* mmremote  SAMPLE PROGRAM - Version 1: Class Implementation                 */
  3. /*                                                                            */
  4. /* COPYRIGHT: Copyright (C) International Business Machines Corp., 1992,1995. */
  5. /*                                                                            */
  6. /* DISCLAIMER OF WARRANTIES:                                                  */
  7. /*   The following [enclosed] code is sample code created by IBM              */
  8. /*   Corporation.  This sample code is not part of any standard IBM product   */
  9. /*   and is provided to you solely for the purpose of assisting you in the    */
  10. /*   development of your applications.  The code is provided "AS IS",         */
  11. /*   without warranty of any kind.  IBM shall not be liable for any damages   */
  12. /*   arising out of your use of the sample code, even if they have been       */
  13. /*   advised of the possibility of such damages.                              */
  14. /******************************************************************************/
  15.  
  16. #ifndef _IBASE_                         //Make sure ibase.hpp is included
  17.   #include <ibase.hpp>                  //  since that is where IC_<environ>
  18. #endif                                  //  is defined.
  19. #include "mmremote.hpp"
  20. #include <ifont.hpp>
  21. #include <immttime.hpp>
  22. #include <inotifev.hpp>
  23. #include <imsgbox.hpp>
  24.  
  25. //*************************************************************************
  26. // main  - Application entry point                                        *
  27. //*************************************************************************
  28.  
  29. int main()
  30. {
  31.   MainWindow  mainWindow(WINDOWID);
  32.   IApplication::current().run();
  33.   return 0;
  34. }
  35.  
  36. //******************************************************************************
  37. // KeyPad::KeyPad                                                              *
  38. //   Defines the keypad 0-9 for entering tracks for the CD player or special   *
  39. //   functions for the video player.                                           *
  40. //******************************************************************************
  41.  
  42. KeyPad::KeyPad(unsigned long windowid,
  43.                IWindow*          parent,
  44.                IWindow*          owner)
  45.       : IMultiCellCanvas(windowid,parent,owner),
  46.         one             (ONEID   ,this  ,owner),
  47.         two             (TWOID   ,this  ,owner),
  48.         three           (THREEID ,this  ,owner),
  49.         four            (FOURID  ,this  ,owner),
  50.         five            (FIVEID  ,this  ,owner),
  51.         six             (SIXID   ,this  ,owner),
  52.         seven           (SEVENID ,this  ,owner),
  53.         eight           (EIGHTID ,this  ,owner),
  54.         nine            (NINEID  ,this  ,owner),
  55.         zero            (ZEROID  ,this  ,owner)
  56. {
  57.    one.setText  ("1");
  58.    two.setText  ("2");
  59.    three.setText("3");
  60.    four.setText ("4");
  61.    five.setText ("5");
  62.    six.setText  ("6");
  63.    seven.setText("7");
  64.    eight.setText("8");
  65.    nine.setText ("9");
  66.    zero.setText ("0");
  67.  
  68. //*****************************************************************************
  69. //  Lay out the keypad multicell canvas - 3 columns, 4 rows, no margins       *
  70. //*****************************************************************************
  71.  
  72.    addToCell(&one,           1, 1, 1, 1);
  73.    addToCell(&two,           2, 1, 1, 1);
  74.    addToCell(&three,         3, 1, 1, 1);
  75.    addToCell(&four,          1, 2, 1, 1);
  76.    addToCell(&five,          2, 2, 1, 1);
  77.    addToCell(&six,           3, 2, 1, 1);
  78.    addToCell(&seven,         1, 3, 1, 1);
  79.    addToCell(&eight,         2, 3, 1, 1);
  80.    addToCell(&nine,          3, 3, 1, 1);
  81.    addToCell(&zero,          2, 4, 1, 1);
  82. }
  83. //*******************************************************************************
  84. // MainWindow::~MainWindow                                                      *
  85. //   Destruct the remote control main window                                    *
  86. //                                                                              *
  87. //*******************************************************************************
  88.  
  89. MainWindow::~MainWindow()
  90. {
  91.    if (cdPlayer)
  92.       delete cdPlayer;
  93.    if (digPlayer)
  94.       delete digPlayer;
  95.    if (midPlayer)
  96.       delete midPlayer;
  97.    if (wavPlayer)
  98.       delete wavPlayer;
  99.    if (handler)
  100.       delete handler;
  101.    if (observer)
  102.       delete observer;
  103. }
  104.  
  105. //*******************************************************************************
  106. // MainWindow::MainWindow                                                       *
  107. //   Construct the remote control main window                                   *
  108. //                                                                              *
  109. //*******************************************************************************
  110.  
  111. MainWindow::MainWindow( unsigned long windowId)
  112.           : IFrameWindow("Multimedia MMREMOTE Sample",windowId),
  113.             newTrackDigit1(0),
  114.             newTrackDigit2(1),
  115.             flyText(FLYTEXTID, this),
  116.             flyHelpHandler(&flyText, 100, 5),
  117.  
  118.  
  119. //*****************************************************************************
  120. // remoteCanvas is the main canvas.  devices, controls, volkey, volume, and   *
  121. // pad are canvases it contains                                               *
  122. //*****************************************************************************
  123.  
  124.             remoteCanvas(REMOTECANVASID ,this,this),
  125.             devices     (DEVID   ,&remoteCanvas,this),
  126.             controls    (CTLID   ,&remoteCanvas,this),
  127.             volkey      (VKID    ,&remoteCanvas,this),
  128.             volume      (VOLUMEID,&volkey,this),
  129.             pad         (PADID   ,&volkey,this),
  130.  
  131. //*****************************************************************************
  132. //  These are the control buttons for the remote control                      *
  133. //*****************************************************************************
  134.  
  135.             powerbtn        (POWERID ,&remoteCanvas,this,IRectangle(),
  136.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  137.             volupbtn        (VOLUPID ,&volume,this,IRectangle(),
  138.                             IControl::group |
  139.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  140.             voldnbtn        (VOLDNID ,&volume,this,IRectangle(),
  141.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  142.             playbtn         (PLAYID  ,&controls,this,IRectangle(),
  143.                             ICustomButton::latchable |
  144.                             ICustomButton::autoLatch |
  145.                             IControl::group |
  146.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  147.             stopbtn         (STOPID  ,&controls,this,IRectangle(),
  148.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  149.             rewbtn          (REWID   ,&controls,this,IRectangle(),
  150.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  151.             ffbtn           (FFID    ,&controls,this,IRectangle(),
  152.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  153.             pausebtn        (PAUSEID ,&controls,this,IRectangle(),
  154.                             ICustomButton::latchable |
  155.                             ICustomButton::autoLatch |
  156.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  157.             stepOrTrackFBtn (STEPTRACKFID ,&controls,this,IRectangle(),
  158.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  159.             stepOrTrackBBtn (STEPTRACKBID ,&controls,this,IRectangle(),
  160.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  161.  
  162. //*****************************************************************************
  163. //  These are the device selection buttons for video, midi, CD, and wave      *
  164. //  players                                                                   *
  165. //*****************************************************************************
  166.  
  167.             videobtn        (VIDEOID ,&devices,this,IRectangle(),
  168.                             IControl::group |
  169.                             ICustomButton::autoLatch |
  170.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  171.             midibtn         (MIDIID  ,&devices,this,IRectangle(),
  172.                             ICustomButton::autoLatch |
  173.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  174.             cdbtn           (CDID    ,&devices,this,IRectangle(),
  175.                             ICustomButton::autoLatch |
  176.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  177.             wavebtn         (WAVEID  ,&devices,this,IRectangle(),
  178.                             ICustomButton::autoLatch |
  179.                             IWindow::visible | IAnimatedButton::animateWhenLatched),
  180.  
  181. //*****************************************************************************
  182. //  This is the status line for the playing device                            *
  183. //*****************************************************************************
  184.  
  185.             readout     (READOUTID, &remoteCanvas,this),
  186.  
  187.  
  188. //*****************************************************************************
  189. //  Set the pointers for the devices to be zero.                              *
  190. //*****************************************************************************
  191.    player   (0),
  192.    cdPlayer (0),
  193.    digPlayer(0),
  194.    midPlayer(0),
  195.    wavPlayer(0),
  196.    handler  (0),
  197.    observer (0)
  198.  
  199. //*****************************************************************************
  200. //  Open the CD player.  If not ready, post message and allow retry or cancel.*
  201. //  Then point the player to the default device - CD and set the device ID.   *
  202. //*****************************************************************************
  203.  
  204. {
  205.    try
  206.    {
  207.       //***********************************************************************
  208.       //  Construct the CD player. The default arguments cause the audio CD   *
  209.       //  device to be opened so we don't need to make an additional open()   *
  210.       //  call later.  Also, it uses the system profile for storing and       *
  211.       //  retrieving information(track titles, disc titles, playback order of *
  212.       //  the tracks).  If we get an error opening the audio CD device then   *
  213.       //  the remote will not control the audio cd player.                    *
  214.       //***********************************************************************
  215.       cdPlayer = new IMMAudioCD();
  216.       while (!cdPlayer->isMediaPresent())
  217.       {
  218.          IMessageBox::Response response = IMessageBox::cancel;
  219.          IMessageBox msgBox(this);
  220.          response = msgBox.show("No audio CD present.  Insert an audio CD and retry or cancel.",
  221.                      IMessageBox::retryCancelButton  |
  222.                      IMessageBox::errorIcon          |
  223.                      IMessageBox::moveable );
  224.          if (response == IMessageBox::cancel)
  225.          {
  226.             msgBox.show("The CD functions are disabled.",
  227.                         IMessageBox::okButton  |
  228.                         IMessageBox::errorIcon |
  229.                         IMessageBox::moveable );
  230.             cdbtn.disable();
  231.             delete cdPlayer;
  232.             cdPlayer = 0;
  233.             break;
  234.          }
  235.       }
  236.    }
  237.    catch (IException& exc)
  238.    {
  239.       IMessageBox msgBox(this);
  240.       msgBox.show("Could not open the CD device.  The CD functions are disabled.",
  241.                   IMessageBox::okButton  |
  242.                   IMessageBox::errorIcon |
  243.                   IMessageBox::moveable );
  244.       cdbtn.disable();
  245.    }
  246.    if (cdPlayer)
  247.    {
  248.       player = cdPlayer;
  249.       playerDevice = CDID;
  250.       try
  251.       {
  252.          //********************************************************************
  253.          //  Allow CD sound to be played without a connector cable            *
  254.          //********************************************************************
  255.          cdPlayer->enableConnector(IMMDevice::cdStream);
  256.       }
  257.       catch (IException& exc)
  258.       {
  259.          IMessageBox msgBox(this);
  260.          msgBox.show("Could not enable digital transfer for the CD device, as a result, the remote will not be able to control the volume of the audio CD player.",
  261.                      IMessageBox::okButton  |
  262.                      IMessageBox::errorIcon |
  263.                      IMessageBox::moveable );
  264.       }
  265.    } /* endif */
  266.  
  267.  
  268.    try
  269.    {
  270.       wavPlayer = new IMMWaveAudio();
  271.       if (!player)
  272.       {
  273.          player       = wavPlayer;
  274.          playerDevice = WAVEID;
  275.       } /* endif */
  276.    }
  277.    catch (IException& exc)
  278.    {
  279.       IMessageBox msgBox(this);
  280.       msgBox.show("Could not open the wave audio device.  The wave audio functions are disabled.",
  281.                   IMessageBox::okButton  |
  282.                   IMessageBox::errorIcon |
  283.                   IMessageBox::moveable );
  284.       wavebtn.disable();
  285.    }
  286.    try
  287.    {
  288.       digPlayer = new IMMDigitalVideo();
  289.       if (!player)
  290.       {
  291.          player       = digPlayer;
  292.          playerDevice = VIDEOID;
  293.       } /* endif */
  294.    }
  295.    catch (IException& exc)
  296.    {
  297.       IMessageBox msgBox(this);
  298.       msgBox.show("Could not open the digital video device.  The digital video functions are disabled.",
  299.                   IMessageBox::okButton  |
  300.                   IMessageBox::errorIcon |
  301.                   IMessageBox::moveable );
  302.       videobtn.disable();
  303.    }
  304.    try
  305.    {
  306.       midPlayer = new IMMSequencer();
  307.       if (!player)
  308.       {
  309.          player       = midPlayer;
  310.          playerDevice = MIDIID;
  311.       } /* endif */
  312.    }
  313.    catch (IException& exc)
  314.    {
  315.       IMessageBox msgBox(this);
  316.       msgBox.show("Could not open the midi device.  The midi functions are disabled.",
  317.                   IMessageBox::okButton  |
  318.                   IMessageBox::errorIcon |
  319.                   IMessageBox::moveable );
  320.       midibtn.disable();
  321.    }
  322.  
  323.  
  324. //*****************************************************************************
  325. //  Put the bitmaps on the buttons                                            *
  326. //*****************************************************************************
  327.  
  328.    powerbtn.setBitmaps(BMPPOWER,1);
  329.    volupbtn.setBitmaps(IAnimatedButton::volumeUp);
  330.    voldnbtn.setBitmaps(IAnimatedButton::volumeDown);
  331.    rewbtn.setBitmaps  (IAnimatedButton::rewind);
  332.    ffbtn.setBitmaps   (IAnimatedButton::fastForward);
  333.    pausebtn.setBitmaps(IAnimatedButton::pause);
  334.    stopbtn.setBitmaps (IAnimatedButton::stop);
  335.    playbtn.setBitmaps (IAnimatedButton::play);
  336.    stepOrTrackBBtn.setBitmaps(IAnimatedButton::trackReverse);
  337.    stepOrTrackFBtn.setBitmaps(IAnimatedButton::trackAdvance);
  338.    videobtn.setBitmaps(BMPVIDEO,1);
  339.    midibtn.setBitmaps (BMPMIDI ,1);
  340.    cdbtn.setBitmaps   (BMPCD   ,1);
  341.    wavebtn.setBitmaps (BMPWAVE ,1);
  342.  
  343. //*****************************************************************************
  344. //  Set the text for each of the buttons.  The \n causes the following word   *
  345. //  to be on a new line                                                       *
  346. //*****************************************************************************
  347.  
  348.    powerbtn.setText("Power" );
  349.    volupbtn.setText("Volume\nUp");
  350.    voldnbtn.setText("Volume\nDown");
  351.    videobtn.setText("Video" );
  352.    midibtn.setText ("Midi"  );
  353.    cdbtn.setText   ("CD"    );
  354.    wavebtn.setText ("Wave"  );
  355.  
  356. //*****************************************************************************
  357. //  Build the main canvas.  Columns 1 and 3 and rows 1 and 11 are margins     *
  358. //*****************************************************************************
  359.  
  360.    remoteCanvas.addToCell(&powerbtn,      2, 2, 1, 1);
  361.    remoteCanvas.addToCell(&devices,       2, 4, 1, 1);
  362.    remoteCanvas.addToCell(&volkey,        2, 6, 1, 1);
  363.    remoteCanvas.addToCell(&controls,      2, 8, 1, 1);
  364.    remoteCanvas.addToCell(&readout,       2, 10, 1,1);
  365.    remoteCanvas.setColumnWidth(1, MARGIN, true);
  366.    remoteCanvas.setColumnWidth(3, MARGIN, true);
  367.    remoteCanvas.setRowHeight  (1, MARGIN, true);
  368.    remoteCanvas.setRowHeight  (11, MARGIN, true);
  369.  
  370. //*****************************************************************************
  371. //  Calculate size for control buttons to keep them all the same.             *
  372. //*****************************************************************************
  373.  
  374.    ISize bigbtn;
  375.    bigbtn = bigbtn.maximum(playbtn.minimumSize());
  376.    bigbtn = bigbtn.maximum(stopbtn.minimumSize());
  377.    bigbtn = bigbtn.maximum(rewbtn.minimumSize());
  378.    bigbtn = bigbtn.maximum(ffbtn.minimumSize());
  379.    bigbtn = bigbtn.maximum(pausebtn.minimumSize());
  380.    bigbtn = bigbtn.maximum(stepOrTrackBBtn.minimumSize());
  381.    bigbtn = bigbtn.maximum(stepOrTrackFBtn.minimumSize());
  382.    if (bigbtn.width() > bigbtn.height())
  383.       bigbtn.setHeight(bigbtn.width());
  384.    else bigbtn.setWidth(bigbtn.height());
  385.    playbtn.setMinimumSize( bigbtn );
  386.    stopbtn.setMinimumSize( bigbtn );
  387.    rewbtn.setMinimumSize( bigbtn );
  388.    ffbtn.setMinimumSize( bigbtn );
  389.    pausebtn.setMinimumSize( bigbtn );
  390.    stepOrTrackBBtn.setMinimumSize( bigbtn );
  391.    stepOrTrackFBtn.setMinimumSize( bigbtn );
  392.  
  393. //*****************************************************************************
  394. //  Build the controls canvas.  Columns 1 and 5 and rows 1 and 5 are margins  *
  395. //*****************************************************************************
  396.  
  397.    controls.addToCell(&playbtn,         3, 2, 1, 1);
  398.    controls.addToCell(&stopbtn,         3, 3, 1, 1);
  399.    controls.addToCell(&rewbtn,          2, 2, 1, 1);
  400.    controls.addToCell(&ffbtn,           4, 2, 1, 1);
  401.    controls.addToCell(&pausebtn,        3, 4, 1, 1);
  402.    controls.addToCell(&stepOrTrackBBtn, 2, 3, 1, 1);
  403.    controls.addToCell(&stepOrTrackFBtn, 4, 3, 1, 1);
  404.    controls.setColumnWidth(1, MARGIN, true);
  405.    controls.setColumnWidth(5, MARGIN, true);
  406.    controls.setRowHeight  (1, MARGIN, true);
  407.    controls.setRowHeight  (5, MARGIN, true);
  408.  
  409. //*****************************************************************************
  410. //  Calculate size for device buttons to keep them all the same.              *
  411. //*****************************************************************************
  412.  
  413.    ISize biggest;
  414.    biggest = biggest.maximum(videobtn.minimumSize());
  415.    biggest = biggest.maximum(midibtn.minimumSize());
  416.    biggest = biggest.maximum(cdbtn.minimumSize());
  417.    biggest = biggest.maximum(wavebtn.minimumSize());
  418.    videobtn.setMinimumSize( biggest );
  419.    midibtn.setMinimumSize( biggest );
  420.    cdbtn.setMinimumSize( biggest );
  421.    wavebtn.setMinimumSize( biggest );
  422.  
  423. //*****************************************************************************
  424. //  Build the devices canvas.  Columns 2, 4, and 6 are separators             *
  425. //*****************************************************************************
  426.  
  427.    devices.addToCell(&videobtn,     1, 1, 1, 1);
  428.    devices.addToCell(&midibtn,      3, 1, 1, 1);
  429.    devices.addToCell(&cdbtn,        5, 1, 1, 1);
  430.    devices.addToCell(&wavebtn,      7, 1, 1, 1);
  431.    devices.setColumnWidth( 1, IMultiCellCanvas::defaultCell().width(), true);
  432.    devices.setColumnWidth( 2, MARGIN);
  433.    devices.setColumnWidth( 3, IMultiCellCanvas::defaultCell().width(), true);
  434.    devices.setColumnWidth( 4, MARGIN);
  435.    devices.setColumnWidth( 5, IMultiCellCanvas::defaultCell().width(), true);
  436.    devices.setColumnWidth( 6, MARGIN);
  437.    devices.setColumnWidth( 7, IMultiCellCanvas::defaultCell().width(), true);
  438.  
  439. //*****************************************************************************
  440. //  Build the canvas containing the volume buttons                            *
  441. //*****************************************************************************
  442.  
  443.    volume.addToCell(&volupbtn,      1, 1, 1, 1);
  444.    volume.addToCell(&voldnbtn,      1, 2, 1, 1);
  445.  
  446. //*****************************************************************************
  447. //  Build the canvas containing the keypad and volume buttons canvases        *
  448. //*****************************************************************************
  449.  
  450.    volkey.addToCell(&pad,           1, 1, 1, 1);
  451.    volkey.addToCell(&volume,        3, 1, 1, 1);
  452.    volkey.setColumnWidth( 2, MARGIN, true);
  453.  
  454. //*****************************************************************************
  455. //  Set the background color for all canvases to black                        *
  456. //*****************************************************************************
  457.  
  458.    remoteCanvas.setBackgroundColor(IColor(IColor::black));
  459.    pad.setBackgroundColor(IColor(IColor::black));
  460.    devices.setBackgroundColor(IColor(IColor::black));
  461.    controls.setBackgroundColor(IColor(IColor::black));
  462.    volume.setBackgroundColor(IColor(IColor::black));
  463.    volkey.setBackgroundColor(IColor(IColor::black));
  464.  
  465. //*****************************************************************************
  466. //  Set up the readout for the player status line                             *
  467. //*****************************************************************************
  468.  
  469.    readout.setForegroundColor(IColor(0,160,0));
  470.    readout.setBackgroundColor(IColor(IColor::black));
  471.    readout.setText(IString("TRACK ") + IString(newTrackDigit1) +
  472.                    IString(newTrackDigit2) + IString(" MIN:SEC 00:00"));
  473.    ISize charSize = readout.characterSize();
  474.    readout.setMinimumSize(ISize( charSize.width()*30, charSize.height()));
  475.  
  476. //*****************************************************************************
  477. // Have the command handler handle events for this window                     *
  478. //*****************************************************************************
  479.  
  480.    handler  = new MainHandler();
  481.    handler->handleEventsFor(this);
  482.  
  483. //*****************************************************************************
  484. //  Latch the button for the default device.  Until play is                   *
  485. //  pressed, disable the stop and pause buttons. By doing this latching after *
  486. //  the command handler is added, we can let the command handler do all of the*
  487. //  setup(enable, disable, and latch) for the buttons.                        *
  488. //*****************************************************************************
  489.  
  490.    switch (playerDevice)
  491.    {
  492.      case VIDEOID:
  493.           videobtn.click();
  494.           videobtn.latch();
  495.           break;
  496.      case MIDIID:
  497.           midibtn.click();
  498.           midibtn.latch();
  499.           break;
  500.      case CDID:
  501.           cdbtn.click();
  502.           cdbtn.latch();
  503.           break;
  504.      case WAVEID:
  505.           wavebtn.click();
  506.           wavebtn.latch();
  507.           break;
  508.      default:
  509.           remoteCanvas.disable();
  510.           break;
  511.    } /* endswitch */
  512.  
  513. //*****************************************************************************
  514. //  When a device is opened, its volume is at maximum, so set the volume to   *
  515. //  something more reasonable.                                                *
  516. //  Define the notification observer for the players                          *
  517. //*****************************************************************************
  518.    observer = new MainObserver(*this);
  519.    if (cdPlayer)
  520.    {
  521.       cdPlayer->setVolume (50);
  522.       observer->handleNotificationsFor(*cdPlayer);
  523.    }
  524.    if (wavPlayer)
  525.    {
  526.       wavPlayer->setVolume(50);
  527.       observer->handleNotificationsFor(*wavPlayer);
  528.    }
  529.    if (digPlayer)
  530.    {
  531.       digPlayer->setVolume(50);
  532.       observer->handleNotificationsFor(*digPlayer);
  533.    }
  534.    if (midPlayer)
  535.    {
  536.       midPlayer->setVolume(50);
  537.       observer->handleNotificationsFor(*midPlayer);
  538.    }
  539.  
  540.  
  541. //*****************************************************************************
  542. //  Set up the fly over help handler                                          *
  543. //*****************************************************************************
  544.  
  545.    flyHelpHandler.handleEventsFor(this);
  546.  
  547. //*****************************************************************************
  548. //  Helvetica font for the main window, LED font for the status line          *
  549. //*****************************************************************************
  550.  
  551.    IFont("Helv",8).setWindowFont(this);
  552.    IFont("LED",10).setWindowFont(&readout);
  553.  
  554. //*****************************************************************************
  555. //  Size the window to it's minimum size, give it focus and show it           *
  556. //*****************************************************************************
  557.  
  558.    setIcon(WINDOWID);
  559.    setClient(&remoteCanvas);
  560.    ISize size = remoteCanvas.minimumSize();
  561.    moveSizeToClient(IRectangle(MARGIN,
  562.                                MARGIN,
  563.                                MARGIN+size.width(),
  564.                                MARGIN+size.height()));
  565.    setFocus();
  566.    show();
  567. }
  568.  
  569. //*******************************************************************************
  570. // MainHandler::MainHandler                                                      *
  571. //                                                                              *
  572. // Constructs the handler.                                                      *
  573. //*******************************************************************************
  574. MainHandler::MainHandler()
  575.            : MainHandler::Inherited()
  576. {}
  577.  
  578. //*******************************************************************************
  579. // MainHandler::command                                                          *
  580. //                                                                              *
  581. // Does the processing for the button presses.                                  *
  582. //*******************************************************************************
  583.  
  584. Boolean MainHandler::command( ICommandEvent& event )
  585. {
  586.   Boolean rv = false;
  587.   MainWindow* panel = (MainWindow*) (event.window());
  588.   switch ( event.commandId() )
  589.   {
  590.  
  591. //*****************************************************************************
  592. //  The power button is used to start a new device.  It loads the file to be  *
  593. //  played and sets up the device and buttons                                 *
  594. //*****************************************************************************
  595.  
  596.   case POWERID:
  597.        {
  598.           IFileDialog::Settings fdSettings;
  599.           fdSettings.setTitle("Load new device");
  600.           switch (panel->playerDevice)
  601.           {
  602. //*****************************************************************************
  603. //  Load a video file, using the file dialog.  Enable the control buttons     *
  604. //  and keypad, and set the status line text.  Start position tracking for    *
  605. //  timer.                                                                    *
  606. //*****************************************************************************
  607.  
  608.              case VIDEOID:
  609.                   {
  610.                   fdSettings.setFileName("*.avi");
  611.                   IFileDialog fd(panel->desktopWindow(),panel,fdSettings);
  612.                   if (fd.pressedOK())
  613.                   {
  614.                      panel->digPlayer->loadOnThread(fd.fileName());
  615.                      panel->digPlayer->startPositionTracking(IMMTime(3000));
  616.                      panel->stepOrTrackBBtn.enable();
  617.                      panel->stepOrTrackFBtn.enable();
  618.                      panel->readout.setText(IString("HR:MIN:SEC 00:00:00 "));
  619.                      if (!panel->playbtn.isEnabled())
  620.                      {
  621.                         panel->playbtn.enable();
  622.                         panel->stopbtn.enable();
  623.                         panel->rewbtn.enable();
  624.                         panel->ffbtn.enable();
  625.                         panel->pausebtn.enable();
  626.                         panel->pad.enable();
  627.                      }
  628.                   }
  629.                   }
  630.                   break;
  631.  
  632. //*****************************************************************************
  633. //  Load a midi file, using the file dialog.  Enable the control buttons      *
  634. //  and set the status line text.  Start position tracking for timer.         *
  635. //*****************************************************************************
  636.  
  637.              case MIDIID:
  638.                   {
  639.                   fdSettings.setFileName("*.mid");
  640.                   IFileDialog fd(panel->desktopWindow(),panel,fdSettings);
  641.                   if (fd.pressedOK())
  642.                   {
  643.                      panel->midPlayer->loadOnThread(fd.fileName());
  644.                      panel->midPlayer->startPositionTracking(IMMTime(3000));
  645.                      panel->readout.setText(IString("HR:MIN:SEC 00:00:00 "));
  646.                      if (!panel->playbtn.isEnabled())
  647.                      {
  648.                         panel->playbtn.enable();
  649.                         panel->stopbtn.enable();
  650.                         panel->rewbtn.enable();
  651.                         panel->ffbtn.enable();
  652.                         panel->pausebtn.enable();
  653.                      }
  654.                   }
  655.                   }
  656.                   break;
  657.  
  658. //*****************************************************************************
  659. //  Load a wave file using the file dialog. Enable the control buttons and    *
  660. //  set the status line text.  Start position tracking for timer.             *
  661. //*****************************************************************************
  662.  
  663.              case WAVEID:
  664.                   {
  665.                   fdSettings.setFileName("*.wav");
  666.                   IFileDialog fd(panel->desktopWindow(),panel,fdSettings);
  667.                   if (fd.pressedOK())
  668.                   {
  669.                      panel->wavPlayer->loadOnThread(fd.fileName());
  670.                      panel->wavPlayer->startPositionTracking(IMMTime(3000));
  671.                      panel->readout.setText(IString("HR:MIN:SEC 00:00:00 "));
  672.                      if (!panel->playbtn.isEnabled())
  673.                      {
  674.                         panel->playbtn.enable();
  675.                         panel->stopbtn.enable();
  676.                         panel->rewbtn.enable();
  677.                         panel->ffbtn.enable();
  678.                         panel->pausebtn.enable();
  679.                      }
  680.                   }
  681.                   }
  682.                   break;
  683.           }
  684.           panel->powerbtn.setText("Power");
  685.           rv=true;
  686.        }
  687.        break;
  688.  
  689. //*****************************************************************************
  690. //  If CD button is pressed, set up the bitmaps on the buttons and the        *
  691. //  status line.                                                              *
  692. //*****************************************************************************
  693.  
  694.   case CDID:
  695.        panel->player->stop();
  696.        panel->pausebtn.unlatch();
  697.        panel->playbtn.unlatch();
  698.        panel->stopbtn.disable();
  699.        panel->pausebtn.disable();
  700.        panel->player=panel->cdPlayer;
  701.        if (panel->playerDevice!=CDID)
  702.        {
  703.          panel->stepOrTrackBBtn.setBitmaps(IAnimatedButton::trackReverse);
  704.          panel->stepOrTrackFBtn.setBitmaps(IAnimatedButton::trackAdvance);
  705.          panel->stepOrTrackBBtn.enable();
  706.          panel->stepOrTrackFBtn.enable();
  707.          panel->readout.setText(IString("TRACK ") + IString(panel->newTrackDigit1) +
  708.                    IString(panel->newTrackDigit2) + IString(" MIN:SEC 00:00"));
  709.          panel->flyHelpHandler.setFlyTextStringTableOffset(0);
  710.        }
  711.        panel->playerDevice=CDID;
  712.        if (!panel->playbtn.isEnabled())
  713.        {
  714.           panel->playbtn.enable();
  715.           panel->stopbtn.enable();
  716.           panel->rewbtn.enable();
  717.           panel->ffbtn.enable();
  718.           panel->pausebtn.enable();
  719.        }
  720.        panel->pad.enable();
  721.        rv=true;
  722.        break;
  723.  
  724. //*****************************************************************************
  725. // If video is pressed, disable the buttons until a file is loaded            *
  726. //*****************************************************************************
  727.  
  728.   case VIDEOID:
  729.        panel->player->stop();
  730.        panel->player=panel->digPlayer;
  731.        if (panel->playerDevice!=VIDEOID)
  732.        {
  733.           panel->stepOrTrackBBtn.setBitmaps(IAnimatedButton::stepBackward);
  734.           panel->stepOrTrackFBtn.setBitmaps(IAnimatedButton::stepForward );
  735.           panel->flyHelpHandler.setFlyTextStringTableOffset(VIDEO);
  736.        }
  737.        if (panel->playbtn.isLatched())
  738.           panel->playbtn.unlatch();
  739.        panel->playerDevice=VIDEOID;
  740.        panel->pausebtn.unlatch();
  741.        panel->playbtn.disable();
  742.        panel->stopbtn.disable();
  743.        panel->rewbtn.disable();
  744.        panel->ffbtn.disable();
  745.        panel->pausebtn.disable();
  746.        panel->stepOrTrackBBtn.disable();
  747.        panel->stepOrTrackFBtn.disable();
  748.        panel->pad.disable();
  749.        panel->powerbtn.setText("Load file" );
  750.        rv=true;
  751.        break;
  752.  
  753. //*****************************************************************************
  754. //  If midi device is selected, disable buttons until a file is loaded        *
  755. //*****************************************************************************
  756.  
  757.   case MIDIID:
  758.        panel->player->stop();
  759.        panel->player=panel->midPlayer;
  760.        panel->playerDevice=MIDIID;
  761.        if (panel->playbtn.isLatched())
  762.           panel->playbtn.unlatch();
  763.        panel->stepOrTrackBBtn.disable();
  764.        panel->stepOrTrackFBtn.disable();
  765.        panel->playbtn.disable();
  766.        panel->stopbtn.disable();
  767.        panel->rewbtn.disable();
  768.        panel->ffbtn.disable();
  769.        panel->pausebtn.unlatch();
  770.        panel->pausebtn.disable();
  771.        panel->pad.disable();
  772.        panel->powerbtn.setText("Load file" );
  773.        panel->flyHelpHandler.setFlyTextStringTableOffset(MIDI);
  774.        rv=true;
  775.        break;
  776.  
  777. //*****************************************************************************
  778. //  If wave device is selected, disable buttons until a file is loaded        *
  779. //*****************************************************************************
  780.  
  781.   case WAVEID:
  782.        panel->player->stop();
  783.        panel->player=panel->wavPlayer;
  784.        panel->playerDevice=WAVEID;
  785.        if (panel->playbtn.isLatched())
  786.           panel->playbtn.unlatch();
  787.        panel->stepOrTrackBBtn.disable();
  788.        panel->stepOrTrackFBtn.disable();
  789.        panel->playbtn.disable();
  790.        panel->stopbtn.disable();
  791.        panel->rewbtn.disable();
  792.        panel->ffbtn.disable();
  793.        panel->pausebtn.unlatch();
  794.        panel->pausebtn.disable();
  795.        panel->pad.disable();
  796.        panel->powerbtn.setText("Load file" );
  797.        panel->flyHelpHandler.setFlyTextStringTableOffset(WAVE);
  798.        rv=true;
  799.        break;
  800.  
  801. //*****************************************************************************
  802. // Step backward button.  For CD, back up to previous track                   *
  803. //*****************************************************************************
  804.  
  805.   case STEPTRACKBID:
  806.        if (panel->playerDevice==CDID)
  807.           panel->cdPlayer->trackBackward();
  808.        else
  809.        {
  810.           IMMTime::Format format = panel->player->timeFormat();
  811.           panel->player->setTimeFormat(IMMTime::mmTime);
  812.           if (panel->player->position())
  813.           {
  814.              panel->player->setTimeFormat(format);
  815.              panel->player->stepFrame(1,false);
  816.           }
  817.           else
  818.              panel->player->setTimeFormat(format);
  819.        }
  820.        break;
  821.  
  822. //*****************************************************************************
  823. //  Step forward button.  For CD, advance to next track                       *
  824. //*****************************************************************************
  825.  
  826.   case STEPTRACKFID:
  827.        if (panel->playerDevice==CDID)
  828.           panel->cdPlayer->trackForward();
  829.        else
  830.        {
  831.           IMMTime::Format format = panel->player->timeFormat();
  832.           panel->player->setTimeFormat(IMMTime::mmTime);
  833.           if (panel->player->position() < panel->player->length())
  834.           {
  835.              panel->player->setTimeFormat(format);
  836.              panel->player->stepFrame();
  837.           }
  838.           else
  839.              panel->player->setTimeFormat(format);
  840.        }
  841.        break;
  842.  
  843. //*****************************************************************************
  844. // If play is pressed, first check to see if already playing.  If not, enable *
  845. // pause and stop buttons and play.  If it is, relatch the play button        *
  846. //*****************************************************************************
  847.  
  848.   case PLAYID:
  849.        if (panel->player->mode() != IMMDevice::playing)
  850.        {
  851.           panel->stopbtn.enable();
  852.           panel->pausebtn.enable();
  853.           panel->pausebtn.unlatch();
  854.           panel->player->play();
  855.         }
  856.        else panel->playbtn.latch();
  857.        rv=true;
  858.        break;
  859.  
  860. //*****************************************************************************
  861. //  If Stop is pressed, stop the player and reset to the beginning.  Disable  *
  862. //  stop and pause buttons                                                    *
  863. //*****************************************************************************
  864.  
  865.   case STOPID:
  866.        panel->player->stop();
  867.        panel->player->seekToStart();
  868.        panel->pausebtn.unlatch();
  869.        panel->playbtn.unlatch();
  870.        panel->stopbtn.disable();
  871.        panel->pausebtn.disable();
  872.        rv=true;
  873.        break;
  874.  
  875. //*****************************************************************************
  876. //  For rewind, reset to beginning of file, unlatch the play button and       *
  877. //  diable stop and pause                                                     *
  878. //*****************************************************************************
  879.  
  880.   case REWID:
  881.        panel->player->seekToStart();
  882.        panel->playbtn.unlatch();
  883.        panel->pausebtn.unlatch();
  884.        panel->stopbtn.disable();
  885.        panel->pausebtn.disable();
  886.        rv=true;
  887.        break;
  888.  
  889. //*****************************************************************************
  890. //  For fast forward, advance to end of file                                  *
  891. //*****************************************************************************
  892.  
  893.   case FFID:
  894.        panel->player->seekToEnd();
  895.        panel->pausebtn.unlatch();
  896.        panel->playbtn.unlatch();
  897.        panel->stopbtn.disable();
  898.        panel->pausebtn.disable();
  899.        rv=true;
  900.        break;
  901.  
  902. //*****************************************************************************
  903. //  If pause, check pause state.  If paused, resume play, otherwise pause     *
  904. //*****************************************************************************
  905.  
  906.     case PAUSEID:
  907.        if (panel->player->mode() == IMMDevice::paused )
  908.        {
  909.           panel->player->play();
  910.           panel->playbtn.latch();
  911.        }
  912.        else panel->player->pause();
  913.        rv=true;
  914.        break;
  915.  
  916. //*****************************************************************************
  917. //  Turn down volume 5%                                                       *
  918. //*****************************************************************************
  919.  
  920.   case VOLDNID:
  921.        panel->player->setVolume(panel->player->volume()-5);
  922.        rv=true;
  923.        break;
  924.  
  925. //*****************************************************************************
  926. //  Turn up volume 5%                                                         *
  927. //*****************************************************************************
  928.  
  929.   case VOLUPID:
  930.        panel->player->setVolume(panel->player->volume()+5);
  931.        rv=true;
  932.        break;
  933.  
  934. //*****************************************************************************
  935. // For one on keypad, enter digit 1 for CD, or play slow motion for video     *
  936. //*****************************************************************************
  937.  
  938.   case ONEID:
  939.        switch (panel->playerDevice){
  940.        case CDID:
  941.           panel->newDigit(1);
  942.           rv=true;
  943.           break;
  944.        case VIDEOID:
  945.           panel->digPlayer->playSlow();
  946.           rv=true;
  947.           break;
  948.        }
  949.        break;
  950.  
  951. //*****************************************************************************
  952. //  For two on keypad, enter digit 2 for CD, or play fast speed for video     *
  953. //*****************************************************************************
  954.  
  955.   case TWOID:
  956.        switch (panel->playerDevice) {
  957.        case CDID:
  958.           panel->newDigit(2);
  959.           rv=true;
  960.           break;
  961.        case VIDEOID:
  962.           panel->digPlayer->playFast();
  963.           rv=true;
  964.           break;
  965.        }
  966.        break;
  967.  
  968. //*****************************************************************************
  969. //  For three on keypad, enter digit 3 for CD, play in scan mode for video    *
  970. //*****************************************************************************
  971.  
  972.   case THREEID:
  973.        switch (panel->playerDevice){
  974.        case CDID:
  975.           panel->newDigit(3);
  976.           rv=true;
  977.           break;
  978.        case VIDEOID:
  979.           panel->digPlayer->playScan();
  980.           rv=true;
  981.           break;
  982.        }
  983.        break;
  984.  
  985. //*****************************************************************************
  986. //  For digits 4-9, enter digit for CD track                                  *
  987. //*****************************************************************************
  988.  
  989.   case FOURID:
  990.        if (panel->playerDevice==CDID)
  991.           panel->newDigit(4);
  992.        rv=true;
  993.        break;
  994.   case FIVEID:
  995.        if (panel->playerDevice==CDID)
  996.           panel->newDigit(5);
  997.        rv=true;
  998.        break;
  999.   case SIXID:
  1000.        if (panel->playerDevice==CDID)
  1001.           panel->newDigit(6);
  1002.        rv=true;
  1003.        break;
  1004.   case SEVENID:
  1005.        if (panel->playerDevice==CDID)
  1006.           panel->newDigit(7);
  1007.        rv=true;
  1008.        break;
  1009.   case EIGHTID:
  1010.        if (panel->playerDevice==CDID)
  1011.           panel->newDigit(8);
  1012.        rv=true;
  1013.        break;
  1014.   case NINEID:
  1015.        if (panel->playerDevice==CDID)
  1016.           panel->newDigit(9);
  1017.        rv=true;
  1018.        break;
  1019.  
  1020. //*****************************************************************************
  1021. //  For zero on keypad, enter 0 for CD, or resume normal play for video       *
  1022. //*****************************************************************************
  1023.  
  1024.   case ZEROID:
  1025.        switch (panel->playerDevice) {
  1026.        case CDID:
  1027.           if (panel->playerDevice==CDID && !(panel->newTrackDigit1==0 && panel->newTrackDigit2==-1))
  1028.           panel->newDigit(0);
  1029.           rv=true;
  1030.           break;
  1031.        case VIDEOID:
  1032.           panel->digPlayer->play();
  1033.           rv=true;
  1034.           break;
  1035.        }
  1036.        break;
  1037.   }
  1038.   return rv;
  1039. }
  1040.  
  1041. //*******************************************************************************
  1042. // MainObserver::MainObserver                                                     *
  1043. //                                                                              *
  1044. // Constructs the observer.                                                     *
  1045. //*******************************************************************************
  1046. MainObserver::MainObserver(MainWindow& mainPanel)
  1047.             : MainObserver::Inherited(),
  1048.               panel(mainPanel)
  1049. {}
  1050.  
  1051. //*****************************************************************************
  1052. //  Set up observer to track time and update status line for CD player        *
  1053. //*****************************************************************************
  1054.  
  1055. MainObserver& MainObserver::dispatchNotificationEvent(const INotificationEvent& event)
  1056. {
  1057.    if (event.notificationId() == IMMAudioCD::positionTimerId)
  1058.    {
  1059.       IMMTrackMinSecFrameTime* time = (IMMTrackMinSecFrameTime*)(event.eventData().asUnsignedLong());
  1060.       panel.readout.setText(IString("TRACK ") +
  1061.                       IString(time->track()).rightJustify(2,'0') +
  1062.                       IString(" MIN:SEC ") +
  1063.                       IString(time->minutes()).rightJustify(2,'0') +
  1064.                       IString(":") +
  1065.                       IString(time->seconds()).rightJustify(2,'0'));
  1066.    }
  1067.    else if (event.notificationId() == IMMAudioCD::trackStartedId)
  1068.    {
  1069.       IMMTrackMinSecFrameTime* time = (IMMTrackMinSecFrameTime*)(event.eventData().asUnsignedLong());
  1070.       panel.readout.setText(IString("TRACK ") +
  1071.                       IString(time->track()).rightJustify(2,'0') +
  1072.                       IString(" MIN:SEC ") +
  1073.                       IString(time->minutes()).rightJustify(2,'0') +
  1074.                       IString(":") +
  1075.                       IString(time->seconds()).rightJustify(2,'0'));
  1076.       if ((panel.cdPlayer->mode()==IMMDevice::playing) &&
  1077.           !(panel.playbtn.isLatched()))
  1078.          panel.playbtn.latch();
  1079.    } /* endif */
  1080.    else if (event.notificationId() == IMMDevice::positionChangeId)
  1081.    {
  1082.       IMMPositionChangeEvent* positionEvent = (IMMPositionChangeEvent*)(event.eventData().asUnsignedLong());
  1083.  
  1084.       IMMTime timer(positionEvent->position());
  1085.       panel.readout.setText(IString("HR:MIN:SEC ") +
  1086.                       IString(timer.hours()).rightJustify(2,'0') +
  1087.                       ":" +
  1088.                       IString(timer.minutes()).rightJustify(2,'0') +
  1089.                       ":" +
  1090.                       IString(timer.seconds()).rightJustify(2,'0'));
  1091.    }
  1092.    else if (event.notificationId() == IMMDevice::commandNotifyId)
  1093.    {
  1094.       IMMNotifyEvent* notifyEvent = (IMMNotifyEvent*)(event.eventData().asUnsignedLong());
  1095.       if (notifyEvent->command() == IMMNotifyEvent::play)
  1096.       {
  1097.          panel.playbtn.unlatch();
  1098.       }
  1099.    }
  1100.  
  1101.    return *this;
  1102. }
  1103. //*****************************************************************************
  1104. //  newDigit routine manages digital input for CD player.                     *
  1105. //*****************************************************************************
  1106.  
  1107. MainWindow& MainWindow::newDigit(int digit)
  1108. {
  1109.   if (newTrackDigit2 ==-1)
  1110.   {
  1111.      newTrackDigit2 = digit;
  1112.      readout.setText(IString("TRACK ") + IString(newTrackDigit1) +
  1113.                      IString(newTrackDigit2) + IString(" MIN:SEC 00:00"));
  1114.      if (newTrackDigit1*10 + newTrackDigit2 > cdPlayer->numberOfTracks())
  1115.      {
  1116.         IMessageBox msgBox(this);
  1117.         msgBox.show(IString("Invalid track number, this cd only has ") + IString(cdPlayer->numberOfTracks()) + IString(" tracks."),
  1118.                     IMessageBox::okButton  |
  1119.                     IMessageBox::errorIcon |
  1120.                     IMessageBox::moveable );
  1121.      } else {
  1122.         cdPlayer->goToEntry(newTrackDigit1*10 + newTrackDigit2);
  1123.      } /* endif */
  1124.   } else {
  1125.      newTrackDigit1 = digit;
  1126.      newTrackDigit2 = -1;
  1127.      readout.setText(IString("TRACK ") + IString(newTrackDigit1) +
  1128.                      IString("_ MIN:SEC 00:00"));
  1129.   }
  1130.   return *this;
  1131. }
  1132.