Sfoglia il codice sorgente

add WindowProperties::set_z_order()

David Rose 22 anni fa
parent
commit
3727394df7

+ 8 - 0
direct/src/showbase/ShowBase.py

@@ -94,6 +94,7 @@ class ShowBase(DirectObject.DirectObject):
         fullscreen = self.config.GetBool('fullscreen', 0)
         undecorated = self.config.GetBool('undecorated', 0)
         cursorHidden = self.config.GetBool('cursor-hidden', 0)
+        zOrder = self.config.GetString('z-order', 'normal')
         windowTitle = self.config.GetString('window-title', 'Panda')
         
         self.defaultWindowProps = WindowProperties()
@@ -104,6 +105,13 @@ class ShowBase(DirectObject.DirectObject):
         self.defaultWindowProps.setFullscreen(fullscreen)
         self.defaultWindowProps.setUndecorated(undecorated)
         self.defaultWindowProps.setCursorHidden(cursorHidden)
+        if zOrder == 'bottom':
+            self.defaultWindowProps.setZOrder(WindowProperties.ZBottom)
+        elif zOrder == 'top':
+            self.defaultWindowProps.setZOrder(WindowProperties.ZTop)
+        elif zOrder != 'normal':
+            self.notify.warning("Unknown z-order: %s" % (zOrder))
+        
         self.defaultWindowProps.setTitle(windowTitle)
 
         # If the aspect ratio is 0 or None, it means to infer the

+ 48 - 0
panda/src/display/windowProperties.I

@@ -561,6 +561,54 @@ clear_cursor_hidden() {
   _flags &= ~F_cursor_hidden;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: WindowProperties::set_z_order
+//       Access: Published
+//  Description: Specifies the relative ordering of the window with
+//               respect to other windows.  If the z_order is Z_top,
+//               the window will always be on top of other windows; if
+//               it is Z_bottom, it will always be below other
+//               windows.  Most windows will want to be Z_normal,
+//               which allows the user to control the order.
+////////////////////////////////////////////////////////////////////
+INLINE void WindowProperties::
+set_z_order(WindowProperties::ZOrder z_order) {
+  _z_order = z_order;
+  _specified |= S_z_order;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: WindowProperties::get_z_order
+//       Access: Published
+//  Description: Returns the window's z_order.
+////////////////////////////////////////////////////////////////////
+INLINE WindowProperties::ZOrder WindowProperties::
+get_z_order() const {
+  return _z_order;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: WindowProperties::has_z_order
+//       Access: Published
+//  Description: Returns true if the window z_order has been specified,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool WindowProperties::
+has_z_order() const {
+  return ((_specified & S_z_order) != 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: WindowProperties::clear_z_order
+//       Access: Published
+//  Description: Removes the z_order specification from the properties.
+////////////////////////////////////////////////////////////////////
+INLINE void WindowProperties::
+clear_z_order() {
+  _specified &= ~S_z_order;
+  _z_order = Z_normal;
+}
+
 INLINE ostream &
 operator << (ostream &out, const WindowProperties &properties) {
   properties.output(out);

+ 19 - 0
panda/src/display/windowProperties.cxx

@@ -42,6 +42,7 @@ operator = (const WindowProperties &copy) {
   _x_size = copy._x_size;
   _y_size = copy._y_size;
   _title = copy._title;
+  _z_order = copy._z_order;
   _flags = copy._flags;
 }
 
@@ -58,6 +59,7 @@ operator == (const WindowProperties &other) const {
           _y_origin == other._y_origin &&
           _x_size == other._x_size &&
           _y_size == other._y_size &&
+          _z_order == other._z_order &&
           _title == other._title);
 }
 
@@ -76,6 +78,7 @@ clear() {
   _x_size = 0;
   _y_size = 0;
   _title = string();
+  _z_order = Z_normal;
   _flags = 0;
 }
 
@@ -118,6 +121,9 @@ add_properties(const WindowProperties &other) {
   if (other.has_cursor_hidden()) {
     set_cursor_hidden(other.get_cursor_hidden());
   }
+  if (other.has_z_order()) {
+    set_z_order(other.get_z_order());
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -159,4 +165,17 @@ output(ostream &out) const {
   if (has_cursor_hidden()) {
     out << (get_cursor_hidden() ? "cursor_hidden " : "!cursor_hidden ");
   }
+  if (has_z_order()) {
+    switch (get_z_order()) {
+    case Z_bottom:
+      out << "Z_bottom ";
+      break;
+    case Z_normal:
+      out << "Z_normal ";
+      break;
+    case Z_top:
+      out << "Z_top ";
+      break;
+    }
+  }
 }

+ 13 - 0
panda/src/display/windowProperties.h

@@ -30,6 +30,12 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA WindowProperties {
 PUBLISHED:
+  enum ZOrder {
+    Z_bottom,
+    Z_normal,
+    Z_top,
+  };
+
   WindowProperties();
   INLINE WindowProperties(const WindowProperties &copy);
   void operator = (const WindowProperties &copy);
@@ -93,6 +99,11 @@ PUBLISHED:
   INLINE bool has_cursor_hidden() const;
   INLINE void clear_cursor_hidden();
 
+  INLINE void set_z_order(ZOrder z_order);
+  INLINE ZOrder get_z_order() const;
+  INLINE bool has_z_order() const;
+  INLINE void clear_z_order();
+
   void add_properties(const WindowProperties &other);
 
   void output(ostream &out) const;
@@ -112,6 +123,7 @@ private:
     S_open             = 0x0080,
     S_cursor_hidden    = 0x0100,
     S_fixed_size       = 0x0200,
+    S_z_order          = 0x0400,
   };
 
   // This bitmask represents the true/false settings for various
@@ -133,6 +145,7 @@ private:
   int _x_size;
   int _y_size;
   string _title;
+  ZOrder _z_order;
   int _flags;
 };
 

+ 14 - 4
panda/src/framework/config_framework.cxx

@@ -24,10 +24,6 @@
 Configure(config_framework);
 NotifyCategoryDef(framework, "");
 
-ConfigureFn(config_framework) {
-  WindowFramework::init_type();
-}
-
 const int win_width = config_framework.GetInt("win-width", 640);
 const int win_height = config_framework.GetInt("win-height", 480);
 const int win_origin_x = config_framework.GetInt("win-origin-x", -1);
@@ -35,6 +31,7 @@ const int win_origin_y = config_framework.GetInt("win-origin-y", -1);
 const bool fullscreen = config_framework.GetBool("fullscreen", false);
 const bool undecorated = config_framework.GetBool("undecorated", false);
 const bool cursor_hidden = config_framework.GetBool("cursor-hidden", false);
+WindowProperties::ZOrder z_order = WindowProperties::Z_normal;
 const string window_title = config_framework.GetString("window-title", "Panda");
 
 const float aspect_ratio = config_framework.GetFloat("aspect-ratio", 0.0f);
@@ -49,3 +46,16 @@ const string record_session = config_framework.GetString("record-session", "");
 const string playback_session = config_framework.GetString("playback-session", "");
 
 
+ConfigureFn(config_framework) {
+  string string_z_order = config_framework.GetString("z-order", "normal");
+  if (string_z_order == "bottom") {
+    z_order = WindowProperties::Z_bottom;
+  } else if (string_z_order == "top") {
+    z_order = WindowProperties::Z_top;
+  } else if (!(string_z_order == "normal")) {
+    framework_cat.warning()
+      << "Unknown z-order: " << string_z_order << "\n";
+  }
+
+  WindowFramework::init_type();
+}

+ 2 - 0
panda/src/framework/config_framework.h

@@ -21,6 +21,7 @@
 
 #include "pandabase.h"
 #include "notifyCategoryProxy.h"
+#include "windowProperties.h"
 
 NotifyCategoryDecl(framework, EXPCL_FRAMEWORK, EXPTP_FRAMEWORK);
 
@@ -32,6 +33,7 @@ extern const int win_origin_y;
 extern const bool fullscreen;
 extern const bool undecorated;
 extern const bool cursor_hidden;
+extern WindowProperties::ZOrder z_order;
 extern const string window_title;
 
 extern const float aspect_ratio;

+ 3 - 0
panda/src/framework/pandaFramework.cxx

@@ -267,6 +267,9 @@ get_default_window_props(WindowProperties &props) {
   props.set_fullscreen(fullscreen);
   props.set_undecorated(undecorated);
   props.set_cursor_hidden(cursor_hidden);
+  if (z_order != WindowProperties::Z_normal) {
+    props.set_z_order(z_order);
+  }
   props.set_title(_window_title);
 }
 

+ 76 - 0
panda/src/windisplay/winGraphicsWindow.cxx

@@ -213,8 +213,17 @@ set_properties_now(WindowProperties &properties) {
 
     properties.clear_cursor_hidden();
   }
+
+  if (properties.has_z_order()) {
+    WindowProperties::ZOrder last_z_order = _properties.get_z_order();
+    _properties.set_z_order(properties.get_z_order());
+    adjust_z_order(last_z_order, properties.get_z_order());
+    
+    properties.clear_z_order();
+  }
 }
 
+
 ////////////////////////////////////////////////////////////////////
 //     Function: WinGraphicsWindow::close_window
 //       Access: Protected, Virtual
@@ -423,6 +432,7 @@ handle_reshape() {
       << "," << properties.get_y_size() << ")\n";
   }
 
+  adjust_z_order();
   system_changed_properties(properties);
 }
 
@@ -663,6 +673,66 @@ open_regular_window() {
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: WinGraphicsWindow::adjust_z_order
+//       Access: Private
+//  Description: Adjusts the Z-order of a window after it has been
+//               moved.
+////////////////////////////////////////////////////////////////////
+void WinGraphicsWindow::
+adjust_z_order() {
+  WindowProperties::ZOrder z_order = _properties.get_z_order();
+  adjust_z_order(z_order, z_order);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: WinGraphicsWindow::adjust_z_order
+//       Access: Private
+//  Description: Adjusts the Z-order of a window after it has been
+//               moved.
+////////////////////////////////////////////////////////////////////
+void WinGraphicsWindow::
+adjust_z_order(WindowProperties::ZOrder last_z_order,
+               WindowProperties::ZOrder this_z_order) {
+  HWND order;
+  bool do_change = false;
+  
+  switch (this_z_order) {
+  case WindowProperties::Z_bottom:
+    order = HWND_BOTTOM;
+    do_change = true;
+    break;
+    
+  case WindowProperties::Z_normal:
+    if ((last_z_order != WindowProperties::Z_normal) &&
+        // If we aren't changing the window order, don't move it to
+        // the top.
+        (last_z_order != WindowProperties::Z_bottom ||
+         _properties.get_foreground())
+        // If the window was previously on the bottom, but it doesn't
+        // have focus now, don't move it to the top; it will get moved
+        // the next time we get focus.
+        ) {
+      order = HWND_TOP;
+      do_change = true;
+    }
+    break;
+    
+  case WindowProperties::Z_top:
+    order = HWND_TOPMOST;
+    do_change = true;
+    break;
+  }
+  if (do_change) {
+    BOOL result = SetWindowPos(_hWnd, order, 0,0,0,0, 
+                               SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
+    if (!result) {
+      windisplay_cat.warning()
+        << "SetWindowPos failed.\n";
+    }
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: WinGraphicsWindow::track_mouse_leaving
 //       Access: Private
@@ -812,6 +882,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
             fullscreen_minimized(properties);
           }
         }
+
+        adjust_z_order();
         system_changed_properties(properties);
         break;
     
@@ -836,6 +908,10 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
       case WM_EXITSIZEMOVE:
         handle_reshape();
         break;
+
+      case WM_WINDOWPOSCHANGED:
+        adjust_z_order();
+        break;
     
       case WM_LBUTTONDOWN:
         button = 0;

+ 4 - 0
panda/src/windisplay/winGraphicsWindow.h

@@ -77,6 +77,10 @@ protected:
 private:
   bool open_fullscreen_window();
   bool open_regular_window();
+  void adjust_z_order();
+  void adjust_z_order(WindowProperties::ZOrder last_z_order,
+                      WindowProperties::ZOrder this_z_order);
+
   void track_mouse_leaving(HWND hwnd);
 
   static void process_1_event();