Browse Source

- Implemented Z-Ordering (Control.UpdateZOrder())
- Implemented Control.UpdatStyles()
- Moved PeekMessageFlags to make them accessible to all drivers
- Fixed XplatUIX11.SetZOrder() bug

svn path=/trunk/mcs/; revision=38753

Peter Dennis Bartok 21 years ago
parent
commit
80fcc1d393

+ 48 - 1
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs

@@ -267,8 +267,10 @@ namespace System.Windows.Forms
 					}
 					value.tab_index = use;
 				}
+
 				list.Add (value);
 				value.Parent = owner;
+				owner.UpdateZOrder();
 			}
 			
 			public virtual void AddRange (Control[] controls)
@@ -340,6 +342,7 @@ namespace System.Windows.Forms
 
 			public virtual void Remove(Control value) {
 				list.Remove(value);
+				owner.UpdateZOrder();
 			}
 
 			public void RemoveAt(int index) {
@@ -348,6 +351,7 @@ namespace System.Windows.Forms
 				}
 
 				list.RemoveAt(index);
+				owner.UpdateZOrder();
 			}
 
 			public void SetChildIndex(Control child, int newIndex) {
@@ -369,6 +373,7 @@ namespace System.Windows.Forms
 				} else {
 					list.Insert(newIndex, child);
 				}
+				owner.UpdateZOrder();
 			}
 			#endregion // ControlCollection Private Instance Methods
 
@@ -1740,7 +1745,18 @@ namespace System.Windows.Forms
 		}
 
 		public Control GetNextControl(Control ctl, bool forward) {
-			return ctl;
+			// If we're not a container we don't play
+			if ( !(this is IContainerControl) || !ctl.GetStyle(ControlStyles.ContainerControl)) {
+				return null;
+			}
+
+			// If ctl is not contained by this, we start at the first child of this
+			if (!this.Contains(ctl)) {
+				ctl = this;
+			}
+
+			// We walk the list of controls, starting at ctl, stepping into children as we encounter them
+			return null;
 		}
 
 		public void Hide() {
@@ -2530,6 +2546,37 @@ namespace System.Windows.Forms
 			this.client_size.Height=clientHeight;
 		}
 
+		protected void UpdateStyles() {
+			if (!IsHandleCreated) {
+				return;
+			}
+
+			XplatUI.SetWindowStyle(window.Handle, CreateParams);
+		}
+
+		protected void UpdateZOrder() {
+			int	children;
+			Control	ctl;
+
+#if not
+			if (parent == null) {
+				return;
+			}
+
+			ctl = parent;
+
+			children = ctl.child_controls.Count;
+			for (int i = 1; i < children; i++ ) {
+				XplatUI.SetZOrder(ctl.child_controls[i].window.Handle, ctl.child_controls[i-1].window.Handle, false, false); 
+			}
+#else
+			children = child_controls.Count;
+			for (int i = 1; i < children; i++ ) {
+				XplatUI.SetZOrder(child_controls[i].window.Handle, child_controls[i-1].window.Handle, false, false); 
+			}
+#endif
+		}
+
 		[MonoTODO]
 		protected virtual void WndProc(ref Message m) {
 #if debug

+ 1 - 1
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ScrollableControl.cs

@@ -186,7 +186,7 @@ namespace System.Windows.Forms {
 
 		#region Public Constructors
 		public ScrollableControl() {
-			base.SetStyle(ControlStyles.ContainerControl, true);
+			SetStyle(ControlStyles.ContainerControl, true);
 			auto_scroll = false;
 			auto_hscroll = false;
 			auto_vscroll = false;

+ 1 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs

@@ -902,6 +902,7 @@ namespace System.Windows.Forms {
 		internal int		y;
 		internal int		width;
 		internal int		height;
+		internal int		border_width;
 		internal IntPtr		sibling;
 		internal StackMode	stack_mode;
 	}	

+ 4 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs

@@ -191,6 +191,10 @@ namespace System.Windows.Forms {
 			driver.SetWindowState(handle, state);
 		}
 
+		internal static void SetWindowStyle(IntPtr handle, CreateParams cp) {
+			driver.SetWindowStyle(handle, cp);
+		}
+
 		internal static void RefreshWindow(IntPtr handle) {
 			driver.RefreshWindow(handle);
 		}

+ 2 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs

@@ -98,6 +98,8 @@ namespace System.Windows.Forms {
 		internal abstract FormWindowState GetWindowState(IntPtr handle);
 		internal abstract void SetWindowState(IntPtr handle, FormWindowState state);
 
+		internal abstract void SetWindowStyle(IntPtr handle, CreateParams cp);
+
 		internal abstract bool GetText(IntPtr handle, out string text);
 		internal abstract bool Text(IntPtr handle, string text);
 		internal abstract bool SetVisible(IntPtr handle, bool visible);

+ 5 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIOSX.cs

@@ -349,6 +349,11 @@ namespace System.Windows.Forms {
 			}
 		}
 
+		internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
+			// Reapply style and exstyle to the window
+			throw new NotImplementedException();
+		}
+
 		internal override void RefreshWindow(IntPtr handle) {
 			HIRect r = new HIRect ();
 			CheckError (HIViewGetFrame (handle, ref r), "HIViewGetFrame ()");

+ 6 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIStructs.cs

@@ -680,5 +680,11 @@ namespace System.Windows.Forms {
 		internal uint		dwContextId;
 		internal POINT		MousePos;
 	}
+
+	internal enum PeekMessageFlags {
+		PM_NOREMOVE			= 0x00000000,
+		PM_REMOVE			= 0x00000001,
+		PM_NOYIELD			= 0x00000002
+	}
 }
 

+ 5 - 6
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs

@@ -163,12 +163,6 @@ namespace System.Windows.Forms {
 			CS_IME				= 0x00010000
 		}
 
-		internal enum PeekMessageFlags {
-			PM_NOREMOVE			= 0x00000000,
-			PM_REMOVE			= 0x00000001,
-			PM_NOYIELD			= 0x00000002
-		}
-
 		internal enum SetWindowPosZOrder {
 			HWND_TOP			= 0,
 			HWND_BOTTOM			= 1,
@@ -576,6 +570,11 @@ namespace System.Windows.Forms {
 			}
 		}
 
+		internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
+			Win32SetWindowLong(handle, WindowLong.GWL_STYLE, (IntPtr)cp.Style);
+			Win32SetWindowLong(handle, WindowLong.GWL_EXSTYLE, (IntPtr)cp.ExStyle);
+		}
+
 		internal override void RefreshWindow(IntPtr handle) {			
 			Win32InvalidateRect(handle, IntPtr.Zero, true);
 			Win32UpdateWindow(handle);

+ 84 - 3
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

@@ -706,6 +706,82 @@ namespace System.Windows.Forms {
 			}
 		}
 
+		internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
+			MotifWmHints		mwmHints;
+			IntPtr[]		atoms;
+			int			atom_count;
+
+			// Set the appropriate window manager hints
+			if (((cp.Style & ((int)WindowStyles.WS_POPUP)) != 0)  && (GetParent(handle) != IntPtr.Zero)) {
+				XSetTransientForHint(DisplayHandle, handle, GetParent(handle));
+			}
+
+			MotifFunctions functions = 0;
+			MotifDecorations decorations = 0;
+			mwmHints = new MotifWmHints();
+			mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
+			mwmHints.functions = (IntPtr)0;
+			mwmHints.decorations = (IntPtr)0;
+				
+			if ((cp.Style & ((int)WindowStyles.WS_CAPTION)) != 0) {
+				functions |= MotifFunctions.Move;
+				decorations |= MotifDecorations.Title | MotifDecorations.Menu;
+			}
+
+			if ((cp.Style & ((int)WindowStyles.WS_THICKFRAME)) != 0) {
+				functions |= MotifFunctions.Move | MotifFunctions.Resize;
+				decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
+			}
+
+			if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
+				functions |= MotifFunctions.Minimize;
+				decorations |= MotifDecorations.Minimize;
+			}
+
+			if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
+				functions |= MotifFunctions.Maximize;
+				decorations |= MotifDecorations.Maximize;
+			}
+
+			if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
+				functions |= MotifFunctions.Close;
+			}
+
+			if ((cp.ExStyle & ((int)WindowStyles.WS_EX_DLGMODALFRAME)) != 0) {
+				decorations |= MotifDecorations.Border;
+			}
+
+			if ((cp.Style & ((int)WindowStyles.WS_DLGFRAME)) != 0) {
+				decorations |= MotifDecorations.Border;
+			}
+
+			if ((cp.Style & ((int)WindowStyles.WS_BORDER)) != 0) {
+				decorations |= MotifDecorations.Border;
+			}
+
+			if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
+				functions = 0;
+				decorations = 0;
+			}
+
+			mwmHints.functions = (IntPtr)functions;
+			mwmHints.decorations = (IntPtr)decorations;
+
+			XChangeProperty(DisplayHandle, handle, mwm_hints, mwm_hints, 32, PropertyMode.Replace, ref mwmHints, 5);
+
+			atoms = new IntPtr[8];
+			atom_count = 0;
+
+			if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
+				atoms[atom_count++] = (IntPtr)wm_state_above;
+				atoms[atom_count++] = (IntPtr)wm_no_taskbar;
+			}
+			// Should we use SendNetWMMessage here?
+			XChangeProperty(DisplayHandle, handle, net_wm_state, atom, 32, PropertyMode.Replace, ref atoms, atom_count);
+
+			XSelectInput(DisplayHandle, handle, SelectInputMask);
+		}
+
 		internal override void RefreshWindow(IntPtr handle) {
 			XEvent	xevent = new XEvent();
 			IntPtr	root;
@@ -887,7 +963,7 @@ namespace System.Windows.Forms {
 
 		internal override void DoEvents () {
 			MSG msg = new MSG ();
-			while (PeekMessage(ref msg, IntPtr.Zero, 0, 0, 0)) {
+			while (PeekMessage(ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
 				if (msg.message == Msg.WM_PAINT) {
 					TranslateMessage (ref msg);
 					DispatchMessage (ref msg);
@@ -895,10 +971,14 @@ namespace System.Windows.Forms {
 			}
 		}
 
-		[MonoTODO("Obey flags; currently we always PM_REMOVE")]
+		[MonoTODO("Implement PM_NOREMOVE flag")]
 		internal override bool PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
 			bool	 pending;
 
+			if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
+				throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet");
+			}
+
 			pending = false;
 			if (message_queue.Count > 0) {
 				pending = true;
@@ -1410,7 +1490,8 @@ namespace System.Windows.Forms {
 
 				values.sibling = AfterhWnd;
 				values.stack_mode = StackMode.Below;
-				XConfigureWindow(DisplayHandle, hWnd, ChangeWindowFlags.CWStackMode, ref values);
+
+				XConfigureWindow(DisplayHandle, hWnd, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
 			} else {
 				XLowerWindow(DisplayHandle, hWnd);
 				return true;