private SizeGrip sizegrip;
internal ImplicitHScrollBar hscrollbar;
internal ImplicitVScrollBar vscrollbar;
- private Size canvas_size;
+ internal Size canvas_size;
private Rectangle display_rectangle;
private Control old_parent;
[TypeConverter(typeof(ScrollableControl.DockPaddingEdgesConverter))]
#region Subclass DockPaddingEdges
- public class DockPaddingEdges : ICloneable {
+ public class DockPaddingEdges : ICloneable
+ {
+ private Control owner;
+
+#if NET_2_0
+ internal DockPaddingEdges (Control owner)
+ {
+ this.owner = owner;
+ }
+
+ #region DockPaddingEdges Public Instance Properties
+ [RefreshProperties (RefreshProperties.All)]
+ public int All {
+ get { return owner.Padding.All; }
+ set { owner.Padding = new Padding (value); }
+ }
+
+ [RefreshProperties (RefreshProperties.All)]
+ public int Bottom {
+ get { return owner.Padding.Bottom; }
+ set { owner.Padding = new Padding (Left, Top, Right, value); }
+ }
+
+ [RefreshProperties (RefreshProperties.All)]
+ public int Left {
+ get { return owner.Padding.Left; }
+ set { owner.Padding = new Padding (value, Top, Right, Bottom); }
+ }
+
+ [RefreshProperties (RefreshProperties.All)]
+ public int Right {
+ get { return owner.Padding.Right; }
+ set { owner.Padding = new Padding (Left, Top, value, Bottom); }
+ }
+
+ [RefreshProperties (RefreshProperties.All)]
+ public int Top {
+ get { return owner.Padding.Top; }
+ set { owner.Padding = new Padding (Left, value, Right, Bottom); }
+ }
+ #endregion // DockPaddingEdges Public Instance Properties
+
+ // Public Instance Methods
+ public override bool Equals (object other)
+ {
+ if (!(other is DockPaddingEdges)) {
+ return false;
+ }
+
+ if ((this.All == ((DockPaddingEdges)other).All) && (this.Left == ((DockPaddingEdges)other).Left) &&
+ (this.Right == ((DockPaddingEdges)other).Right) && (this.Top == ((DockPaddingEdges)other).Top) &&
+ (this.Bottom == ((DockPaddingEdges)other).Bottom)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return All * Top * Bottom * Right * Left;
+ }
+
+ public override string ToString ()
+ {
+ return "All = " + All.ToString () + " Top = " + Top.ToString () + " Left = " + Left.ToString () + " Bottom = " + Bottom.ToString () + " Right = " + Right.ToString ();
+ }
+
+ internal void Scale (float dx, float dy)
+ {
+ Left = (int)(Left * dx);
+ Right = (int)(Right * dx);
+ Top = (int)(Top * dy);
+ Bottom = (int)(Bottom * dy);
+ }
+
+ object ICloneable.Clone ()
+ {
+ return new DockPaddingEdges (owner);
+ }
+#else
#region DockPaddingEdges Local Variables
private int all;
private int left;
private int right;
private int top;
private int bottom;
- private Control owner;
#endregion // DockPaddingEdges Local Variables
#region DockPaddingEdges Constructor
return padding_edge;
}
+#endif
}
#endregion // Subclass DockPaddingEdges
scroll_position = new Point(0, 0);
dock_padding = new DockPaddingEdges(this);
SizeChanged +=new EventHandler(Recalculate);
- VisibleChanged += new EventHandler(Recalculate);
+ VisibleChanged += new EventHandler (VisibleChangedHandler);
LocationChanged += new EventHandler (LocationChangedHandler);
ParentChanged += new EventHandler (ParentChangedHandler);
HandleCreated += new EventHandler (AddScrollbars);
#endif
}
+ void VisibleChangedHandler (object sender, EventArgs e)
+ {
+ Recalculate (false);
+ }
+
void LocationChangedHandler (object sender, EventArgs e)
{
UpdateSizeGripVisible ();
}
set {
- if (auto_scroll == value) {
- return;
+ if (auto_scroll != value) {
+ auto_scroll = value;
+ PerformLayout (this, "AutoScroll");
}
-
- auto_scroll = value;
}
}
}
}
+ internal bool ShouldSerializeAutoScrollMargin ()
+ {
+ return this.AutoScrollMargin != new Size (0, 0);
+ }
+
[Localizable(true)]
[MWFCategory("Layout")]
public Size AutoScrollMinSize {
if (value != auto_scroll_min_size) {
auto_scroll_min_size = value;
AutoScroll = true;
+ PerformLayout (this, "AutoScrollMinSize");
}
}
}
+ internal bool ShouldSerializeAutoScrollMinSize ()
+ {
+ return this.AutoScrollMinSize != new Size (0, 0);
+ }
+
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Point AutoScrollPosition {
get {
- return new Point(-scroll_position.X, -scroll_position.Y);
+ return DisplayRectangle.Location;
}
set {
- if ((value.X != scroll_position.X) || (value.Y != scroll_position.Y)) {
+ if (value != AutoScrollPosition) {
int shift_x;
int shift_y;
shift_x = 0;
shift_y = 0;
if (hscrollbar.VisibleInternal) {
+ int max = hscrollbar.Maximum - hscrollbar.LargeChange + 1;
+ value.X = value.X < hscrollbar.Minimum ? hscrollbar.Minimum : value.X;
+ value.X = value.X > max ? max : value.X;
shift_x = value.X - scroll_position.X;
}
if (vscrollbar.VisibleInternal) {
+ int max = vscrollbar.Maximum - vscrollbar.LargeChange + 1;
+ value.Y = value.Y < vscrollbar.Minimum ? vscrollbar.Minimum : value.Y;
+ value.Y = value.Y > max ? max : value.Y;
shift_y = value.Y - scroll_position.Y;
}
ScrollWindow(shift_x, shift_y);
if (hscrollbar.VisibleInternal) {
- hscrollbar.Value = scroll_position.X;
+ if (scroll_position.X >= hscrollbar.Minimum && scroll_position.X <= hscrollbar.Maximum)
+ hscrollbar.Value = scroll_position.X;
}
if (vscrollbar.VisibleInternal) {
- vscrollbar.Value = scroll_position.Y;
+ if (scroll_position.Y >= vscrollbar.Minimum && scroll_position.Y <= vscrollbar.Maximum)
+ vscrollbar.Value = scroll_position.Y;
}
}
set {
if (hscrollbar.VisibleInternal != value) {
force_hscroll_visible = value;
- Recalculate(this, EventArgs.Empty);
+ Recalculate (false);
}
}
}
set {
if (vscrollbar.VisibleInternal != value) {
force_vscroll_visible = value;
- Recalculate(this, EventArgs.Empty);
+ Recalculate (false);
}
}
}
}
auto_scroll_margin = new Size(x, y);
- Recalculate(this, EventArgs.Empty);
+ Recalculate (false);
}
#endregion // Public Instance Methods
#region Protected Instance Methods
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void AdjustFormScrollbars(bool displayScrollbars) {
- Recalculate(this, EventArgs.Empty);
+ Recalculate (false);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected override void OnLayout(LayoutEventArgs levent) {
- CalculateCanvasSize();
+ CalculateCanvasSize (true);
AdjustFormScrollbars(AutoScroll); // Dunno what the logic is. Passing AutoScroll seems to match MS behaviour
base.OnLayout(levent);
+
+#if NET_2_0
+ // The first time through, we just set the canvas to clientsize
+ // so we could re-layout everything according to the flow.
+ // This time we want to actually calculate the canvas.
+ if (this is FlowLayoutPanel) {
+ CalculateCanvasSize (false);
+ AdjustFormScrollbars (AutoScroll);
+ }
+#endif
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
base.ScaleCore(dx, dy);
}
+#if NET_2_0
+ protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
+ {
+ base.ScaleControl (factor, specified);
+ }
+
+ protected virtual Point ScrollToControl (Control activeControl)
+ {
+ int corner_x;
+ int corner_y;
+
+ Rectangle within = new Rectangle ();
+ within.Size = ClientSize;
+
+ if (vscrollbar.Visible)
+ within.Width -= vscrollbar.Width;
+
+ if (hscrollbar.Visible)
+ within.Height -= hscrollbar.Height;
+
+ // If the control is above the top or the left, move it down and right until it aligns
+ // with the top/left.
+ // If the control is below the bottom or to the right, move it up/left until it aligns
+ // with the bottom/right, but do never move it further than the top/left side.
+ int x_diff = 0, y_diff = 0;
+
+ if (activeControl.Top <= 0 || activeControl.Height >= within.Height)
+ y_diff = -activeControl.Top;
+ else if (activeControl.Bottom > within.Height)
+ y_diff = within.Height - activeControl.Bottom;
+
+ if (activeControl.Left <= 0 || activeControl.Width >= within.Width)
+ x_diff = -activeControl.Left;
+ else if (activeControl.Right > within.Width)
+ x_diff = within.Width - activeControl.Right;
+
+ corner_x = AutoScrollPosition.X + x_diff;
+ corner_y = AutoScrollPosition.Y + y_diff;
+
+ return new Point (corner_x, corner_y);
+ }
+#endif
+
protected void SetDisplayRectLocation(int x, int y) {
// This method is weird. MS documents that the scrollbars are not
// updated. We need to move stuff, but leave the scrollbars as is
return base.AfterTopMostControl ();
}
- private void CalculateCanvasSize() {
+ internal virtual void CalculateCanvasSize (bool canOverride) {
Control child;
int num_of_children;
int width;
}
private void Recalculate (object sender, EventArgs e) {
+ Recalculate (true);
+ }
+
+ private void Recalculate (bool doLayout) {
if (!IsHandleCreated) {
return;
}
hscrollbar.Value = 0;
}
+ /* Manually setting the size of the thumb should be done before
+ * the other assignments */
if (hscroll_visible) {
- hscrollbar.LargeChange = right_edge;
+ hscrollbar.SetManualLargeChange (right_edge);
hscrollbar.SmallChange = 5;
hscrollbar.Maximum = canvas.Width - 1;
} else {
}
if (vscroll_visible) {
- vscrollbar.LargeChange = bottom_edge;
+ vscrollbar.SetManualLargeChange (bottom_edge);
vscrollbar.SmallChange = 5;
vscrollbar.Maximum = canvas.Height - 1;
} else {
SuspendLayout ();
- hscrollbar.Bounds = hscroll_bounds;
+ hscrollbar.SetBoundsInternal (hscroll_bounds.X, hscroll_bounds.Y, hscroll_bounds.Width, hscroll_bounds.Height, BoundsSpecified.None);
hscrollbar.Visible = hscroll_visible;
if (hscrollbar.Visible)
XplatUI.SetZOrder (hscrollbar.Handle, IntPtr.Zero, true, false);
- vscrollbar.Bounds = vscroll_bounds;
+ vscrollbar.SetBoundsInternal (vscroll_bounds.X, vscroll_bounds.Y, vscroll_bounds.Width, vscroll_bounds.Height, BoundsSpecified.None);
vscrollbar.Visible = vscroll_visible;
if (vscrollbar.Visible)
XplatUI.SetZOrder (vscrollbar.Handle, IntPtr.Zero, true, false);
UpdateSizeGripVisible ();
- ResumeLayout ();
+ ResumeLayout (doLayout);
// We should now scroll the active control into view,
// the funny part is that ScrollableControl does not have
}
}
+#if NET_2_0
+ private void HandleScrollEvent (object sender, ScrollEventArgs args)
+ {
+ OnScroll (args);
+ }
+#endif
+
private void AddScrollbars (object o, EventArgs e)
{
Controls.AddRangeImplicit (new Control[] {hscrollbar, vscrollbar, sizegrip});
hscrollbar.Visible = false;
hscrollbar.ValueChanged += new EventHandler (HandleScrollBar);
hscrollbar.Height = SystemInformation.HorizontalScrollBarHeight;
+ hscrollbar.use_manual_thumb_size = true;
+#if NET_2_0
+ hscrollbar.Scroll += new ScrollEventHandler (HandleScrollEvent);
+#endif
vscrollbar = new ImplicitVScrollBar ();
vscrollbar.Visible = false;
vscrollbar.ValueChanged += new EventHandler (HandleScrollBar);
vscrollbar.Width = SystemInformation.VerticalScrollBarWidth;
+ vscrollbar.use_manual_thumb_size = true;
+#if NET_2_0
+ vscrollbar.Scroll += new ScrollEventHandler (HandleScrollEvent);
+#endif
sizegrip = new SizeGrip (this);
sizegrip.Visible = false;
num_of_children = Controls.Count;
for (int i = 0; i < num_of_children; i++) {
- Controls[i].Left -= XOffset;
- Controls[i].Top -= YOffset;
+ Controls[i].Location = new Point (Controls[i].Left - XOffset, Controls[i].Top - YOffset);
+ //Controls[i].Left -= XOffset;
+ //Controls[i].Top -= YOffset;
// Is this faster? Controls[i].Location -= new Size(XOffset, YOffset);
}
scroll_position.X += XOffset;
scroll_position.Y += YOffset;
- // Should we call XplatUI.ScrollWindow??? If so, we need to position our windows by other means above
- // Since we're already causing a redraw above
- Invalidate(false);
+ XplatUI.ScrollWindow (Handle, ClientRectangle, -XOffset, -YOffset, false);
ResumeLayout(false);
}
#endregion // Internal & Private Methods
protected virtual void OnScroll (ScrollEventArgs se)
{
- EventHandler eh = (EventHandler) (Events [OnScrollEvent]);
+ ScrollEventHandler eh = (ScrollEventHandler) (Events [OnScrollEvent]);
if (eh != null)
eh (this, se);
}
+ protected override void OnPaddingChanged (EventArgs e)
+ {
+ base.OnPaddingChanged (e);
+ }
+
protected override void OnPaintBackground (PaintEventArgs e)
{
base.OnPaintBackground (e);