home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pwrgu2.zip / POWERGU2.EXE / CANVAS / VPORTLOG / VPORTLOG.CPP < prev    next >
Text File  |  1995-07-25  |  10KB  |  278 lines

  1. //************************************************************
  2. // Canvas - IViewPort with Logically-sized View Window.
  3. //
  4. // Copyright (C) 1994, Law, Leong, Love, Olson, Tsuji.
  5. // All Rights Reserved.
  6. //************************************************************
  7. #define INCL_WINWINDOWMGR   // WinFillRect
  8. #include <os2.h>
  9.  
  10. #include <icolor.hpp>
  11. #include <ifont.hpp>
  12. #include <iframe.hpp>
  13. #include <iapp.hpp>
  14. #include <ipoint.hpp>
  15. #include <iscroll.hpp>
  16. #include <istring.hpp>
  17. #include <icconst.h>
  18.  
  19. #include "vportlog.hpp"
  20.  
  21. #define NUMBER_COLORS  8
  22. static IColor::Color colorEnums[ NUMBER_COLORS ] =
  23.   { IColor::blue, IColor::darkGreen, IColor::red,
  24.     IColor::darkCyan, IColor::pink, IColor::darkRed,
  25.     IColor::brown, IColor::black };
  26.  
  27. //=================== LogicalSizeViewPort =====================
  28.  
  29. LogicalSizeViewPort :: LogicalSizeViewPort
  30.                         ( unsigned long windowId,
  31.                           IWindow* parentAndOwner,
  32.                           unsigned long scale,
  33.                           Boolean  specialScrolling )
  34.   : IViewPort( windowId, parentAndOwner,
  35.                parentAndOwner, IRectangle(),
  36.                IViewPort::classDefaultStyle
  37.                  | IViewPort::noViewWindowFill ),
  38.     clViewWindow( windowId, this, this ),
  39.     clViewPaintHdr( this ),
  40.     clVerticalLogicalRatio( 1 ),
  41.     clCustomScrolling( specialScrolling )
  42. {
  43.   // Physically size the view window to the size of the
  44.   // screen, and leave it positioned at (0, 0).
  45.   ISize desktopSize = IWindow::desktopWindow()->size();
  46.   this->clViewWindow.sizeTo(desktopSize);
  47.  
  48.   // Logically size the view window using the scaling factor.
  49.   ISize logicalSize( 0x4000 * scale, 0x8000 * scale );
  50.   if (scale == 0)
  51.   {                     // <32K logical sizes.
  52.      logicalSize = ISize( 0x4000, 0x7FFF );
  53.   }
  54.   (*this).setViewWindowSize( logicalSize );
  55.  
  56.   this->clViewPaintHdr.handleEventsFor( &clViewWindow );
  57. #if PRE_CTM0006
  58.   this->clFocusKludgeHdr.handleEventsFor( &clViewWindow );
  59. #endif
  60.  
  61.   if (clCustomScrolling)
  62.   {                     // Modify scroll bars if necessary.
  63.      IScrollBar* horz = this->horizontalScrollBar();
  64.      horz->setMinScrollIncrement
  65.              ( horz->minScrollIncrement() * 4 );
  66.      IScrollBar* vert = this->verticalScrollBar();
  67.      vert->setMinScrollIncrement
  68.              ( vert->minScrollIncrement() * 4 );
  69.   }
  70. }  // LogicalSizeViewPort ctor
  71.  
  72. #if PRE_CTM0005
  73. LogicalSizeViewPort&
  74.   LogicalSizeViewPort :: scrollViewVerticallyTo
  75.                            ( unsigned long topOffset )
  76. {
  77.   if (this->viewWindowSize().height() >
  78.         this->viewWindowDrawRectangle().height())
  79.   {      // It's ok to scroll (application may have called us).
  80.      // Adjust scroll amount if too large.
  81.      unsigned long new0basedOffset =
  82.                       this->viewWindowSize().height();
  83.      if (topOffset < new0basedOffset)
  84.      {
  85.         new0basedOffset = topOffset;
  86.      }
  87.  
  88.      // Set new top left point.
  89.      unsigned long topPos =
  90.                    this->viewWindowSize().height() - topOffset;
  91.      this->setTopLeftViewPoint( (*this).topLeftViewPoint()
  92.                                        .setY(topPos) );
  93.  
  94.      // Move the scroll box.
  95. //   this->verticalScrollBar()
  96. //       ->moveScrollBoxTo(new0basedOffset + 1);
  97.   }
  98.  
  99.   refresh();  // Force a repaint.
  100.  
  101.   return *this;
  102. }  // LogicalSizeViewPort::scrollViewVerticallyTo
  103. #endif
  104.  
  105. LogicalSizeViewPort& LogicalSizeViewPort :: layout ( )
  106. {
  107.   IViewPort::layout();
  108.  
  109.   if (clCustomScrolling)
  110.   {                     // Modify scroll bars if necessary.
  111.      IScrollBar* horz = this->horizontalScrollBar();
  112.      horz->setPageScrollIncrement
  113.              ( horz->pageScrollIncrement() / 2 );
  114.      IScrollBar* vert = this->verticalScrollBar();
  115.      vert->setPageScrollIncrement
  116.              ( vert->pageScrollIncrement() / 2 );
  117.   }
  118.  
  119.   return *this;
  120. }  // LogicalSizeViewPort::layout
  121.  
  122. LogicalSizeViewPort& LogicalSizeViewPort :: positionViewWindow
  123.                             ( const IWindowHandle& viewWindow,
  124.                               const IRectangle& viewRectangle )
  125. {
  126. #if 0
  127.   // Only honor horizontal changes to keep the view window
  128.   // visible.
  129.   IPoint viewPos = this->clViewWindow.position()
  130.                        .setX(0 - this->topLeftViewPoint().x());
  131.   this->clViewWindow.moveTo(viewPos);
  132. #endif
  133.  
  134.   // Force repaint to allow painting updates.
  135.   this->clViewWindow.refresh();
  136.  
  137.   return *this;
  138. }  // LogicalSizeViewPort::positionViewWindow
  139.  
  140. //============ LogicalSizeViewPort::ViewPaintHdr ==============
  141.  
  142. Boolean LogicalSizeViewPort::ViewPaintHdr :: paintWindow
  143.                                          ( IPaintEvent& event )
  144. {
  145.   ICanvas* canvas = (ICanvas*)event.window();
  146.  
  147.   // Compensate for effects of CS_PARENTCLIP.
  148.   IRectangle rectWindow = canvas->rect().moveTo( IPoint() );
  149.   IRectangle rectInvalid = event.rect() & rectWindow;
  150.  
  151.   if (rectInvalid.size() > ISize())
  152.   {                     // Something needs painting.
  153.      // Initialize drawing variables.
  154.      unsigned long blockWidth  = 0x0100,  // 256
  155.                    blockHeight = 0x0080;  // 128
  156.      IRectangle drawRect =
  157.                   clViewPort->viewWindowDrawRectangle();
  158.      IColor fgColor( IColor::yellow );
  159.  
  160.      // Width-dependent painting: Paint colors and offsets.
  161.      // Figure out where we are.
  162.      long x = drawRect.left();
  163.      unsigned long xIndex = x / blockWidth;
  164.  
  165.      while (x < drawRect.right())
  166.      {                  // Paint visible background.
  167.        // Paint a color block.
  168.        IColor bgColor( colorEnums[ xIndex % NUMBER_COLORS ] );
  169.        unsigned long x2 = (xIndex + 1) * blockWidth;
  170.        Boolean rightEdge = true;
  171.        if (x2 > drawRect.right())
  172.        {                // For last visible block.
  173.           x2 = drawRect.right() + 1;
  174.           rightEdge = false;
  175.        }
  176.        x2--;
  177. //     event.clearBackground(rectInvalid, bgColor);
  178.        IRectangle paintRect( IPoint( x, rectInvalid.bottom() ),
  179.                              IPoint( x2, rectInvalid.top() ));
  180.        paintRect.moveBy( IPoint( 0 - drawRect.left(), 0 ));
  181.        RECTL rcl = paintRect.asRECTL();
  182.        WinFillRect( event.presSpaceHandle(),
  183.                     &rcl, bgColor.index() );
  184.  
  185.        if (rightEdge)
  186.        {                // Right edge is visible.
  187.           // Draw thin divider at right edge of color block.
  188.           IRectangle divider( IPoint( x2,
  189.                                       rectInvalid.bottom() ),
  190.                               IPoint( x2 + 1,
  191.                                       rectInvalid.top() ));
  192.           divider.moveBy( IPoint(0 - drawRect.left(), 0) );
  193.           rcl = divider.asRECTL();
  194.           WinFillRect( event.presSpaceHandle(),
  195.                        &rcl, fgColor.index() );
  196.        }
  197.  
  198.        // Write offset at left edge of color block.
  199.        if (!(x % blockWidth))
  200.        {                // Left edge of color block is showing.
  201.           IString offset( xIndex * blockWidth );
  202.           event.drawText( offset.d2x(),
  203.                           IPoint( x - drawRect.left(), 0 ),
  204.                           fgColor );
  205.        }
  206.  
  207.        x = x2 + 1;
  208.        xIndex++;
  209.      }
  210.  
  211.      // Height-dependent painting: Draw offsets of logical rows.
  212.      // Figure out where we are.
  213.      unsigned long fontHeight =
  214.                      IFont( event.window() ).maxCharHeight();
  215.      long y = clViewPort->viewWindowSize().height() -
  216.                                           drawRect.top();
  217.      long viewBottom = y + drawRect.height();
  218.      unsigned long yIndex = y / blockHeight;
  219.           // Bottom of a row, relative to logical view window.
  220.  
  221.      while (y < viewBottom)
  222.      {                  // Draw visible rows.
  223.        unsigned long y2 = (yIndex + 1) * blockHeight;
  224.        if (y2 - fontHeight < viewBottom)
  225.        {                // This row number is visible.
  226.           IString lineNumber( IString(y2).d2x() );
  227.           event.drawText( lineNumber,
  228.                           IPoint( 20, viewBottom - y2 ),
  229.                           fgColor );
  230.        }
  231.  
  232.        y = y2 + 1;
  233.        yIndex++;
  234.      }
  235.  
  236.   }  // End something needs painting.
  237.  
  238.   return true;          // All painting performed
  239. }  // LogicalSizeViewPort::ViewPaintHdr::paintWindow()
  240.  
  241. //========================== Main =============================
  242.  
  243. void main( int argc, char *argv[] )
  244. {
  245.   long scale = 1;
  246.   Boolean specialScrolling = false;
  247.  
  248.   // This .exe take two optional command line arguments.
  249.   // The first is a "scale" value, which specifies the
  250.   // multiples of 0x4000 for width and 0x8000 for height that
  251.   // the view port should logically size its view window.  A
  252.   // value of zero means to use (0x4000, 0x7FFF).
  253.   // A second argument means that the default scroll amounts
  254.   // should not be used.
  255.   if (argc > 1)
  256.   {                     // First argument is scale.
  257.      scale = IString( argv[1] ).asInt();
  258.      if (scale < 0)
  259.      {                  // Valid values are 0 or greater.
  260.         scale = 1;      // 1 is default.
  261.      }
  262.      if (argc > 2)
  263.      {                  // Second command line argument.
  264.         specialScrolling = true;
  265.      }
  266.   }
  267.  
  268.   // Create the frame window and its client view port.
  269.   IFrameWindow frame
  270.                ( "View port with logically-sized view window" );
  271.   LogicalSizeViewPort vport( IC_FRAME_CLIENT_ID, &frame,
  272.                              scale, specialScrolling );
  273.  
  274.   // Show it all now.
  275.   frame.setFocus().show();
  276.   IApplication::current().run();
  277. }  // main()
  278.