home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C ++ / Applications / Venus 3.5 / FlightWindow.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-10  |  9.4 KB  |  317 lines  |  [TEXT/CWIE]

  1. /*
  2.  ***********************************************************************
  3.  *
  4.  *                    Implementations of the FlightWindow
  5.  * a live (animated) window that displays the FlightView and tells it to move on
  6.  * 
  7.  ***********************************************************************
  8.  */
  9.  
  10. #include "FlightWindow.h"
  11. #include <Palettes.h>
  12. #include "EventHandlers.h"
  13.  
  14. FlightWindow::FlightWindow(const ElevationMap& image_map, const int wind_id)
  15.     : ScreenWindow(wind_id),
  16.       viewer(image_map),
  17.       proj_parameters(ScreenWindow::q_bounds()),    // Order! proj_parameters is used at view_buffer init...
  18.       view_buffer(image_map,viewer,proj_parameters),
  19.       is_flying(FALSE),
  20.       was_QD_optimized(FALSE)
  21. {}
  22.  
  23. FlightWindow::FlightWindow(const ElevationMap& image_map, const int wind_id,
  24.                            ScreenRect buffer_rect)
  25.     : ScreenWindow(wind_id),
  26.       viewer(image_map),
  27.       proj_parameters(buffer_rect),
  28.       view_buffer(image_map,viewer,proj_parameters),
  29.       is_flying(FALSE),
  30.       was_QD_optimized(FALSE)
  31. {}
  32.  
  33.                         // Post- (but still is a) constructor
  34. void FlightWindow::init(void)
  35. {
  36.   setup_color_env(view_buffer);
  37.   view_buffer.project();
  38.   ScreenWindow::init();
  39. }
  40.  
  41.                     // Negotiate color environment for displaying clouds...
  42. void FlightWindow::setup_color_env(OffScreenBuffer& offscreen_buffer)
  43. {
  44.   set_private_palette(offscreen_buffer.q_clut());
  45.   was_QD_optimized = offscreen_buffer.optimize_color_worlds(GetGDevice());
  46. }
  47.  
  48.                             // How many marks were made per second
  49. int StopWatch::marks_per_sec(void) const
  50. {
  51.   const int time_elapsed = (time_stopped == 0 ? TickCount() : time_stopped) 
  52.                              - time_started;    // in Ticks
  53.   return time_elapsed == 0 ? 0 : (60*mark_counter)/time_elapsed;
  54. }
  55.  
  56.                     // Window functions
  57.                     
  58. void FlightWindow::draw(void)            // It is this function that really draws smth
  59.   //view_buffer.draw(q_bounds());
  60.   {                                        // This is a little bit faster method, works only
  61.                                           // if we blit to the whole window;
  62.                                           // view_buffer.draw(q_bounds()); works even if
  63.                                           // we blit to a user-item control within a dialog
  64.                                           // window
  65.     PixMapHandle pixmap = view_buffer.get_pixmap();
  66.     assert( LockPixels(pixmap) );
  67.     Rect& pixmap_rect = (**pixmap).bounds;
  68.     CopyBits((const BitMap *)*pixmap, &qd.thePort->portBits, &pixmap_rect, 
  69.           q_bounds(), /*ditherCopy*/ srcCopy, nil);
  70.     UnlockPixels(pixmap);
  71.   }
  72.   animate();
  73. }
  74.  
  75.  
  76. Boolean FlightWindow::handle_mouse_down(const EventRecord& the_event, WindowPtr where_window, short window_part)
  77. {
  78.   switch(window_part)
  79.   {
  80.     case inContent:
  81.          return track_mouse(the_event.where);
  82.   
  83.     case inZoomOut:
  84.           return EventHandler::put_back_my_event(EventHandler::zoom_requested),
  85.                     false;
  86.                     
  87.     case inGrow:
  88.            {
  89.            // SetPort(twindow);
  90.            Rect growth_limits = qd.screenBits.bounds;
  91.            growth_limits.left = 64;        // minimal allowed window size
  92.            growth_limits.top = 64;
  93.            DrawGrowIcon (where_window);
  94.            const long new_win_dims =
  95.                 ::GrowWindow(where_window, the_event.where, &growth_limits);
  96.            if( new_win_dims == 0 )    // resize was canceled: merely redraw the window
  97.                return refresh(), true;
  98.  
  99.            Point topleft = {0,0};    // Current window location
  100.            LocalToGlobal(&topleft);        // .. in global coordinates
  101.            EventHandler::put_back_my_event(EventHandler::resize_requested,
  102.                                            new_win_dims,topleft);
  103.            return false;
  104.            }
  105.  
  106.   default:
  107.          break;
  108.   }
  109.   return ScreenWindow::handle_mouse_down(the_event,where_window,window_part);
  110. }
  111.  
  112. Boolean FlightWindow::handle_null_event(const long event_time)
  113. {
  114.   if( !is_flying )
  115.     start_flight();
  116.   return TRUE;
  117. }
  118.  
  119.                             // Handles key_down & auto_key events
  120. Boolean FlightWindow::handle_key_down(const EventRecord& the_event)
  121. {
  122.   //_error("char pressed %ld",the_event.message & charCodeMask);
  123.   stop_flight();                        // The user wanted to take an active role
  124.   switch(the_event.message & charCodeMask)
  125.   {
  126.     case 11:                // PgUp
  127.          if( the_event.modifiers & optionKey )
  128.            proj_parameters.climb(1);
  129.          else
  130.            proj_parameters.move_horizon(4);
  131.          break;
  132.              
  133.     case 12:                // PgDn
  134.          if( the_event.modifiers & optionKey )
  135.            proj_parameters.climb(-1);
  136.          else
  137.            proj_parameters.move_horizon(-4);
  138.          break;
  139.         
  140.     case 30:                // Arrow Up
  141.          viewer.move_ver(2);
  142.          break;
  143.              
  144.     case 31:                // Arrow Down
  145.          viewer.move_ver(-2);
  146.          break;
  147.  
  148.     case 28:                // Arrow Left
  149.          viewer.move_hor(-4);
  150.          break;
  151.  
  152.     case 29:                // Arrow Right
  153.          viewer.move_hor(4);
  154.          break;
  155.  
  156.     case 'z':
  157.          proj_parameters.zoom(-1);
  158.          break;
  159.      
  160.     case 'Z':
  161.          proj_parameters.zoom(1);
  162.          break;
  163.          
  164.     case 'D':
  165.          view_buffer.dump();
  166.          message("\n\nAnimation speed %d frames/sec\n",frame_counter.marks_per_sec());
  167.          message("\nQuickDraw drawing %s optimized\n",
  168.                   was_QD_optimized ? "WAS" : "was NOT");
  169.          return FALSE;
  170.  
  171.     default:                // Get the parent to handle the other keys: 
  172.          return ScreenWindow::handle_key_down(the_event);    // he'll probably kill the application
  173.   }
  174.   view_buffer.project();
  175.   refresh();
  176.   return TRUE;
  177. }
  178.  
  179.                                 // Track the mouse clicked in content
  180.                                 // and move the plane as the mouse (still down) moves
  181. Boolean  FlightWindow::track_mouse(Point mouse_down_pt)
  182. {
  183.   Point prev_point = mouse_down_pt;        // In _global_ coordinates!
  184.   stop_flight();
  185.   
  186.   EventRecord new_event;
  187.   while( !OSEventAvail(mUpMask,&new_event) )
  188.   {
  189.     const int delta_x = prev_point.h - new_event.where.h;
  190.     const int delta_y = prev_point.v - new_event.where.v;
  191.     prev_point = new_event.where;
  192.     
  193.       if( abs(delta_x) < 2 && abs(delta_y) < 2 )
  194.         continue;                            // Ignore mouse dribble....
  195.         
  196.       viewer.move_ver(delta_y);
  197.       viewer.move_hor(delta_x);
  198.     view_buffer.project();
  199.     refresh();
  200.     draw_immediately();
  201.   }
  202.   return TRUE;
  203. }
  204.  
  205.                             // Dealing with viewer position (and animating it)
  206. FlightWindow::ViewerAnim::ViewerAnim(const ScreenRect& rect)
  207.   : ViewerPosition(rect.q_width()/2,0,0,g_unit),
  208.     sup_xe(rect.q_width()),
  209.     sup_ye(rect.q_height())
  210. {
  211. }
  212.  
  213.                                 // move things a little
  214. void FlightWindow::ViewerAnim::stir(void)
  215. {
  216.   move_hor(4);
  217.   move_ver(4);
  218. }
  219.  
  220.                                 // Commencing and terminating the flight
  221. void FlightWindow::start_flight(void)
  222. {
  223.   is_flying = TRUE;
  224.   refresh();
  225.   frame_counter.start();
  226. }
  227.  
  228. void FlightWindow::stop_flight(void)
  229. {
  230.   is_flying = FALSE;
  231.   frame_counter.stop();
  232. }
  233.  
  234.                                 // Move things a little
  235.                                 // (usually called within draw())
  236. void FlightWindow::animate(void)
  237. {
  238.   if( !is_flying )
  239.     return;
  240.   viewer.stir();
  241.   view_buffer.project();
  242.   refresh();                            // That would make sure that the next call
  243.                                         // to WaitNextEvent would get another update
  244.   ++frame_counter;
  245. }
  246.  
  247.  
  248. FullFlightWindow::FullFlightWindow(const ElevationMap& image_map, const int wind_id)
  249.     : FlightWindow(image_map,wind_id,qd.screenBits.bounds),
  250.       normal_menu_bar_height(LMGetMBarHeight())
  251. {
  252.   WindowPtr whole_screen_win = our_window();
  253.   assert( whole_screen_win != nil );
  254.   MoveWindow( whole_screen_win, qd.screenBits.bounds.left, qd.screenBits.bounds.top, true );
  255.   SizeWindow( whole_screen_win, qd.screenBits.bounds.right - qd.screenBits.bounds.left,
  256.                         qd.screenBits.bounds.bottom - qd.screenBits.bounds.top, false );
  257.     /****************************************************/
  258.     /* Set the window's visRgn to include the menu bar. */
  259.     /****************************************************/
  260.     
  261.   RectRgn( (*whole_screen_win).visRgn, &qd.screenBits.bounds );
  262.   InvalRect( &qd.screenBits.bounds );
  263.     
  264.     /*************************************************/
  265.     /* Set the global MBarHeight to 0 to prevent any */
  266.     /*    other apps from writing to the menu bar.     */
  267.     /*************************************************/
  268.   LMSetMBarHeight(0);
  269.   ObscureCursor();                        // hide the cursor, use ShieldCursor()???
  270. }
  271.  
  272.         // Make sure we restore the original Menu Bar height
  273.         // And the gDevice colors we must've screwed up...
  274. void FullFlightWindow::destroy_it(void)
  275. {
  276.   LMSetMBarHeight(normal_menu_bar_height);    // Restore the normal menu bar height
  277.   RestoreDeviceClut(GetGDevice());
  278.   FlightWindow::destroy_it();                // Continue destructing...
  279. }
  280.  
  281. void FullFlightWindow::setup_color_env(OffScreenBuffer& offscreen_buffer)
  282. {
  283.   was_QD_optimized = offscreen_buffer.impose_on_gdevice(GetGDevice());
  284. }
  285.  
  286.  
  287. void FullFlightWindow::draw(void)            // It is this function that really draws smth
  288.   //view_buffer.draw(q_bounds());
  289.   {                                        // This is a little bit faster method, works only
  290.                                           // if we blit to the whole window;
  291.                                           // view_buffer.draw(q_bounds()); works even if
  292.                                           // we blit to a user-item control within a dialog
  293.                                           // window
  294.     PixMapHandle pixmap = get_pixmap();
  295.     assert( LockPixels(pixmap) );
  296.     //GDHandle gd_device = GetGDevice();    // maybe current device?
  297.     //CTabHandle old_ctab = (**pixmap).pmTable;
  298.     //(**pixmap).pmTable = (**(**gd_device).gdPMap).pmTable;
  299.     Rect& pixmap_rect = (**pixmap).bounds;
  300.     //ScreenRect(pixmap_rect).print("pixmap");
  301.     //q_bounds().print("bounds");
  302.     //ScreenRect((**(**gd_device).gdPMap).bounds).print("gd device's rect");
  303.     //_error("done");
  304.       //EraseRect(q_bounds());
  305.     //CopyBits((const BitMap *)*pixmap, (BitMap*)(*(**gd_device).gdPMap), &pixmap_rect, 
  306.      //      &(**(**gd_device).gdPMap).bounds, /*ditherCopy*/ srcCopy, nil);
  307.            // Make sure that rectangles are appropriate!! that same as gdevice's!!!
  308.     CopyBits((const BitMap *)*pixmap, &qd.thePort->portBits, &pixmap_rect, 
  309.           q_bounds(), /*ditherCopy*/ srcCopy, nil);
  310.      //(**pixmap).pmTable = old_ctab;
  311.     UnlockPixels(pixmap);
  312.   }
  313.   animate();
  314. }
  315.