31 using System.ComponentModel;
32 using System.Collections.Generic;
34 namespace Jypeli.GameObjects
43 internal class VerticalScrollLayout : ILayout
45 private Sizing _horizontalSizing;
46 private Sizing _verticalSizing;
47 private Vector _preferredSize;
48 private double _heightRequestedByExpandingObjects;
49 private double _heightRequestedByFixedSizeObjects;
50 private double _spacing = 0;
51 private double _topPadding = 0;
52 private double _bottomPadding = 0;
53 private double _leftPadding = 0;
54 private double _rightPadding = 0;
55 private double _firstVisibleItemOffset = 0;
58 [EditorBrowsable( EditorBrowsableState.Never )]
59 public GameObject Parent {
get;
set; }
66 get {
return _spacing; }
67 set { _spacing = value; NotifyParent(); }
73 public double TopPadding
75 get {
return _topPadding; }
76 set { _topPadding = value; NotifyParent(); }
82 public double BottomPadding
84 get {
return _bottomPadding; }
85 set { _bottomPadding = value; NotifyParent(); }
91 public double LeftPadding
93 get {
return _leftPadding; }
94 set { _leftPadding = value; NotifyParent(); }
100 public double RightPadding
102 get {
return _rightPadding; }
103 set { _rightPadding = value; NotifyParent(); }
109 public int StartIndex {
get;
set; }
114 public int EndIndex {
get;
set; }
116 private void NotifyParent()
118 if ( Parent != null )
120 Parent.NotifyParentAboutChangedSizingAttributes();
124 public void ScrollUp( IList<GameObject> objects )
126 if ( StartIndex > 0 )
129 _firstVisibleItemOffset = 0;
130 Update( objects, Parent.Size );
134 public void ScrollDown( IList<GameObject> objects )
136 if ( StartIndex < objects.Count - 1 )
139 _firstVisibleItemOffset = 0;
140 Update( objects, Parent.Size );
147 public void Scroll( IList<GameObject> objects,
double amount )
149 if ( objects.Count == 0 )
return;
153 double totalScrollingAmount = -amount;
154 double spaceForCurrentObject = _firstVisibleItemOffset;
156 while ( spaceForCurrentObject < totalScrollingAmount )
158 if ( StartIndex == 0 )
160 spaceForCurrentObject = 0;
164 totalScrollingAmount -= spaceForCurrentObject;
166 spaceForCurrentObject = objects[StartIndex].PreferredSize.Y + Spacing;
169 spaceForCurrentObject -= totalScrollingAmount;
170 _firstVisibleItemOffset = spaceForCurrentObject;
174 double totalScrollingAmount = -amount;
175 double spaceForCurrentObject = objects[StartIndex].PreferredSize.Y + Spacing - _firstVisibleItemOffset;
177 while ( spaceForCurrentObject < -totalScrollingAmount )
179 if ( StartIndex >= objects.Count - 1 )
181 spaceForCurrentObject = 0;
185 totalScrollingAmount += spaceForCurrentObject;
187 spaceForCurrentObject = objects[StartIndex].PreferredSize.Y + Spacing;
190 spaceForCurrentObject += totalScrollingAmount;
191 _firstVisibleItemOffset = objects[StartIndex].PreferredSize.Y + Spacing - spaceForCurrentObject;
194 Update( objects, Parent.Size );
197 [EditorBrowsable( EditorBrowsableState.Never )]
198 public void UpdateSizeHints( IList<GameObject> objects )
200 if ( objects.Count == 0 )
204 double heightOfExpandingObjects = 0;
205 double heightOfFixedSizeObjects = 0;
209 foreach ( var o
in objects )
211 if ( o.PreferredSize.X > maxWidth )
213 maxWidth = o.PreferredSize.X;
216 if ( o.VerticalSizing !=
Sizing.FixedSize )
218 verticalSizing =
Sizing.Expanding;
219 heightOfExpandingObjects += o.PreferredSize.Y;
221 else if ( o.VerticalSizing ==
Sizing.FixedSize )
223 heightOfFixedSizeObjects += o.PreferredSize.Y;
226 if ( o.HorizontalSizing !=
Sizing.FixedSize )
228 horizontalSizing =
Sizing.Expanding;
232 double preferredHeight = TopPadding + heightOfExpandingObjects + heightOfFixedSizeObjects + ( ( objects.Count - 1 ) * Spacing ) + BottomPadding;
233 double preferredWidth = LeftPadding + maxWidth + RightPadding;
235 _horizontalSizing = horizontalSizing;
236 _verticalSizing = verticalSizing;
237 _heightRequestedByExpandingObjects = heightOfExpandingObjects;
238 _heightRequestedByFixedSizeObjects = heightOfFixedSizeObjects;
239 _preferredSize =
new Vector( preferredWidth, preferredHeight );
242 [EditorBrowsable( EditorBrowsableState.Never )]
243 public Sizing HorizontalSizing
245 get {
return _horizontalSizing; }
248 [EditorBrowsable( EditorBrowsableState.Never )]
249 public Sizing VerticalSizing
251 get {
return _verticalSizing; }
254 [EditorBrowsable( EditorBrowsableState.Never )]
255 public Vector PreferredSize
257 get {
return _preferredSize; }
260 [EditorBrowsable( EditorBrowsableState.Never )]
261 public void Update( IList<GameObject> objects, Vector maximumSize )
263 double contentHeight = maximumSize.Y - ( TopPadding + BottomPadding );
264 double contentWidth = maximumSize.X - ( LeftPadding + RightPadding );
265 double contentBottomLimit = -maximumSize.Y / 2 + BottomPadding;
266 double top = maximumSize.Y / 2 - TopPadding;
267 double offset = _firstVisibleItemOffset;
270 while ( ( i < objects.Count ) && ( top >= contentBottomLimit ) )
272 GameObject o = objects[i];
273 double width = o.PreferredSize.X;
274 double height = o.PreferredSize.Y;
276 if ( ( o.PreferredSize.X > contentWidth ) || ( o.HorizontalSizing !=
Sizing.FixedSize ) )
278 width = contentWidth;
281 o.Size =
new Vector( width, height );
282 o.X = ( -maximumSize.X / 2 ) + ( LeftPadding + contentWidth / 2 );
283 o.Y = top - height / 2 + offset;
285 top -= height + Spacing - offset;
Sizing
Olion koon asettaminen asettelijan sisällä.