Browse Source

onwindowattach, onwindowdetach

David Rose 16 years ago
parent
commit
a927aedf52

+ 2 - 1
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)
 

+ 35 - 5
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)) {

+ 0 - 1
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,

+ 61 - 1
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 &copy) :
   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

+ 5 - 1
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 &copy);
 
-  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() {