瀏覽代碼

rework a bit for linux progress bar

David Rose 16 年之前
父節點
當前提交
de2788c4cc

+ 3 - 4
direct/src/plugin/p3dOsxSplashWindow.cxx

@@ -242,10 +242,9 @@ paint_window() {
 
 
   // Draw the progress bar.  We don't draw this bar at all unless we
   // Draw the progress bar.  We don't draw this bar at all unless we
   // have nonzero progress.
   // have nonzero progress.
-  int bar_width = min((int)(win_width * 0.6), 400);
-  int bar_height = min((int)(win_height * 0.1), 24);
-  int bar_x = (win_width - bar_width) / 2;
-  int bar_y = (win_height - bar_height * 2);
+  int bar_x, bar_y, bar_width, bar_height;
+  get_bar_placement(win_width, win_height,
+                    bar_x, bar_y, bar_width, bar_height);
   
   
   int progress_width = (int)((bar_width - 2) * _install_progress);
   int progress_width = (int)((bar_width - 2) * _install_progress);
   if (progress_width > 0) {
   if (progress_width > 0) {

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

@@ -219,3 +219,19 @@ read_image(const string &image_filename, bool image_filename_temp,
 
 
   return true;
   return true;
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DSplashWindow::get_bar_placement
+//       Access: Protected
+//  Description: Given the window width and height, determine the
+//               rectangle in which to place the progress bar.
+////////////////////////////////////////////////////////////////////
+void P3DSplashWindow::
+get_bar_placement(int win_width, int win_height,
+                  int &bar_x, int &bar_y,
+                  int &bar_width, int &bar_height) {
+  bar_width = min((int)(win_width * 0.6), 400);
+  bar_height = min((int)(win_height * 0.1), 24);
+  bar_x = (win_width - bar_width) / 2;
+  bar_y = (win_height - bar_height * 2);
+}

+ 3 - 0
direct/src/plugin/p3dSplashWindow.h

@@ -54,6 +54,9 @@ public:
 protected:
 protected:
   bool read_image(const string &image_filename, bool image_filename_temp,
   bool read_image(const string &image_filename, bool image_filename_temp,
                   int &height, int &width, int &num_channels, string &data);
                   int &height, int &width, int &num_channels, string &data);
+  void get_bar_placement(int win_width, int win_height,
+                         int &bar_x, int &bar_y,
+                         int &bar_width, int &bar_height);
 
 
 protected:
 protected:
   P3DInstance *_inst;
   P3DInstance *_inst;

+ 108 - 49
direct/src/plugin/p3dX11SplashWindow.cxx

@@ -57,9 +57,8 @@ P3DX11SplashWindow(P3DInstance *inst) :
   _resized_width = 0;
   _resized_width = 0;
   _resized_height = 0;
   _resized_height = 0;
   _graphics_context = None;
   _graphics_context = None;
-  _image_filename_changed = false;
+  _bar_context = None;
   _image_filename_temp = false;
   _image_filename_temp = false;
-  _install_label_changed = false;
   _install_progress = 0.0;
   _install_progress = 0.0;
 }
 }
 
 
@@ -330,19 +329,31 @@ subprocess_run() {
 
 
   make_window();
   make_window();
   setup_gc();
   setup_gc();
+  if (_graphics_context == None) {
+    // No point in continuing if we couldn't get a graphics context.
+    close_window();
+    return;
+  }
 
 
   XEvent event;
   XEvent event;
   XSelectInput(_display, _window, ExposureMask | StructureNotifyMask);
   XSelectInput(_display, _window, ExposureMask | StructureNotifyMask);
   
   
-  bool override = true, have_event = false;
+  string prev_image_filename;
   string prev_label;
   string prev_label;
   double prev_progress;
   double prev_progress;
 
 
+  bool needs_redraw = true;
+  bool needs_draw_label = false;
+  bool needs_redraw_progress = false;
+  bool needs_update_progress = false;
+
   _subprocess_continue = true;
   _subprocess_continue = true;
   while (_subprocess_continue) {
   while (_subprocess_continue) {
     // First, scan for X events.
     // First, scan for X events.
-    have_event = XCheckTypedWindowEvent(_display, _window, Expose, &event)
-              || XCheckTypedWindowEvent(_display, _window, GraphicsExpose, &event);
+    if (XCheckTypedWindowEvent(_display, _window, Expose, &event)
+        || XCheckTypedWindowEvent(_display, _window, GraphicsExpose, &event)) {
+      needs_redraw = true;
+    }
     
     
     if (XCheckTypedWindowEvent(_display, _window, ConfigureNotify, &event)) {
     if (XCheckTypedWindowEvent(_display, _window, ConfigureNotify, &event)) {
       if (_resized_image != NULL && (event.xconfigure.width  != _width ||
       if (_resized_image != NULL && (event.xconfigure.width  != _width ||
@@ -352,37 +363,80 @@ subprocess_run() {
       }
       }
       _width = event.xconfigure.width;
       _width = event.xconfigure.width;
       _height = event.xconfigure.height;
       _height = event.xconfigure.height;
-      override = true;
+      needs_redraw = true;
     }
     }
     
     
-    double install_progress = _install_progress;
-    string install_label = _install_label;
-    
-    if (_image_filename_changed) {
+    if (_image_filename != prev_image_filename) {
       update_image_filename(_image_filename, _image_filename_temp);
       update_image_filename(_image_filename, _image_filename_temp);
-      override = true;
+      needs_redraw = true;
+      prev_image_filename = _image_filename;
     }
     }
-    _image_filename_changed = false;
 
 
-    if (override || have_event || install_label != prev_label) {
-      override = false;
-      
-      if (install_progress != 0.0) {
-        redraw(install_label);
-        XFillRectangle(_display, _window, _graphics_context, 12, _height - 18,
-                       (unsigned int)(install_progress * (_width - 24)), 7);
+    if (_install_label != prev_label) {
+      needs_redraw = true;
+      prev_label = _install_label;
+    }
+    
+    if (_install_progress != prev_progress) {
+      needs_update_progress = true;
+      prev_progress = _install_progress;
+
+      if (_install_progress == 0.0) {
+        // If the progress bar drops to zero, repaint the screen to
+        // take the progress bar away.
+        needs_redraw = true;
       }
       }
+    }
+    
+    if (needs_redraw) {
+      redraw();
       XFlush(_display);
       XFlush(_display);
 
 
-    } else if (install_progress != prev_progress) {
-      if (install_progress != 0.0) {
-        XFillRectangle(_display, _window, _graphics_context, 12, _height - 18,
-                       (unsigned int)(install_progress * (_width - 24)), 7);
+      needs_redraw = false;
+      needs_draw_label = true;
+      needs_redraw_progress = true;
+    }
+
+    // Don't draw an install label or a progress bar unless we have
+    // some nonzero progress.
+    if (_install_progress != 0.0) {
+      int bar_x, bar_y, bar_width, bar_height;
+      get_bar_placement(_width, _height,
+                        bar_x, bar_y, bar_width, bar_height);
+
+      if (needs_draw_label) {
+        int text_width = _install_label.size() * 6;
+        int text_height = 10;
+        int text_x = (_width - text_width) / 2;
+        int text_y = bar_y - 4;
+
+        XClearArea(_display, _window,
+                   text_x - 2, text_y - text_height - 2,
+                   text_width + 4, text_height + 4, false);
+        XDrawString(_display, _window, _graphics_context, text_x, text_y,
+                    _install_label.c_str(), _install_label.size());
+        
+        needs_draw_label = false;
+      }
+      
+      if (needs_redraw_progress) {
+        XClearArea(_display, _window, 
+                   bar_x, bar_y, bar_width, bar_height, false);
+        XDrawRectangle(_display, _window, _graphics_context, 
+                       bar_x, bar_y, bar_width, bar_height);
+        needs_update_progress = true;
+        needs_redraw_progress = false;
+      }
+      
+      if (needs_update_progress) {
+        int progress_width = (int)((bar_width - 2) * _install_progress);
+        XFillRectangle(_display, _window, _bar_context, 
+                       bar_x + 1, bar_y + 1,
+                       progress_width + 1, bar_height - 1);
+        needs_update_progress = false;
       }
       }
     }
     }
 
 
-    prev_label = install_label;
-    prev_progress = install_progress;
 
 
     // Now check for input from the parent.
     // Now check for input from the parent.
     int read_fd = _pipe_read.get_handle();
     int read_fd = _pipe_read.get_handle();
@@ -437,7 +491,6 @@ receive_command() {
           if (_image_filename != string(str)) {
           if (_image_filename != string(str)) {
             _image_filename = str;
             _image_filename = str;
             _image_filename_temp = image_filename_temp;
             _image_filename_temp = image_filename_temp;
-            _image_filename_changed = true;
           }
           }
         }
         }
 
 
@@ -446,7 +499,6 @@ receive_command() {
         if (str != NULL) {
         if (str != NULL) {
           if (_install_label != string(str)) {
           if (_install_label != string(str)) {
             _install_label = str;
             _install_label = str;
-            _install_label_changed = true;
           }
           }
         }
         }
 
 
@@ -466,9 +518,7 @@ receive_command() {
 //  Description: Redraws the window.
 //  Description: Redraws the window.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void P3DX11SplashWindow::
 void P3DX11SplashWindow::
-redraw(string label) {
-  if (_graphics_context == NULL) return;
-  
+redraw() {
   if (_image == NULL) {
   if (_image == NULL) {
     XClearWindow(_display, _window);
     XClearWindow(_display, _window);
   } else {
   } else {
@@ -506,22 +556,6 @@ redraw(string label) {
                 (_width - _resized_width) / 2, (_height - _resized_height) / 2,
                 (_width - _resized_width) / 2, (_height - _resized_height) / 2,
                 _resized_width, _resized_height);
                 _resized_width, _resized_height);
     }
     }
-    XClearArea(_display, _window, 10, _height - 20, _width - 20, 10, false);
-  }
-
-  if (_install_progress != 0.0) {
-    // Draw the rest - the label and the progress bar outline.
-    int text_width = label.size() * 6;
-    int text_height = 10;
-    int text_x = (_width - text_width) / 2;
-    int text_y = _height - 30;
-
-    XClearArea(_display, _window,
-               text_x - 2, text_y - text_height - 2,
-               text_width + 4, text_height + 4, false);
-    XDrawString(_display, _window, _graphics_context, text_x, text_y,
-                label.c_str(), label.size());
-    XDrawRectangle(_display, _window, _graphics_context, 10, _height - 20, _width - 20, 10);
   }
   }
 }
 }
 
 
@@ -579,13 +613,12 @@ make_window() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void P3DX11SplashWindow::
 void P3DX11SplashWindow::
 setup_gc() {
 setup_gc() {
-  if (_graphics_context != NULL) {
+  if (_graphics_context != None) {
     return;
     return;
   }
   }
 
 
-  _install_label_changed = false;
-  
   XFontStruct* fs = XLoadQueryFont(_display, "6x13");
   XFontStruct* fs = XLoadQueryFont(_display, "6x13");
+
   XGCValues gcval;
   XGCValues gcval;
   gcval.font = fs->fid; 
   gcval.font = fs->fid; 
   gcval.function = GXcopy;
   gcval.function = GXcopy;
@@ -594,6 +627,22 @@ setup_gc() {
   gcval.background = WhitePixel(_display, _screen);
   gcval.background = WhitePixel(_display, _screen);
   _graphics_context = XCreateGC(_display, _window, 
   _graphics_context = XCreateGC(_display, _window, 
     GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground, &gcval); 
     GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground, &gcval); 
+
+  // Also create a gc for filling in the interior of the progress bar
+  // in a pleasant blue color.
+  XColor blue;
+  blue.red = 27756;
+  blue.green = 42405;
+  blue.blue = 57568;
+  blue.flags = DoRed | DoGreen | DoBlue;
+
+  Colormap colormap = DefaultColormap(_display, _screen);
+  if (XAllocColor(_display, colormap, &blue)) {
+    gcval.foreground = blue.pixel;
+  }
+
+  _bar_context = XCreateGC(_display, _window, 
+    GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground, &gcval);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -605,14 +654,24 @@ void P3DX11SplashWindow::
 close_window() {
 close_window() {
   if (_image != NULL) {
   if (_image != NULL) {
     XDestroyImage(_image);
     XDestroyImage(_image);
+    _image = NULL;
   }
   }
   
   
   if (_resized_image != NULL) {
   if (_resized_image != NULL) {
     XDestroyImage(_resized_image);
     XDestroyImage(_resized_image);
+    _resized_image = NULL;
+  }
+  
+  if (_bar_context != None) {
+    if (_bar_context != _graphics_context) {
+      XFreeGC(_display, _bar_context);
+    }
+    _bar_context = None;
   }
   }
   
   
   if (_graphics_context != None) {
   if (_graphics_context != None) {
     XFreeGC(_display, _graphics_context);
     XFreeGC(_display, _graphics_context);
+    _graphics_context = None;
   }
   }
   
   
   if (_window != None) {
   if (_window != None) {

+ 2 - 3
direct/src/plugin/p3dX11SplashWindow.h

@@ -56,7 +56,7 @@ private:
   void subprocess_run();
   void subprocess_run();
   void receive_command();
   void receive_command();
 
 
-  void redraw(string label);
+  void redraw();
   void make_window();
   void make_window();
   void setup_gc();
   void setup_gc();
   void update_image_filename(const string &image_filename, 
   void update_image_filename(const string &image_filename, 
@@ -70,10 +70,8 @@ private:
   int _width, _height;
   int _width, _height;
   
   
   bool _own_display;
   bool _own_display;
-  bool _image_filename_changed;
   string _image_filename;
   string _image_filename;
   bool _image_filename_temp;
   bool _image_filename_temp;
-  bool _install_label_changed;
   string _install_label;
   string _install_label;
   double _install_progress;
   double _install_progress;
   
   
@@ -82,6 +80,7 @@ private:
   Display *_display;
   Display *_display;
   int _screen;
   int _screen;
   GC _graphics_context;
   GC _graphics_context;
+  GC _bar_context;
   XImage* _image;
   XImage* _image;
   XImage* _resized_image;
   XImage* _resized_image;
   int _image_width, _image_height;
   int _image_width, _image_height;

+ 1 - 1
direct/src/showutil/packp3d.py

@@ -65,7 +65,7 @@ def makePackedApp(args):
 
 
     packager = Packager.Packager()
     packager = Packager.Packager()
 
 
-    root = '.'
+    root = Filename('.')
     main = None
     main = None
     requires = []
     requires = []
     versionIndependent = False
     versionIndependent = False