Browse Source

use quartz for splash window

David Rose 16 years ago
parent
commit
c4842323e8

+ 10 - 0
direct/src/plugin/Sources.pp

@@ -174,4 +174,14 @@
 
 #end static_lib_target
 
+
+#begin bin_target
+  #define BUILD_TARGET $[HAVE_WX]
+  #define USE_PACKAGES wx openssl
+  #define TARGET p3dcert
+
+  #define SOURCES p3dCert.cxx
+#end bin_target
+
+
 #include $[THISDIRPREFIX]p3d_plugin_config.h.pp

+ 145 - 86
direct/src/plugin/p3dOsxSplashWindow.cxx

@@ -84,7 +84,7 @@ set_wparams(const P3DWindowParams &wparams) {
       EventHandlerRef application_event_ref_ref1;
       EventTypeSpec list1[] = { 
         { kEventClassWindow, kEventWindowDrawContent },
-        //{ kEventClassWindow, kEventWindowUpdate },
+        { kEventClassWindow, kEventWindowBoundsChanged },
         { kEventClassMouse, kEventMouseUp },
         { kEventClassMouse, kEventMouseDown },
         { kEventClassMouse, kEventMouseMoved },
@@ -242,96 +242,76 @@ paint_window() {
   }
 
   GrafPtr out_port = NULL;
-  GrafPtr portSave = NULL;
-  Boolean portChanged = false;
-
   if (_toplevel_window != NULL) {
     GetPort(&out_port);
 
   } else {
     out_port = _wparams.get_parent_window()._port;
-    portChanged = QDSwapPort(out_port, &portSave);
   }
 
-  Rect r = { 0, 0, _win_height, _win_width }; 
-  ClipRect(&r);
-  EraseRect(&r);
+  CGContextRef context;
+  OSStatus err = CreateCGContextForPort(out_port, &context);
+  if (err != noErr) {
+    nout << "Couldn't create CG context\n";
+    return;
+  }
+
+  //  Adjust for any SetOrigin calls on out_port
+  SyncCGContextOriginWithPort(context, out_port);
+  
+  //  Move the CG origin to the upper left of the port
+  Rect port_rect;
+  GetPortBounds(out_port, &port_rect);
+  CGContextTranslateCTM(context, 0, (float)(port_rect.bottom - port_rect.top));
+  
+  //  Flip the y axis so that positive Y points down
+  CGContextScaleCTM(context, 1.0, -1.0);
+
+  int width = port_rect.right - port_rect.left;
+  int height = port_rect.bottom - port_rect.top;
+  if (width != _win_width || height != _win_height) {
+    _win_width = width;
+    _win_height = height;
+    set_button_range(_button_ready_image);
+  }
+
+  // Clear the whole region to white before beginning.
+  CGRect region = { { 0, 0 }, { _win_width, _win_height } };
 
-  paint_image(out_port, _background_image);
+  // Clear the entire progress bar to white.
+  CGColorRef white = CGColorGetConstantColor(kCGColorWhite);
+  CGContextBeginPath(context);
+  CGContextSetFillColorWithColor(context, white);
+  CGContextAddRect(context, region);
+  CGContextFillPath(context);
 
+  // Now paint in the image(s).
+  paint_image(context, _background_image);
   switch (_bstate) {
   case BS_hidden:
     break;
   case BS_ready:
-    paint_image(out_port, _button_ready_image);
+    paint_image(context, _button_ready_image);
     break;
   case BS_rollover:
-    if (!paint_image(out_port, _button_rollover_image)) {
-      paint_image(out_port, _button_ready_image);
+    if (!paint_image(context, _button_rollover_image)) {
+      paint_image(context, _button_ready_image);
     }
     break;
   case BS_click:
-    if (!paint_image(out_port, _button_click_image)) {
-      paint_image(out_port, _button_ready_image);
+    if (!paint_image(context, _button_click_image)) {
+      paint_image(context, _button_ready_image);
     }
     break;
   }
 
   // Draw the progress bar.  We don't draw this bar at all unless we
   // have nonzero progress.
-  int bar_x, bar_y, bar_width, bar_height;
-  get_bar_placement(bar_x, bar_y, bar_width, bar_height);
-  
   if (_install_progress != 0.0) {
-    Rect rbar = { bar_y, bar_x, bar_y + bar_height, bar_x + bar_width };
-    FrameRect(&rbar);
-
-    int progress_width = (int)((bar_width - 2) * _install_progress);
-    if (progress_width != 0) {
-      int progress = bar_x + 1 + progress_width;
-      Rect rneed = { bar_y + 1, progress, bar_y + bar_height - 1, bar_x + bar_width - 1 };
-      Rect rdone = { bar_y + 1, bar_x + 1, bar_y + bar_height - 1, progress };
-      RGBColor blue = { 27756, 42405, 57568 };
-      RGBForeColor(&blue);
-      PaintRect(&rdone);
-      EraseRect(&rneed);
-    }
-    
-    RGBColor black = { 0, 0, 0 };
-    RGBForeColor(&black);
-
-    if (!_install_label.empty()) {
-      // Now draw the install_label right above it.
-      TextFont(0);
-      TextFace(bold);
-      TextMode(srcOr);
-      TextSize(0);
-      
-      Point numer = { 1, 1 };
-      Point denom = { 1, 1 };
-      FontInfo font_info;
-      StdTxMeas(_install_label.size(), _install_label.data(), &numer, &denom, &font_info);
-      int ascent = font_info.ascent * numer.v / denom.v;
-      int descent = font_info.descent * numer.v / denom.v;
-      
-      int text_width = TextWidth(_install_label.data(), 0, _install_label.size());
-      int text_x = (_win_width - text_width) / 2;
-      int text_y = bar_y - descent - 8;
-      
-      Rect rtext = { text_y - ascent - 2, text_x - 2, 
-                     text_y + descent + 2, text_x + text_width + 2 }; 
-      EraseRect(&rtext);
-      
-      MoveTo(text_x, text_y);
-      DrawText(_install_label.data(), 0, _install_label.size());
-    }
-  }
-    
-  if (_toplevel_window == NULL) {
-    if (portChanged) {
-      QDSwapPort(portSave, NULL);
-    }
+    paint_progress_bar(context);
   }
+
+  CGContextRelease(context);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -348,13 +328,15 @@ load_image(OsxImageData &image, const string &image_filename) {
   }
 
   // Now we need to copy from the RGB (or RGBA) source image into the
-  // BGRA target image.
+  // BGRA target image.  We also flip the image upside-down here to
+  // compensate for the upside-down vertical scale on
+  // CGContextScaleCTM.
   int row_stride = image._width * image._num_channels;
   int new_row_stride = image._width * 4;
   image._raw_data = new char[new_row_stride * image._height];
   for (int yi = 0; yi < image._height; ++yi) {
     char *dest = image._raw_data + yi * new_row_stride;
-    const char *source = string_data.data() + yi * row_stride;
+    const char *source = string_data.data() + (image._height - 1 - yi) * row_stride;
     if (image._num_channels == 3) {
       // Source is RGB.
       for (int xi = 0; xi < image._width; ++xi) {
@@ -407,28 +389,16 @@ load_image(OsxImageData &image, const string &image_filename) {
 //               is not defined.
 ////////////////////////////////////////////////////////////////////
 bool P3DOsxSplashWindow::
-paint_image(GrafPtr out_port, const OsxImageData &image) {
+paint_image(CGContextRef context, const OsxImageData &image) {
   if (image._image == NULL) {
     return false;
   }
-
-  CGContextRef context;
-  QDErr err = QDBeginCGContext(out_port, &context);
-  if (err != noErr) {
-    nout << "Error: QDBeginCGContext\n";
-    return false;
-  }
-
-  // We have to rely on the clipping rectangle having been set up
-  // correctly in order to get the proper location to draw the image.
-  // This isn't completely right, because if the image is slightly
-  // offscreen, the top left of the clipping rectangle will no longer
-  // correspond to the top left of the original image.
-  CGRect rect = CGContextGetClipBoundingBox(context);
     
   // Determine the relative size of image and window.
   int win_cx = _win_width / 2;
   int win_cy = _win_height / 2;
+
+  CGRect rect = { { 0, 0 }, { 0, 0 } };
     
   if (image._width <= _win_width && image._height <= _win_height) {
     // The bitmap fits within the window; center it.
@@ -461,11 +431,92 @@ paint_image(GrafPtr out_port, const OsxImageData &image) {
 
   CGContextDrawImage(context, rect, image._image);
   
-  QDEndCGContext(out_port, &context);
-
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DOsxSplashWindow::paint_progress_bar
+//       Access: Private
+//  Description: Draws the progress bar and the label within the
+//               window.
+////////////////////////////////////////////////////////////////////
+void P3DOsxSplashWindow::
+paint_progress_bar(CGContextRef context) {
+  int bar_x, bar_y, bar_width, bar_height;
+  get_bar_placement(bar_x, bar_y, bar_width, bar_height);
+
+  // We offset the bar by half a pixel, so we'll be drawing the
+  // one-pixel line through the middle of a pixel, and it won't try to
+  // antialias itself into a half-black two-pixel line.
+  float bar_xf = bar_x + 0.5;
+  float bar_yf = bar_y - 0.5;
+
+  CGRect bar = { { bar_xf, bar_yf }, { bar_width, bar_height } };
+
+  // Clear the entire progress bar to white.
+  CGColorRef white = CGColorGetConstantColor(kCGColorWhite);
+  CGContextBeginPath(context);
+  CGContextSetFillColorWithColor(context, white);
+  CGContextAddRect(context, bar);
+  CGContextFillPath(context);
+
+  // Draw the interior of the progress bar in blue.
+  int progress_width = (int)((bar_width - 2) * _install_progress);
+  if (progress_width != 0) {
+    CGRect prog = { { bar_xf, bar_yf }, { progress_width, bar_height } };
+    CGColorRef blue = CGColorCreateGenericRGB(0.424, 0.647, 0.878, 1.0);
+    CGContextBeginPath(context);
+    CGContextSetFillColorWithColor(context, blue);
+    CGContextAddRect(context, prog);
+    CGContextFillPath(context);
+    CGColorRelease(blue);
+  }
+
+  // Draw the black stroke around the progress bar.
+  CGColorRef black = CGColorGetConstantColor(kCGColorBlack);
+  CGContextBeginPath(context);
+  CGContextSetLineWidth(context, 1);
+  CGContextSetStrokeColorWithColor(context, black);
+  CGContextAddRect(context, bar);
+  CGContextStrokePath(context);
+
+  if (!_install_label.empty()) {
+    // Now draw the install_label right above it.
+
+    CGContextSetTextMatrix(context, CGContextGetCTM(context));
+
+    // Choose a suitable font.
+    float text_height = 15.0;
+    CGContextSelectFont(context, "Helvetica", text_height, kCGEncodingMacRoman);
+
+    // Measure the text, for centering.
+    CGContextSetTextPosition(context, 0, 0);
+    CGContextSetTextDrawingMode(context, kCGTextInvisible);
+    CGContextShowText(context, _install_label.data(), _install_label.length());
+    CGPoint end_point = CGContextGetTextPosition(context);
+    float text_width = end_point.x;
+
+    int text_x = (_win_width - text_width) / 2;
+    int text_y = bar_y - text_height * 1.5;
+
+    // Clear the rectangle behind the text to white.
+    CGRect text_rect = { { text_x - 2, text_y - 2 }, { text_width + 4, text_height + 4 } };
+
+    CGContextBeginPath(context);
+    CGContextAddRect(context, text_rect);
+    CGContextSetFillColorWithColor(context, white);
+    CGContextFillPath(context);
+
+    // And finally, draw the text.
+    CGContextSetTextDrawingMode(context, kCGTextFill);
+    CGColorRef black = CGColorGetConstantColor(kCGColorBlack);
+    CGContextSetFillColorWithColor(context, black);
+
+    CGContextShowTextAtPoint(context, text_x, text_y + text_height, 
+                             _install_label.data(), _install_label.length());
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DOsxSplashWindow::st_event_callback
 //       Access: Private, Static
@@ -495,6 +546,16 @@ event_callback(EventHandlerCallRef my_handler, EventRef event) {
   switch (the_class) {
   case kEventClassWindow:
     switch (kind) {
+    case kEventWindowBoundsChanged:
+      // If the window changes size, we have to repaint it.
+      refresh();
+
+      // We seem to get the mouse-down, but lose the mouse-up, event
+      // in this case, so infer it.
+      set_mouse_data(_mouse_x, _mouse_y, false);
+      result = noErr;
+      break;
+
     case kEventWindowDrawContent:
       paint_window();
       result = noErr;
@@ -532,8 +593,6 @@ event_callback(EventHandlerCallRef my_handler, EventRef event) {
         set_mouse_data(point.h, point.v, _mouse_down);
       }
       break;
-
-      break;
     }
   }
 

+ 2 - 1
direct/src/plugin/p3dOsxSplashWindow.h

@@ -49,7 +49,8 @@ private:
   class OsxImageData;
 
   void load_image(OsxImageData &image, const string &image_filename);
-  bool paint_image(GrafPtr out_port, const OsxImageData &image);
+  bool paint_image(CGContextRef context, const OsxImageData &image);
+  void paint_progress_bar(CGContextRef context);
 
   static pascal OSStatus
   st_event_callback(EventHandlerCallRef my_handler, EventRef event, 

+ 5 - 0
direct/src/plugin/p3dSplashWindow.cxx

@@ -431,6 +431,11 @@ set_mouse_data(int mouse_x, int mouse_y, bool mouse_down) {
         if (orig_bstate == BS_rollover || _button_depressed) {
           _button_depressed = true;
           bstate = BS_click;
+        } else {
+          // Otherwise, we're mousing over the button region with the
+          // button held down.  Hmm, don't think the button should
+          // light up.
+          bstate = BS_ready;
         }
       } else {
         _button_depressed = false;

+ 1 - 1
direct/src/plugin_standalone/panda3d.cxx

@@ -973,7 +973,7 @@ URLGetter(P3D_instance *instance, int unique_id,
   HTTPClient *http = HTTPClient::get_global_ptr();
 
   _channel = http->make_channel(false);
-  //  _channel->set_download_throttle(true);
+  _channel->set_download_throttle(true);
   if (_post_data.empty()) {
     _channel->begin_get_document(_url);
   } else {