internal bool is_captured; // tracks if the control has captured the mouse
internal bool is_toplevel; // tracks if the control is a toplevel window
internal bool is_recreating; // tracks if the handle for the control is being recreated
+ internal ArrayList children_to_recreate; // keep track of the children which need to be recreated
internal bool causes_validation; // tracks if validation is executed on changes
internal int tab_index; // position in tab order of siblings
internal bool tab_stop = true; // is the control a tab stop?
private Graphics dc_mem; // Graphics context for double buffering
private GraphicsState dc_state; // Pristine graphics context to reset after paint code alters dc_mem
private Bitmap bmp_mem; // Bitmap for double buffering control
- private bool needs_redraw = true;
+ private Region invalid_region;
private ControlBindingsCollection data_bindings;
{
if (impl_list == null)
impl_list = new ArrayList ();
+
+ if (AllContains (control))
+ return;
+
all_controls = null;
impl_list.Add (control);
}
public virtual void Remove(Control value) {
- all_controls = null;
-
owner.PerformLayout(value, "Parent");
owner.OnControlRemoved(new ControlEventArgs(value));
+
+ all_controls = null;
list.Remove(value);
value.ChangeParent(null);
- // Removing this temporarily because we have a bug somewhere else
- // that this exposes
- // value.Hide ();
-
owner.UpdateChildrenZOrder();
}
bmp_mem=null;
}
+ if (invalid_region!=null) {
+ invalid_region.Dispose();
+ invalid_region=null;
+ }
if (this.InvokeRequired) {
if (Application.MessageLoop) {
this.BeginInvokeInternal(new MethodInvoker(DestroyHandle), null, true);
return true;
}
- if (parent != null) {
- return parent.IsRecreating;
- }
-
- return false;
+ return ParentWaitingOnRecreation(this);
}
}
- private bool ParentIsRecreating {
- get {
- if (parent != null) {
- return parent.IsRecreating;
- }
- return false;
+ internal bool ChildNeedsRecreating (Control child)
+ {
+ if (children_to_recreate != null && children_to_recreate.Contains (child))
+ return true;
+ return ParentWaitingOnRecreation (this);
+ }
+
+ internal void RemoveChildFromRecreateList (Control child)
+ {
+ if (children_to_recreate != null)
+ children_to_recreate.Remove (child);
+ }
+
+ private bool ParentWaitingOnRecreation (Control c) {
+ if (parent != null) {
+ return parent.ChildNeedsRecreating (c);
}
+ return false;
}
internal Graphics DeviceContext {
dc_state = dc_mem.Save();
}
+ private void ImageBufferNeedsRedraw () {
+ if (invalid_region != null)
+ invalid_region.Dispose();
+ invalid_region = new Region (ClientRectangle);
+ }
+
private Bitmap ImageBuffer {
get {
if (bmp_mem==null) {
bmp_mem = new Bitmap (width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
dc_mem = Graphics.FromImage (bmp_mem);
- needs_redraw = true;
+ ImageBufferNeedsRedraw ();
}
internal void InvalidateBuffers ()
dc_mem = null;
bmp_mem = null;
- needs_redraw = true;
+ ImageBufferNeedsRedraw ();
}
internal static void SetChildColor(Control parent) {
parent = new_parent;
- if (IsHandleCreated && (new_parent != null) && new_parent.IsHandleCreated) {
- XplatUI.SetParent(Handle, new_parent.Handle);
- }
+ if (IsHandleCreated)
+ XplatUI.SetParent(Handle,
+ (new_parent == null || !new_parent.IsHandleCreated) ? IntPtr.Zero : new_parent.Handle);
OnParentChanged(EventArgs.Empty);
public bool IsHandleCreated {
get {
if ((window != null) && (window.Handle != IntPtr.Zero)) {
- return true;
+ Hwnd hwnd = Hwnd.ObjectFromHandle (window.Handle);
+ if (hwnd != null && !hwnd.zombie)
+ return true;
}
return false;
if (parent!=value) {
if (value==null) {
parent.Controls.Remove(this);
+ parent = null;
return;
}
if (text!=value) {
text=value;
if (IsHandleCreated) {
+ /* we need to call .SetWindowStyle here instead of just .Text
+ because the presence/absence of Text (== "" or not) can cause
+ other window style things to appear/disappear */
+ XplatUI.SetWindowStyle(window.Handle, CreateParams);
XplatUI.Text(Handle, text);
}
OnTextChanged (EventArgs.Empty);
}
public void Update() {
- needs_redraw = true;
if (IsHandleCreated) {
XplatUI.UpdateWindow(window.Handle);
}
is_recreating=true;
if (IsHandleCreated) {
+ children_to_recreate = new ArrayList();
+ children_to_recreate.AddRange (child_controls.GetAllControls ());
DestroyHandle();
// WM_DESTROY will CreateHandle for us
} else {
} else {
CreateHandle();
}
+ if (parent != null)
+ parent.RemoveChildFromRecreateList (this);
}
is_recreating = false;
OnHandleDestroyed(EventArgs.Empty);
window.InvalidateHandle();
- if (ParentIsRecreating) {
+ if (ParentWaitingOnRecreation (this)) {
RecreateHandle();
} else if (is_recreating) {
CreateHandle();
return;
}
- if (!needs_redraw) {
+ if (invalid_region != null && !invalid_region.IsVisible (paint_event.ClipRectangle)) {
// Just blit the previous image
paint_event.Graphics.DrawImage (ImageBuffer, paint_event.ClipRectangle, paint_event.ClipRectangle, GraphicsUnit.Pixel);
XplatUI.PaintEventEnd(Handle, true);
}
Graphics dc = null;
+ Rectangle old_clip_rect = Rectangle.Empty;
if (ThemeEngine.Current.DoubleBufferingSupported) {
if ((control_style & ControlStyles.DoubleBuffer) != 0) {
dc = paint_event.SetGraphics (DeviceContext);
if (ThemeEngine.Current.DoubleBufferingSupported)
if ((control_style & ControlStyles.DoubleBuffer) != 0) {
+ paint_event.SetClipRectangle (old_clip_rect);
dc.DrawImage (ImageBuffer, paint_event.ClipRectangle, paint_event.ClipRectangle, GraphicsUnit.Pixel);
paint_event.SetGraphics (dc);
- needs_redraw = false;
+ invalid_region.Exclude (paint_event.ClipRectangle);
}
XplatUI.PaintEventEnd(Handle, true);
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnInvalidated(InvalidateEventArgs e) {
- needs_redraw = true;
+ // should this block be here? seems like it
+ // would be more at home in
+ // NotifyInvalidated..
+ if (e.InvalidRect == ClientRectangle) {
+ ImageBufferNeedsRedraw ();
+ }
+ else {
+ // we need this Inflate call here so
+ // that the border of the rectangle is
+ // considered Visible (the
+ // invalid_region.IsVisible call) in
+ // the WM_PAINT handling below.
+ invalid_region.Union (Rectangle.Inflate(e.InvalidRect, 1,1));
+ }
if (Invalidated!=null) Invalidated(this, e);
}
}
}
- needs_redraw = true;
-
if (VisibleChanged!=null) VisibleChanged(this, e);
// We need to tell our kids