diff --git a/direct/src/p3d/coreapi.pdef b/direct/src/p3d/coreapi.pdef index dd93e5e11e..9468439742 100644 --- a/direct/src/p3d/coreapi.pdef +++ b/direct/src/p3d/coreapi.pdef @@ -55,12 +55,13 @@ class images(package): print "Could not locate %s" % (filename) # Also make a few special cases. We use the same default image - # for download, ready, unauth, and launch. + # for many of the states. download = configDict.get('download_img', None) if download: configDict['ready_img'] = download configDict['unauth_img'] = download configDict['launch_img'] = download + configDict['active_img'] = download config(**configDict) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index deeacf9586..891150ea12 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -54,7 +54,6 @@ const char *P3DInstance::_image_type_names[P3DInstance::IT_num_image_types] = { "failed", "launch", "active", - "done", "auth_ready", "auth_rollover", "auth_click", @@ -223,6 +222,10 @@ P3DInstance:: _panda_script_object->set_instance(NULL); P3D_OBJECT_DECREF(_panda_script_object); + for (int i = 0; i < (int)IT_num_image_types; ++i) { + _image_files[i].cleanup(); + } + // Tell all of the packages that we're no longer in business for // them. Packages::iterator pi; @@ -1957,19 +1960,28 @@ handle_notify_request(const string &message) { } else if (message == "onwindowopen") { // The process told us that it just succesfully opened its - // window. Hide the splash window. + // window, for the first time. Hide the splash window. _instance_window_opened = true; if (_splash_window != NULL) { _splash_window->set_visible(false); } - // Guess we won't be using these images any more. + // Guess we won't be using (most of) these images any more. for (int i = 0; i < (int)IT_num_image_types; ++i) { - _image_files[i].cleanup(); + if (i != IT_active) { + _image_files[i].cleanup(); + } } _panda_script_object->set_string_property("status", "open"); + } else if (message == "onwindowattach") { + // The graphics window has been attached to the browser frame + // (maybe initially, maybe later). Hide the splash window. + if (_splash_window != NULL) { + _splash_window->set_visible(false); + } + #ifdef __APPLE__ // Start a timer to update the frame repeatedly. This seems to be // steadier than waiting for nullEvent. @@ -1982,6 +1994,24 @@ handle_notify_request(const string &message) { CFRunLoopAddTimer(run_loop, _frame_timer, kCFRunLoopCommonModes); #endif // __APPLE__ + } else if (message == "onwindowdetach") { + // The graphics window has been removed from the browser frame. + // Restore the splash window. + _instance_window_opened = true; + set_background_image(IT_active); + if (_splash_window != NULL) { + _splash_window->set_visible(true); + } + +#ifdef __APPLE__ + // Stop the frame timer; we don't need it any more. + if (_frame_timer != NULL) { + CFRunLoopTimerInvalidate(_frame_timer); + CFRelease(_frame_timer); + _frame_timer = NULL; + } +#endif // __APPLE__ + } else if (message == "buttonclick") { // We just got a special "button click" message from the // sub-thread. This case is a little unusual, as it came from the @@ -2164,7 +2194,7 @@ make_splash_window() { // Go get the required images. for (int i = 0; i < (int)IT_none; ++i) { string token_keyword = string(_image_type_names[i]) + "_img"; - if (!_fparams.has_token(token_keyword) && i != IT_done) { + if (!_fparams.has_token(token_keyword)) { token_keyword = "splash_img"; } if (!_fparams.has_token(token_keyword)) { diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 3627399620..fe57de055e 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -145,7 +145,6 @@ private: IT_failed, IT_launch, IT_active, - IT_done, IT_auth_ready, IT_auth_rollover, IT_auth_click, diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index 09592d9e7c..0334456cea 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -389,6 +389,31 @@ run_python() { return true; } +//////////////////////////////////////////////////////////////////// +// Function: P3DPythonRun::set_window_open +// Access: Public +// Description: Called from low-level Panda (via the P3DWindowHandle +// object) when a child window has been attached or +// detached from the browser window. This triggers the +// "onwindowattach" and "onwindowdetach" JavaScript +// notifications. +//////////////////////////////////////////////////////////////////// +void P3DPythonRun:: +set_window_open(P3DCInstance *inst, bool is_open) { + TiXmlDocument doc; + TiXmlElement *xrequest = new TiXmlElement("request"); + xrequest->SetAttribute("instance_id", inst->get_instance_id()); + xrequest->SetAttribute("rtype", "notify"); + if (is_open) { + xrequest->SetAttribute("message", "onwindowattach"); + } else { + xrequest->SetAttribute("message", "onwindowdetach"); + } + doc.LinkEndChild(xrequest); + + write_xml(_pipe_write, &doc, nout); +} + //////////////////////////////////////////////////////////////////// // Function: P3DPythonRun::request_keyboard_focus // Access: Public @@ -1774,10 +1799,45 @@ P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst, const WindowHandle ©) : WindowHandle(copy), _p3dpython(p3dpython), - _inst(inst) + _inst(inst), + _child_count(0) { } +//////////////////////////////////////////////////////////////////// +// Function: P3DPythonRun::P3DWindowHandle::attach_child +// Access: Public, Virtual +// Description: Called on a parent handle to indicate a child +// window's intention to attach itself. +//////////////////////////////////////////////////////////////////// +void P3DPythonRun::P3DWindowHandle:: +attach_child(WindowHandle *child) { + WindowHandle::attach_child(child); + ++_child_count; + + if (_child_count == 1) { + // When the first child window is attached, we tell the plugin. + _p3dpython->set_window_open(_inst, true); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DPythonRun::P3DWindowHandle::detach_child +// Access: Public, Virtual +// Description: Called on a parent handle to indicate a child +// window's intention to detach itself. +//////////////////////////////////////////////////////////////////// +void P3DPythonRun::P3DWindowHandle:: +detach_child(WindowHandle *child) { + WindowHandle::detach_child(child); + --_child_count; + + if (_child_count == 0) { + // When the last child window is detached, we tell the plugin. + _p3dpython->set_window_open(_inst, false); + } +} + //////////////////////////////////////////////////////////////////// // Function: P3DPythonRun::P3DWindowHandle::request_keyboard_focus // Access: Public, Virtual diff --git a/direct/src/plugin/p3dPythonRun.h b/direct/src/plugin/p3dPythonRun.h index 8e09446cc9..da0a942267 100755 --- a/direct/src/plugin/p3dPythonRun.h +++ b/direct/src/plugin/p3dPythonRun.h @@ -74,6 +74,7 @@ public: bool run_python(); + void set_window_open(P3DCInstance *inst, bool is_open); void request_keyboard_focus(P3DCInstance *inst); private: @@ -120,12 +121,15 @@ private: P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst, const WindowHandle ©); - protected: + public: + virtual void attach_child(WindowHandle *child); + virtual void detach_child(WindowHandle *child); virtual void request_keyboard_focus(WindowHandle *child); private: P3DPythonRun *_p3dpython; P3DCInstance *_inst; + int _child_count; public: static TypeHandle get_class_type() {