internal bool is_visible; // true if control is visible
internal bool is_entered; // is the mouse inside the control?
internal bool is_enabled; // true if control is enabled (usable/not grayed out)
- internal bool is_selected; // true if control is selected
internal bool is_accessible; // true if the control is visible to accessibility applications
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?
internal int dist_bottom; // distance to the bottom border of the parent
// to be categorized...
- static internal ArrayList controls = new ArrayList(); // All of the application's controls, in a flat list
+ static internal ArrayList controls = new ArrayList(); // All of the application's controls, in a flat list
internal ControlCollection child_controls; // our children
internal Control parent; // our parent control
internal AccessibleObject accessibility_object; // object that contains accessibility information about our control
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;
internal bool use_compatible_text_rendering;
static internal bool verify_thread_handle;
private Padding padding;
+ private Size maximum_size;
+ private Size minimum_size;
+ private Size preferred_size;
+ private Padding margin;
+ internal Layout.LayoutEngine layout_engine;
#endif
#endregion // Local Variables
{
if (impl_list == null)
impl_list = new ArrayList ();
+
+ if (AllContains (control))
+ return;
+
all_controls = null;
impl_list.Add (control);
// MS sends remove events in reverse order
while (list.Count > 0) {
- RemoveAt(list.Count - 1);
+ Remove((Control)list[list.Count - 1]);
}
}
if (all_controls != null)
return all_controls;
- if (impl_list == null)
- return (Control []) list.ToArray (typeof (Control));
+ if (impl_list == null) {
+ all_controls = (Control []) list.ToArray (typeof (Control));
+ return all_controls;
+ }
- Control [] res = new Control [list.Count + impl_list.Count];
- impl_list.CopyTo (res);
- list.CopyTo (res, impl_list.Count);
+ all_controls = new Control [list.Count + impl_list.Count];
+ impl_list.CopyTo (all_controls);
+ list.CopyTo (all_controls, impl_list.Count);
- return res;
+ return all_controls;
}
public override int GetHashCode() {
}
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);
return;
}
+ all_controls = null;
list.RemoveAt(old_index);
if (newIndex>list.Count) {
throw new ArgumentException("Object of type Control required", "value");
}
- list[index]=(Control)value;
+ all_controls = null;
+ Control ctrl = (Control) value;
+ list[index]= ctrl;
+
+ ctrl.ChangeParent(owner);
+
+ ctrl.InitLayout();
+
+ owner.UpdateChildrenZOrder();
+ owner.PerformLayout(ctrl, "Parent");
}
}
#if NET_2_0
use_compatible_text_rendering = Application.use_compatible_text_rendering;
padding = new Padding(0);
+ maximum_size = new Size();
+ minimum_size = new Size();
+ preferred_size = new Size();
+ margin = this.DefaultMargin;
+ layout_engine = new Layout.DefaultLayout();
#endif
control_style = ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint |
bounds.Y=top;
bounds.Width=width;
bounds.Height=height;
- SetBoundsCore(left, top, width, height, BoundsSpecified.All);
+ SetBounds(left, top, width, height, BoundsSpecified.All);
Text=text;
}
bounds.Y=top;
bounds.Width=width;
bounds.Height=height;
- SetBoundsCore(left, top, width, height, BoundsSpecified.All);
+ SetBounds(left, top, width, height, BoundsSpecified.All);
Text=text;
}
protected override void Dispose(bool disposing) {
if (disposing) {
+ Capture = false;
+
if (dc_mem!=null) {
dc_mem.Dispose();
dc_mem=null;
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);
}
} else {
DestroyHandle();
- controls.Remove(this);
+ lock (Control.controls) {
+ Control.controls.Remove(this);
+ }
}
}
}
is_disposed = true;
+ is_visible = false;
base.Dispose(disposing);
}
#endregion // Public Constructors
result = new AsyncMethodResult ();
data = new AsyncMethodData ();
+ data.Handle = window.Handle;
data.Method = method;
data.Args = args;
data.Result = result;
XplatUI.ClientToScreen (Handle, ref x, ref y);
}
- private bool IsRecreating {
+ internal bool IsRecreating {
get {
if (is_recreating) {
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) {
}
internal bool Select(Control control) {
- Control parent;
IContainerControl container;
if (control == null) {
return false;
}
- parent = control.parent;
-
- control.is_selected = true;
-
container = GetContainerControl();
if (container != null) {
container.ActiveControl = control;
return true;
}
+ internal void SelectChild (Control control)
+ {
+ if (control.IsHandleCreated)
+ XplatUI.SetFocus (control.window.Handle);
+ }
+
internal virtual void DoDefaultAction() {
// Only here to be overriden by our actual controls; this is needed by the accessibility class
}
}
+ internal void FireEnter ()
+ {
+ OnEnter (EventArgs.Empty);
+ }
+
+ internal void FireLeave ()
+ {
+ OnLeave (EventArgs.Empty);
+ }
+
+ internal void FireValidating (CancelEventArgs ce)
+ {
+ OnValidating (ce);
+ }
+
+ internal void FireValidated ()
+ {
+ OnValidated (EventArgs.Empty);
+ }
+
internal virtual bool ProcessControlMnemonic(char charCode) {
return ProcessMnemonic(charCode);
}
if (start != null) {
found = FindFlatBackward(start.parent, start);
- if (found == null && start.parent != container) {
- return start.parent;
+ if (found == null) {
+ if (start.parent != container) {
+ return start.parent;
+ }
+ } else {
+ return found;
}
}
if (found == null) {
found = FindFlatBackward(container, start);
}
- while ((found != null) && ((found is IContainerControl) || found.GetStyle(ControlStyles.ContainerControl))) {
- found = FindControlBackward(found, null);
- if (found != null) {
- return found;
+ if (container != start) {
+ while ((found != null) && (!found.Contains(start)) && ((found is IContainerControl) || found.GetStyle(ControlStyles.ContainerControl))) {
+ found = FindControlBackward(found, null);
+ if (found != null) {
+ return found;
+ }
}
}
return found;
}
- private void HandleClick(int clicks, MouseEventArgs me) {
+ internal virtual void HandleClick(int clicks, MouseEventArgs me) {
if (GetStyle(ControlStyles.StandardClick)) {
if ((clicks > 1) && GetStyle(ControlStyles.StandardDoubleClick)) {
#if !NET_2_0
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 virtual bool AutoSize {
get {
- Console.Error.WriteLine("Unimplemented: Control::get_AutoSize()");
+ //Console.Error.WriteLine("Unimplemented: Control::get_AutoSize()");
return auto_size;
}
set {
auto_size = value;
}
}
+
+ public virtual Size MaximumSize {
+ get {
+ return maximum_size;
+ }
+ set {
+ maximum_size = value;
+ }
+ }
+
+ public virtual Size MinimumSize {
+ get {
+ return minimum_size;
+ }
+ set {
+ minimum_size = value;
+ }
+ }
#endif // NET_2_0
[DispId(-501)]
throw new ArgumentException("Transparent background colors are not supported on this control");
}
- background_color=value;
- SetChildColor(this);
- OnBackColorChanged(EventArgs.Empty);
- Invalidate();
+ if (background_color != value) {
+ background_color=value;
+ SetChildColor(this);
+ OnBackColorChanged(EventArgs.Empty);
+ Invalidate();
+ }
}
}
}
set {
- SetBoundsCore(value.Left, value.Top, value.Width, value.Height, BoundsSpecified.All);
+ SetBounds(value.Left, value.Top, value.Width, value.Height, BoundsSpecified.All);
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool ContainsFocus {
get {
- if (this.Focused) {
- return true;
- }
+ IntPtr focused_window;
- for (int i=0; i < child_controls.Count; i++) {
- if (child_controls[i].ContainsFocus) {
+ focused_window = XplatUI.GetFocus();
+ if (IsHandleCreated) {
+ if (focused_window == Handle) {
return true;
}
+
+ for (int i=0; i < child_controls.Count; i++) {
+ if (child_controls[i].ContainsFocus) {
+ return true;
+ }
+ }
}
return false;
}
if (parent != null) {
XplatUI.SetCursor(window.Handle, parent.Cursor.handle);
} else {
- XplatUI.SetCursor(window.Handle, Cursors.def.handle);
+ XplatUI.SetCursor(window.Handle, Cursors.Default.handle);
}
}
}
}
set {
- if (is_enabled == value) {
+ if (Enabled == value) {
+ is_enabled = value;
return;
}
- if (IsHandleCreated) {
- if (this is Form) {
- if (((Form)this).context == null) {
- XplatUI.EnableWindow(window.Handle, value);
- }
- } else {
- XplatUI.EnableWindow(window.Handle, value);
- }
- }
is_enabled = value;
- Refresh();
+
+ // FIXME - we need to switch focus to next control if we're disabling the focused control
+
OnEnabledChanged (EventArgs.Empty);
}
}
}
set {
- SetBoundsCore(bounds.X, bounds.Y, bounds.Width, value, BoundsSpecified.Height);
+ SetBounds(bounds.X, bounds.Y, bounds.Width, value, BoundsSpecified.Height);
}
}
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 NET_2_0
+ public virtual Layout.LayoutEngine LayoutEngine {
+ get { return this.layout_engine; }
+ }
+#endif
+
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
}
set {
- SetBoundsCore(value, bounds.Y, bounds.Width, bounds.Height, BoundsSpecified.X);
+ SetBounds(value, bounds.Y, bounds.Width, bounds.Height, BoundsSpecified.X);
}
}
}
set {
- SetBoundsCore(value.X, value.Y, bounds.Width, bounds.Height, BoundsSpecified.Location);
+ SetBounds(value.X, value.Y, bounds.Width, bounds.Height, BoundsSpecified.Location);
}
}
+#if NET_2_0
+ [Localizable (true)]
+ public Padding Margin {
+ get { return this.margin; }
+ set { this.margin = value; }
+ }
+#endif
+
[Browsable(false)]
public string Name {
get {
if (parent!=value) {
if (value==null) {
parent.Controls.Remove(this);
+ parent = null;
return;
}
}
set {
- SetBoundsCore(bounds.X, bounds.Y, value.Width, value.Height, BoundsSpecified.Size);
+ SetBounds(bounds.X, bounds.Y, value.Width, value.Height, BoundsSpecified.Size);
}
}
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);
}
set {
- SetBoundsCore(bounds.X, value, bounds.Width, bounds.Height, BoundsSpecified.Y);
+ SetBounds(bounds.X, value, bounds.Width, bounds.Height, BoundsSpecified.Y);
}
}
}
set {
- SetBoundsCore(bounds.X, bounds.Y, value, bounds.Height, BoundsSpecified.Width);
+ SetBounds(bounds.X, bounds.Y, value, bounds.Height, BoundsSpecified.Width);
}
}
}
}
+#if NET_2_0
+ protected virtual Padding DefaultMargin {
+ get { return new Padding (3); }
+ }
+#endif
+
protected virtual Size DefaultSize {
get {
return new Size(0, 0);
#region Public Static Methods
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static Control FromChildHandle(IntPtr handle) {
- IEnumerator control = Control.controls.GetEnumerator();
-
- while (control.MoveNext()) {
- if (((Control)control.Current).window.Handle == handle) {
- // Found it
- if (((Control)control.Current).Parent != null) {
- return ((Control)control.Current).Parent;
+ lock (Control.controls) {
+ IEnumerator control = Control.controls.GetEnumerator();
+
+ while (control.MoveNext()) {
+ if (((Control)control.Current).window.Handle == handle) {
+ // Found it
+ if (((Control)control.Current).Parent != null) {
+ return ((Control)control.Current).Parent;
+ }
}
}
+ return null;
}
- return null;
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
if (parent != null) {
parent.child_controls.SetChildIndex(this, 0);
parent.Refresh();
+ } else {
+ XplatUI.SetZOrder(Handle, IntPtr.Zero, false, false);
}
}
}
public void CreateControl() {
+ if (is_disposed) {
+ throw new ObjectDisposedException(GetType().FullName.ToString());
+ }
if (is_created) {
return;
}
return null;
}
+ // Special cases
+ if (this == ctl) {
+ if (!forward) {
+ return FindFlatBackward(ctl, null);
+ }
+ } else {
+ if ((parent == null) && (ctl is IContainerControl) && ctl.GetStyle(ControlStyles.ContainerControl)) {
+ if (forward) {
+ return FindFlatForward(this, ctl);
+ } else {
+ return FindFlatBackward(this, ctl);
+ }
+ }
+ }
+
// If ctl is not contained by this, we start at the first child of this
if (!this.Contains(ctl)) {
ctl = null;
return FindControlBackward(this, ctl);
}
+#if NET_2_0
+ public virtual Size GetPreferredSize (Size proposedSize) {
+ return preferred_size;
+ }
+#endif
+
public void Hide() {
this.Visible = false;
}
// Perform all Dock and Anchor calculations
try {
+
+#if NET_2_0
+ this.layout_engine.Layout(this, levent);
+#else
+ // This has been moved to Layout/DefaultLayout.cs for 2.0, please duplicate any changes/fixes there.
Control child;
AnchorStyles anchor;
Rectangle space;
- space= DisplayRectangle;
+ space = DisplayRectangle;
// Deal with docking; go through in reverse, MS docs say that lowest Z-order is closest to edge
Control [] controls = child_controls.GetAllControls ();
for (int i = controls.Length - 1; i >= 0; i--) {
child=controls[i];
- if (child.Visible && (child.Dock == DockStyle.Fill)) {
+ //if (child.Visible && (child.Dock == DockStyle.Fill)) {
+ if (child.Dock == DockStyle.Fill) {
child.SetBounds(space.Left, space.Top, space.Width, space.Height);
}
}
- space=DisplayRectangle;
+ space = DisplayRectangle;
for (int i=0; i < controls.Length; i++) {
int left;
child.SetBounds(left, top, width, height);
}
+#endif
// Let everyone know
OnLayout(levent);
}
public virtual bool PreProcessMessage(ref Message msg) {
+ return InternalPreProcessMessage (ref msg);
+ }
+
+ internal virtual bool InternalPreProcessMessage (ref Message msg) {
Keys key_data;
if ((msg.Msg == (int)Msg.WM_KEYDOWN) || (msg.Msg == (int)Msg.WM_SYSKEYDOWN)) {
if (IsInputChar((char)msg.WParam)) {
return false;
}
+ return ProcessDialogChar((char)msg.WParam);
} else if (msg.Msg == (int)Msg.WM_SYSCHAR) {
- if (IsInputChar((char)msg.WParam)) {
- return false;
- }
return ProcessDialogChar((char)msg.WParam);
}
return false;
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void ResetBackColor() {
- background_color = Color.Empty;
+ BackColor = Color.Empty;
}
[EditorBrowsable(EditorBrowsableState.Never)]
ScaleCore(dx, dy);
}
+#if NET_2_0
+ public void Scale(SizeF factor) {
+ ScaleCore(factor.Width, factor.Height);
+ }
+#endif
+
public void Select() {
Select(false, false);
}
public bool SelectNextControl(Control ctl, bool forward, bool tabStopOnly, bool nested, bool wrap) {
Control c;
-
+
c = ctl;
do {
c = GetNextControl(c, forward);
break;
}
- if (c.CanSelect && ((c.parent == ctl.parent) || nested) && (c.tab_stop || !tabStopOnly)) {
- Select(c);
+ if (c.CanSelect && ((c.parent == this) || nested) && (c.tab_stop || !tabStopOnly)) {
+ c.Select (true, true);
return true;
}
} while (c != ctl); // If we wrap back to ourselves we stop
}
public void SetBounds(int x, int y, int width, int height) {
- SetBoundsCore(x, y, width, height, BoundsSpecified.All);
+ SetBounds(x, y, width, height, BoundsSpecified.All);
}
public void SetBounds(int x, int y, int width, int height, BoundsSpecified specified) {
+ if ((specified & BoundsSpecified.X) != BoundsSpecified.X) {
+ x = Left;
+ }
+
+ if ((specified & BoundsSpecified.Y) != BoundsSpecified.Y) {
+ y = Top;
+ }
+
+ if ((specified & BoundsSpecified.Width) != BoundsSpecified.Width) {
+ width = Width;
+ }
+
+ if ((specified & BoundsSpecified.Height) != BoundsSpecified.Height) {
+ height = Height;
+ }
+
SetBoundsCore(x, y, width, height, specified);
+ if (parent != null) {
+ parent.PerformLayout(this, "Bounds");
+ }
}
public void Show() {
}
public void Update() {
- needs_redraw = true;
if (IsHandleCreated) {
XplatUI.UpdateWindow(window.Handle);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void CreateHandle() {
if (IsDisposed) {
- throw new ObjectDisposedException(Name);
+ throw new ObjectDisposedException(GetType().FullName.ToString());
}
if (IsHandleCreated && !is_recreating) {
window.CreateHandle(CreateParams);
if (window.Handle != IntPtr.Zero) {
- if (!controls.Contains(window.Handle)) {
- controls.Add(this);
+ lock (Control.controls) {
+ if (!Control.controls.Contains(window.Handle)) {
+ Control.controls.Add(this);
+ }
}
creator_thread = Thread.CurrentThread;
OnHandleCreated(EventArgs.Empty);
}
-
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
key_press_event = new KeyPressEventArgs((char)msg.WParam);
OnKeyPress(key_press_event);
+#if NET_2_0
+ msg.WParam = (IntPtr)key_press_event.KeyChar;
+#endif
return key_press_event.Handled;
}
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;
size.Height = (int)(size.Height * dy);
}
- SetBoundsCore(location.X, location.Y, size.Width, size.Height, BoundsSpecified.All);
+ SetBounds(location.X, location.Y, size.Width, size.Height, BoundsSpecified.All);
/* Now scale our children */
Control [] controls = child_controls.GetAllControls ();
protected virtual void Select(bool directed, bool forward) {
IContainerControl container;
-
+
container = GetContainerControl();
- if (container != null) {
+ if (container != null)
container.ActiveControl = this;
- }
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
// SetBoundsCore updates the Win32 control itself. UpdateBounds updates the controls variables and fires events, I'm guessing - pdb
- if ((specified & BoundsSpecified.X) != BoundsSpecified.X) {
- x = Left;
- }
-
- if ((specified & BoundsSpecified.Y) != BoundsSpecified.Y) {
- y = Top;
- }
-
- if ((specified & BoundsSpecified.Width) != BoundsSpecified.Width) {
- width = Width;
- }
-
- if ((specified & BoundsSpecified.Height) != BoundsSpecified.Height) {
- height = Height;
- }
-
if (IsHandleCreated) {
XplatUI.SetWindowPos(Handle, x, y, width, height);
}
return;
}
- SetBoundsCore(bounds.X, bounds.Y, WindowRect.Width, WindowRect.Height, BoundsSpecified.Size);
+ SetBounds(bounds.X, bounds.Y, WindowRect.Width, WindowRect.Height, BoundsSpecified.Size);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void SetVisibleCore(bool value) {
if (value!=is_visible) {
- if (value && !is_created) {
+ if (value && (window.Handle == IntPtr.Zero) || !is_created) {
CreateControl();
}
OnVisibleChanged(EventArgs.Empty);
- if (value == false && parent != null) {
+ if (value == false && parent != null && Focused) {
Control container;
// Need to start at parent, GetContainerControl might return ourselves if we're a container
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);
}
case Msg.WM_LBUTTONDOWN: {
- if (CanSelect && !is_selected) {
- Select(this);
+ if (CanSelect) {
+ Select (true, true);
}
InternalCapture = true;
OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
}
case Msg.WM_KILLFOCUS: {
- OnLeave(EventArgs.Empty);
- if (CausesValidation) {
- CancelEventArgs e;
- e = new CancelEventArgs(false);
-
- OnValidating(e);
-
- if (e.Cancel) {
- Focus();
- return;
- }
-
- OnValidated(EventArgs.Empty);
- }
-
this.has_focus = false;
- this.is_selected = false;
- OnLostFocus(EventArgs.Empty);
+ OnLostFocusInternal (EventArgs.Empty);
return;
}
case Msg.WM_SETFOCUS: {
if (!has_focus) {
- OnEnter(EventArgs.Empty);
this.has_focus = true;
- OnGotFocus(EventArgs.Empty);
+ OnGotFocusInternal (EventArgs.Empty);
}
return;
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnEnabledChanged(EventArgs e) {
- if (EnabledChanged!=null) EnabledChanged(this, e);
- for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentEnabledChanged(e);
+ if (IsHandleCreated) {
+ if (this is Form) {
+ if (((Form)this).context == null) {
+ XplatUI.EnableWindow(window.Handle, Enabled);
+ }
+ } else {
+ XplatUI.EnableWindow(window.Handle, Enabled);
+ }
+ Refresh();
+ }
+
+ if (EnabledChanged != null) {
+ EnabledChanged(this, e);
+ }
+
+ for (int i=0; i<child_controls.Count; i++) {
+ child_controls[i].OnParentEnabledChanged(e);
+ }
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
[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);
}
// Override me
}
+ internal virtual void OnGotFocusInternal (EventArgs e)
+ {
+ OnGotFocus (e);
+ }
+
+ internal virtual void OnLostFocusInternal (EventArgs e)
+ {
+ OnLostFocus (e);
+ }
+
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnPaintBackground(PaintEventArgs pevent) {
PaintControlBackground (pevent);
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnParentEnabledChanged(EventArgs e) {
- if (is_enabled != Parent.is_enabled) {
- is_enabled=Parent.is_enabled;
- Invalidate();
- if (EnabledChanged != null) {
- EnabledChanged(this, e);
- }
+ if (is_enabled) {
+ OnEnabledChanged(e);
}
}
}
}
- needs_redraw = true;
-
if (VisibleChanged!=null) VisibleChanged(this, e);
// We need to tell our kids