rework a bit for linux progress bar

This commit is contained in:
David Rose 2009-08-17 19:24:54 +00:00
parent 95b4011312
commit de2788c4cc
6 changed files with 133 additions and 57 deletions

View File

@ -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_x, bar_y, bar_width, bar_height;
int bar_height = min((int)(win_height * 0.1), 24); get_bar_placement(win_width, win_height,
int bar_x = (win_width - bar_width) / 2; bar_x, bar_y, bar_width, bar_height);
int bar_y = (win_height - bar_height * 2);
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) {

View File

@ -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);
}

View File

@ -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;

View File

@ -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) if (XCheckTypedWindowEvent(_display, _window, Expose, &event)
|| XCheckTypedWindowEvent(_display, _window, GraphicsExpose, &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; if (_image_filename != prev_image_filename) {
string install_label = _install_label;
if (_image_filename_changed) {
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) { if (_install_label != prev_label) {
override = false; needs_redraw = true;
prev_label = _install_label;
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_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) { needs_redraw = false;
if (install_progress != 0.0) { needs_draw_label = true;
XFillRectangle(_display, _window, _graphics_context, 12, _height - 18, needs_redraw_progress = true;
(unsigned int)(install_progress * (_width - 24)), 7); }
// 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) { redraw() {
if (_graphics_context == NULL) return;
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) {

View File

@ -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;

View File

@ -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