From 902ab1111a2e1448398347f17209bcdda6e0999b Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 19 Nov 2009 21:37:52 +0000 Subject: [PATCH] bgcolor, fgcolor, barcolor --- direct/src/plugin/p3dInstance.cxx | 129 +++++++++++++++++++---- direct/src/plugin/p3dInstance.h | 3 + direct/src/plugin/p3dSplashWindow.cxx | 58 ++++++++++ direct/src/plugin/p3dSplashWindow.h | 7 ++ direct/src/plugin/p3dX11SplashWindow.cxx | 66 ++++++++++-- direct/src/plugin/p3dX11SplashWindow.h | 6 +- 6 files changed, 238 insertions(+), 31 deletions(-) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 024a72d8c8..634e788221 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -2189,8 +2189,37 @@ make_splash_window() { } _splash_window = new SplashWindowType(this, make_visible); + + // Get the splash window colors. We must set these *before* we call + // set_wparams. + if (_fparams.has_token("fgcolor")) { + int r, g, b; + if (parse_color(r, g, b, _fparams.lookup_token("fgcolor"))) { + _splash_window->set_fgcolor(r, g, b); + } else { + nout << "parse failure on fgcolor " << _fparams.lookup_token("fgcolor") << "\n"; + } + } + if (_fparams.has_token("bgcolor")) { + int r, g, b; + if (parse_color(r, g, b, _fparams.lookup_token("bgcolor"))) { + _splash_window->set_bgcolor(r, g, b); + } else { + nout << "parse failure on bgcolor " << _fparams.lookup_token("bgcolor") << "\n"; + } + } + if (_fparams.has_token("barcolor")) { + int r, g, b; + if (parse_color(r, g, b, _fparams.lookup_token("barcolor"))) { + _splash_window->set_barcolor(r, g, b); + } else { + nout << "parse failure on barcolor " << _fparams.lookup_token("barcolor") << "\n"; + } + } + _splash_window->set_wparams(_wparams); _splash_window->set_install_label(_install_label); + P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); @@ -2713,25 +2742,6 @@ set_install_label(const string &install_label) { } } -//////////////////////////////////////////////////////////////////// -// Function: P3DInstance::send_notify -// Access: Private -// Description: Generates a synthetic notify message here at the C++ -// level. -// -// Most notify messages are generated from within the -// Python code, and don't use this method; but a few -// have to be sent before Python has started, and those -// come through this method. -//////////////////////////////////////////////////////////////////// -void P3DInstance:: -send_notify(const string &message) { - P3D_request *request = new P3D_request; - request->_request_type = P3D_RT_notify; - request->_request._notify._message = strdup(message.c_str()); - add_baked_request(request); -} - //////////////////////////////////////////////////////////////////// // Function: P3DInstance::paint_window // Access: Private @@ -2918,6 +2928,87 @@ add_modifier_flags(unsigned int &swb_flags, int modifiers) { #endif // __APPLE__ } +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::send_notify +// Access: Private +// Description: Generates a synthetic notify message here at the C++ +// level. +// +// Most notify messages are generated from within the +// Python code, and don't use this method; but a few +// have to be sent before Python has started, and those +// come through this method. +//////////////////////////////////////////////////////////////////// +void P3DInstance:: +send_notify(const string &message) { + P3D_request *request = new P3D_request; + request->_request_type = P3D_RT_notify; + request->_request._notify._message = strdup(message.c_str()); + add_baked_request(request); +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::parse_color +// Access: Private, Static +// Description: Parses a HTML color spec of the form #rgb or #rrggbb. +// Returns true on success, false on failure. On +// success, fills r, g, b with the color values in the +// range 0..255. On failure, r, g, b are undefined. +//////////////////////////////////////////////////////////////////// +bool P3DInstance:: +parse_color(int &r, int &g, int &b, const string &color) { + if (color.empty() || color[0] != '#') { + return false; + } + if (color.length() == 4) { + if (!parse_hexdigit(r, color[1]) || + !parse_hexdigit(g, color[2]) || + !parse_hexdigit(b, color[3])) { + return false; + } + r *= 0x11; + g *= 0x11; + b *= 0x11; + return true; + } + if (color.length() == 7) { + int rh, rl, gh, gl, bh, bl; + if (!parse_hexdigit(rh, color[1]) || + !parse_hexdigit(rl, color[2]) || + !parse_hexdigit(gh, color[3]) || + !parse_hexdigit(gl, color[4]) || + !parse_hexdigit(bh, color[5]) || + !parse_hexdigit(bl, color[6])) { + return false; + } + r = (rh << 4) | rl; + g = (gh << 4) | gl; + b = (bh << 4) | bl; + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::parse_hexdigit +// Access: Private, Static +// Description: Parses a single hex digit. Returns true on success, +// false on failure. On success, fills result with the +// parsed value, an integer in the range 0..15. +//////////////////////////////////////////////////////////////////// +bool P3DInstance:: +parse_hexdigit(int &result, char digit) { + if (isdigit(digit)) { + result = digit - '0'; + return true; + } else if (isxdigit(digit)) { + result = tolower(digit) - 'a' + 10; + return true; + } + return false; +} + #ifdef __APPLE__ //////////////////////////////////////////////////////////////////// // Function: P3DInstance::timer_callback diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index fe57de055e..18e9f48ca7 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -195,6 +195,9 @@ private: void send_notify(const string &message); + static bool parse_color(int &r, int &g, int &b, const string &color); + static bool parse_hexdigit(int &result, char digit); + #ifdef __APPLE__ static void timer_callback(CFRunLoopTimerRef timer, void *info); #endif // __APPLE__ diff --git a/direct/src/plugin/p3dSplashWindow.cxx b/direct/src/plugin/p3dSplashWindow.cxx index 12846d66ad..f67e302eb8 100755 --- a/direct/src/plugin/p3dSplashWindow.cxx +++ b/direct/src/plugin/p3dSplashWindow.cxx @@ -55,6 +55,15 @@ P3DSplashWindow(P3DInstance *inst, bool make_visible) : _wparams(inst->get_wparams()) { _visible = make_visible; + _fgcolor_r = 0x00; + _fgcolor_g = 0x00; + _fgcolor_b = 0x00; + _bgcolor_r = 0xff; + _bgcolor_g = 0xff; + _bgcolor_b = 0xff; + _barcolor_r = 0x6c; + _barcolor_g = 0xa5; + _barcolor_b = 0xe0; _button_width = 0; _button_height = 0; _button_x = 0; @@ -118,6 +127,55 @@ void P3DSplashWindow:: set_image_filename(const string &image_filename, ImagePlacement image_placement) { } +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::set_fgcolor +// Access: Public, Virtual +// Description: Specifies the color that is used to display the text +// above the loading bar. +// +// This may only be set before wparams is set. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_fgcolor(int r, int g, int b) { + nout << "fgcolor " << r << ", " << g << ", " << b << "\n"; + _fgcolor_r = r; + _fgcolor_g = g; + _fgcolor_b = b; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::set_bgcolor +// Access: Public, Virtual +// Description: Specifies the solid color that is displayed behind +// the splash image, if any, or before the splash image +// is loaded. +// +// This may only be set before wparams is set. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_bgcolor(int r, int g, int b) { + nout << "bgcolor " << r << ", " << g << ", " << b << "\n"; + _bgcolor_r = r; + _bgcolor_g = g; + _bgcolor_b = b; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::set_barcolor +// Access: Public, Virtual +// Description: Specifies the color that is used to fill the +// loading bar. +// +// This may only be set before wparams is set. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_barcolor(int r, int g, int b) { + nout << "barcolor " << r << ", " << g << ", " << b << "\n"; + _barcolor_r = r; + _barcolor_g = g; + _barcolor_b = b; +} + //////////////////////////////////////////////////////////////////// // Function: P3DSplashWindow::set_install_label // Access: Public, Virtual diff --git a/direct/src/plugin/p3dSplashWindow.h b/direct/src/plugin/p3dSplashWindow.h index 6d66d14a05..34740bc65a 100755 --- a/direct/src/plugin/p3dSplashWindow.h +++ b/direct/src/plugin/p3dSplashWindow.h @@ -54,6 +54,9 @@ public: virtual void set_image_filename(const string &image_filename, ImagePlacement image_placement); + virtual void set_fgcolor(int r, int g, int b); + virtual void set_bgcolor(int r, int g, int b); + virtual void set_barcolor(int r, int g, int b); virtual void set_install_label(const string &install_label); virtual void set_install_progress(double install_progress); @@ -102,6 +105,10 @@ protected: int _win_width, _win_height; bool _visible; + int _fgcolor_r, _fgcolor_g, _fgcolor_b; + int _bgcolor_r, _bgcolor_g, _bgcolor_b; + int _barcolor_r, _barcolor_g, _barcolor_b; + // The region of the window for accepting button clicks. int _button_width, _button_height; int _button_x, _button_y; diff --git a/direct/src/plugin/p3dX11SplashWindow.cxx b/direct/src/plugin/p3dX11SplashWindow.cxx index ac56c6523d..113ff89b37 100755 --- a/direct/src/plugin/p3dX11SplashWindow.cxx +++ b/direct/src/plugin/p3dX11SplashWindow.cxx @@ -52,6 +52,10 @@ P3DX11SplashWindow(P3DInstance *inst, bool make_visible) : _screen = 0; _graphics_context = None; _bar_context = None; + _fg_pixel = -1; + _bg_pixel = -1; + _bar_pixel = -1; + _own_display = false; _install_progress = 0.0; } @@ -824,9 +828,35 @@ make_window() { ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask; + // Allocate the foreground and background colors. + Colormap colormap = DefaultColormap(_display, _screen); + + XColor fg; + fg.red = _fgcolor_r * 0x101; + fg.green = _fgcolor_g * 0x101; + fg.blue = _fgcolor_b * 0x101; + fg.flags = DoRed | DoGreen | DoBlue; + _fg_pixel = -1; + if (XAllocColor(_display, colormap, &fg)) { + _fg_pixel = fg.pixel; + } + + XColor bg; + bg.red = _bgcolor_r * 0x101; + bg.green = _bgcolor_g * 0x101; + bg.blue = _bgcolor_b * 0x101; + bg.flags = DoRed | DoGreen | DoBlue; + _bg_pixel = -1; + if (XAllocColor(_display, colormap, &bg)) { + _bg_pixel = bg.pixel; + } + // Initialize window attributes XSetWindowAttributes wa; wa.background_pixel = XWhitePixel(_display, _screen); + if (_bg_pixel != -1) { + wa.background_pixel = _bg_pixel; + } wa.border_pixel = 0; wa.event_mask = event_mask; @@ -859,22 +889,28 @@ setup_gc() { gcval.function = GXcopy; gcval.plane_mask = AllPlanes; gcval.foreground = BlackPixel(_display, _screen); + if (_fg_pixel != -1) { + gcval.foreground = _fg_pixel; + } gcval.background = WhitePixel(_display, _screen); + if (_bg_pixel != -1) { + gcval.background = _bg_pixel; + } _graphics_context = XCreateGC(_display, _window, 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; + // in a pleasant blue color (or whatever color the user requested). + XColor bar; + bar.red = _barcolor_r * 0x101; + bar.green = _barcolor_g * 0x101; + bar.blue = _barcolor_b * 0x101; + bar.flags = DoRed | DoGreen | DoBlue; Colormap colormap = DefaultColormap(_display, _screen); - if (XAllocColor(_display, colormap, &blue)) { - _blue_pixel = blue.pixel; - gcval.foreground = blue.pixel; + if (XAllocColor(_display, colormap, &bar)) { + _bar_pixel = bar.pixel; + gcval.foreground = bar.pixel; } _bar_context = XCreateGC(_display, _window, @@ -901,7 +937,17 @@ close_window() { // Also free the color we allocated. Colormap colormap = DefaultColormap(_display, _screen); - XFreeColors(_display, colormap, &_blue_pixel, 1, 0); + XFreeColors(_display, colormap, &_bar_pixel, 1, 0); + } + + if (_fg_pixel != -1) { + Colormap colormap = DefaultColormap(_display, _screen); + XFreeColors(_display, colormap, &_fg_pixel, 1, 0); + } + + if (_bg_pixel != -1) { + Colormap colormap = DefaultColormap(_display, _screen); + XFreeColors(_display, colormap, &_bg_pixel, 1, 0); } if (_graphics_context != None) { diff --git a/direct/src/plugin/p3dX11SplashWindow.h b/direct/src/plugin/p3dX11SplashWindow.h index 38269ef9d0..7f9b97f65d 100755 --- a/direct/src/plugin/p3dX11SplashWindow.h +++ b/direct/src/plugin/p3dX11SplashWindow.h @@ -118,7 +118,7 @@ private: bool _needs_new_composite; bool _subprocess_continue; - + bool _own_display; string _install_label; double _install_progress; @@ -129,7 +129,9 @@ private: int _screen; GC _graphics_context; GC _bar_context; - unsigned long _blue_pixel; + unsigned long _fg_pixel; + unsigned long _bg_pixel; + unsigned long _bar_pixel; Window _window; };