Jypeli  9
The simple game programming library
ListWidget.cs
Siirry tämän tiedoston dokumentaatioon.
1 #region MIT License
2 /*
3  * Copyright (c) 2009-2011 University of Jyväskylä, Department of Mathematical
4  * Information Technology.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #endregion
25 
26 /*
27  * Authors: Tomi Karppinen, Tero Jäntti
28  */
29 
30 using System.ComponentModel;
31 using Microsoft.Xna.Framework;
32 using Jypeli.GameObjects;
33 
34 namespace Jypeli
35 {
36  [EditorBrowsable( EditorBrowsableState.Never )]
37  public class ScrollableList<O> : Widget where O : Widget
38  {
39  public bool IsAtTop
40  {
41  get { return _layout.StartIndex == 0; }
42  }
43 
44  public bool IsAtBottom
45  {
46  get { return _layout.EndIndex == _childObjects.Count; }
47  }
48 
49  public int ItemCount { get { return _childObjects.Count; } }
50 
52 
53  public ScrollableList()
54  : base( new VerticalScrollLayout() )
55  {
56  _layout = (VerticalScrollLayout)Layout;
58  HorizontalSizing = Sizing.Expanding;
59  VerticalSizing = Sizing.Expanding;
60  AddedToGame += AddListeners;
61  }
62 
63  void AddListeners()
64  {
65 #if WINDOWS_PHONE || ANDROID
66  // TODO: gestures
67  //Game.TouchPanel.ListenGestureOn( this, GestureType.VerticalDrag, Scroll, null ).InContext( this );
68 #endif
69  }
70 
71 #if WINDOWS_PHONE || ANDROID
72  const double MaxMoves = 5;
73 
74  double velocity = 0;
75  Queue<double> lastMoves = new Queue<double>();
76 
77  void Scroll( Touch touch )
78  {
79  if ( _childObjects == null || _childObjects.Count == 0 )
80  return;
81 
82  // Works better when divided by 2. Don't know why :)
83  double movement = touch.MovementOnScreen.Y / 2;
84 
85  if ( lastMoves.Count >= MaxMoves )
86  lastMoves.Dequeue();
87  lastMoves.Enqueue( movement );
88 
89  velocity = lastMoves.Average();
90 
91  List<GameObject> widgets = _childObjects.FindAll( o => o is Widget );
92  _layout.Scroll( widgets, movement );
93  }
94 
95  public override void Update( Time time )
96  {
97  if ( Math.Abs( velocity ) > float.Epsilon && _childObjects != null && _childObjects.Count > 0 )
98  {
99  List<GameObject> widgets = _childObjects.FindAll( o => o is Widget );
100  _layout.Scroll( widgets, velocity );
101  }
102 
103  velocity *= 0.98;
104  base.Update( time );
105  }
106 #endif
107 
108  public void ScrollUp()
109  {
110  _layout.ScrollUp( Objects.items );
111  }
112 
113  public void ScrollDown()
114  {
115  _layout.ScrollDown( Objects.items );
116  }
117 
118  public override void Clear()
119  {
120  _layout.StartIndex = 0;
121  _layout.EndIndex = 0;
122  base.Clear();
123  }
124 
125  public O this[int index]
126  {
127  get { return (O)_childObjects[index]; }
128  set { _childObjects[index] = value; }
129  }
130 
131  protected internal override void DrawChildObjects( ref Matrix parentTransformation, ref Matrix transformation, ref Matrix childTransformation )
132  {
133  Renderer.BeginDrawingInsideShape( Shape, ref transformation );
134  for ( int i = _layout.StartIndex; i < _layout.EndIndex; i++ )
135  {
136  ( (Widget)Objects[i] ).Draw( childTransformation );
137  }
139  }
140  }
141 
142 
152  [EditorBrowsable( EditorBrowsableState.Never )]
153  public abstract class ListWidget<T, O> : Widget
154  where O : Widget
155  {
156 #if WINDOWS
157  static Image upImage = null;
158  static Image downImage = null;
159  static Image transparentImage = null;
160 
161  PushButton scrollUpButton = null;
162  PushButton scrollDownButton = null;
163 #endif
164 
166 
167  internal protected ScrollableList<O> Content;
168 
173  {
174  get { return List; }
175  }
176 
177  public ListWidget( INotifyList<T> list )
178  : base( new HorizontalLayout() )
179  {
180  Add( Content = new ScrollableList<O> { Color = Color.Transparent } );
181 #if WINDOWS
182  Add( CreateVerticalScrollPanel() );
183 #endif
184 
185  Bind( list );
186 
187  AddedToGame += AddListeners;
188  }
189 
193  internal protected abstract O CreateWidget( T item );
194 
195  private void AddListeners()
196  {
197  var l1 = Game.Instance.Keyboard.Listen( Key.Up, ButtonState.Pressed, scrollUp, null ).InContext( this );
198  var l2 = Game.Instance.Keyboard.Listen( Key.Down, ButtonState.Pressed, scrollDown, null ).InContext( this );
199  associatedListeners.AddItems(l1, l2);
200  }
201 
202 #if WINDOWS
203  private Widget CreateVerticalScrollPanel()
204  {
205  Widget scrollPanel = new Widget( new VerticalLayout() ) { Color = Color.Transparent, HorizontalSizing = Sizing.FixedSize };
206 
207  if ( upImage == null )
208  {
209  upImage = Game.LoadImageFromResources( "UpArrow.png" );
210  downImage = Game.LoadImageFromResources( "DownArrow.png" );
211  transparentImage = Image.FromColor( upImage.Width, upImage.Height, Color.Transparent );
212  }
213 
214  scrollUpButton = new PushButton( transparentImage );
215  scrollUpButton.Clicked += scrollUp;
216  scrollPanel.Add( scrollUpButton );
217 
218  scrollPanel.Add( new VerticalSpacer() );
219 
220  scrollDownButton = new PushButton( transparentImage );
221  scrollDownButton.Clicked += scrollDown;
222  scrollPanel.Add( scrollDownButton );
223 
224  return scrollPanel;
225  }
226 #endif
227 
228  protected void Reset()
229  {
230  Content.Clear();
231 
232  foreach ( var item in List )
233  {
234  Content.Add( CreateWidget( item ) );
235  }
236 
237 #if WINDOWS
238  // This is a bit tricky case. Because the clear call above doesn't take
239  // effect immediately, calling UpdateLayout() uses old objects when updating
240  // layout. Thus, let's just wait for at least one update to occur.
241  Game.DoNextUpdate( delegate { if ( !Content.IsAtBottom ) ShowDownButton(); } );
242 #endif
243  }
244 
245 #if WINDOWS
246  private void ShowUpButton()
247  {
248  scrollUpButton.Image = upImage;
249  }
250 #endif
251 
252 #if WINDOWS
253  private void ShowDownButton()
254  {
255  scrollDownButton.Image = downImage;
256  }
257 #endif
258 
259 #if WINDOWS
260  private void Hide(PushButton button)
261  {
262  button.Image = transparentImage;
263  }
264 #endif
265 
266  private void scrollDown()
267  {
268  Content.ScrollDown();
269 
270 #if WINDOWS
271  if ( !Content.IsAtTop )
272  {
273  ShowUpButton();
274  }
275 
276  if ( Content.IsAtBottom )
277  {
278  Hide( scrollDownButton );
279  }
280 #endif
281  }
282 
283  private void scrollUp()
284  {
285  Content.ScrollUp();
286 
287 #if WINDOWS
288  if ( Content.IsAtTop )
289  {
290  Hide( scrollUpButton );
291  }
292 #endif
293  }
294 
295  private void listChanged()
296  {
297  Reset();
298  }
299 
304  public void Bind( INotifyList<T> list )
305  {
306  this.List = list;
307  list.Changed += listChanged;
308  Reset();
309  }
310 
314  public void Unbind()
315  {
316  List.Changed -= listChanged;
317  }
318  }
319 }
Jypeli.ListWidget.ListWidget
ListWidget(INotifyList< T > list)
Definition: ListWidget.cs:177
Jypeli.ListWidget.CreateWidget
abstract O CreateWidget(T item)
Luo annettua alkiota vastaavan listan rivin.
Jypeli.Image.FromColor
static Image FromColor(int imageWidth, int imageHeight, Color color)
Luo yksivärisen kuvan.
Definition: Image.cs:875
Jypeli.ScrollableList.ScrollableList
ScrollableList()
Definition: ListWidget.cs:53
Jypeli.Renderer
Luokka, joka sisältää metodeita kuvioiden ja tekstuurien piirtämiseen 2D-tasossa.
Definition: Renderer.cs:48
Jypeli.Matrix
Microsoft.Xna.Framework.Matrix Matrix
Definition: Mouse.cs:36
Microsoft.Xna
Definition: JypeliContentManager.cs:6
Jypeli.Image.Image
Image(int width, int height)
Definition: Image.cs:388
Jypeli.ListWidget.listChanged
void listChanged()
Definition: ListWidget.cs:295
Jypeli
Definition: Automobile.cs:5
Jypeli.GameObjects.VerticalScrollLayout.ScrollDown
void ScrollDown(IList< GameObject > objects)
Definition: VerticalScrollLayout.cs:133
Jypeli.INotifyList
Lista, joka ilmoittaa muutoksistaan.
Definition: INotifyList.cs:11
Microsoft
Definition: JypeliContentManager.cs:6
Microsoft.Xna.Framework
Definition: JypeliContentManager.cs:6
Jypeli.ScrollableList.Clear
override void Clear()
Definition: ListWidget.cs:118
Jypeli.GameObjects.VerticalScrollLayout
Asettelee widgetit päällekäin, järjestyksessä ylhäältä alas. Jos widgeteille ei ole tarpeeksi tilaa,...
Definition: VerticalScrollLayout.cs:43
Jypeli.Shape
Kuvio.
Definition: Shapes.cs:47
Jypeli.GameObjects.VerticalScrollLayout.Scroll
void Scroll(IList< GameObject > objects, double amount)
Listan portaaton vieritys.
Definition: VerticalScrollLayout.cs:146
Jypeli.ScrollableList
Definition: ListWidget.cs:38
Jypeli.ScrollableList.ScrollDown
void ScrollDown()
Definition: ListWidget.cs:113
Jypeli.ListWidget
Listakomponentti. Voidaan liittää listaan, joka toteuttaa INotifyList-rajapinnan. Tällöin listaan teh...
Definition: ListWidget.cs:155
Jypeli.GameObjects
Definition: GameObjectBase.cs:5
Jypeli.Touch.MovementOnScreen
Vector MovementOnScreen
Kosketuksen liike ruudulla.
Definition: Touch.cs:105
Jypeli.Game.DoNextUpdate
static void DoNextUpdate(Action action)
Suorittaa aliohjelman seuraavalla päivityksellä.
Definition: DelayedActions.cs:65
Jypeli.ListWidget.AddListeners
void AddListeners()
Definition: ListWidget.cs:195
Jypeli.Game.Instance
static Game Instance
Käynnissä olevan pelin pääolio.
Definition: Game.cs:90
Jypeli.Widget
Käyttöliittymän komponentti.
Definition: Appearance.cs:6
Jypeli.Color.Transparent
static readonly Color Transparent
Läpinäkyvä väri.
Definition: Color.cs:878
Jypeli.ListWidget.Reset
void Reset()
Definition: ListWidget.cs:228
Jypeli.ListWidget.Bind
void Bind(INotifyList< T > list)
Sitoo olemassaolevan listan tähän näyttöön. Kun listaa muutetaan, näytetyt arvot päivittyvät automaat...
Definition: ListWidget.cs:304
Jypeli.VerticalLayout
Asettelee widgetit päällekäin, järjestyksessä ylhäältä alas.
Definition: VerticalLayout.cs:39
Jypeli.ListWidget.Items
INotifyList< T > Items
Listan alkiot.
Definition: ListWidget.cs:173
Jypeli.INotifyList.Changed
Action Changed
Tapahtuu kun listan sisältö muuttuu.
Definition: INotifyList.cs:15
Jypeli.PushButton
Painonappi.
Definition: PushButton.cs:40
Jypeli.ScrollableList.ScrollUp
void ScrollUp()
Definition: ListWidget.cs:108
Jypeli.ScrollableList._layout
VerticalScrollLayout _layout
Definition: ListWidget.cs:51
Jypeli.ListWidget.scrollDown
void scrollDown()
Definition: ListWidget.cs:266
Jypeli.Touch
Kosketuspaneelin kosketus.
Definition: Touch.cs:39
Jypeli.ListWidget.Unbind
void Unbind()
Poistaa yhteyden olemassaolevaan listaan.
Definition: ListWidget.cs:314
Jypeli.Color
Väri.
Definition: Color.cs:13
Jypeli.Widget.Widget
Widget(Animation animation)
Alustaa widgetin.
Definition: Widget.cs:14
Jypeli.Renderer.EndDrawingInsideShape
static void EndDrawingInsideShape()
Definition: Renderer.cs:256
Jypeli.Game.Keyboard
Keyboard Keyboard
Näppäimistö.
Definition: Controls.cs:44
Jypeli.Image
Kuva.
Definition: Image.cs:29
Jypeli.ScrollableList.ItemCount
int ItemCount
Definition: ListWidget.cs:49
Jypeli.ScrollableList.AddListeners
void AddListeners()
Definition: ListWidget.cs:63
Jypeli.ButtonState
ButtonState
Napin (minkä tahansa) asento.
Definition: ButtonState.cs:37
System
Definition: CFFauxAttributes.cs:29
Jypeli.ListWidget.scrollUp
void scrollUp()
Definition: ListWidget.cs:283
Jypeli.Widget.associatedListeners
List< Listener > associatedListeners
Tähän listaan lisätyt kuuntelijat tuhotaan automaattisesti kun Widget poistetaan pelistä.
Definition: Control.cs:14
Jypeli.ScrollableList.IsAtBottom
bool IsAtBottom
Definition: ListWidget.cs:45
Jypeli.ListWidget.List
INotifyList< T > List
Definition: ListWidget.cs:165
Jypeli.HorizontalLayout
Asettelee widgetit riviin vaakasuunnassa.
Definition: HorizontalLayout.cs:39
Jypeli.ScrollableList.IsAtTop
bool IsAtTop
Definition: ListWidget.cs:40
Jypeli.Renderer.BeginDrawingInsideShape
static void BeginDrawingInsideShape(Shape shape, ref Matrix transformation)
Makes all the subsequent draw calls until EndDrawingInsideShape limit the drawing inside shape (trans...
Definition: Renderer.cs:238
Jypeli.PushButton.Clicked
Action Clicked
Tapahtuu kun nappia on painettu.
Definition: PushButton.cs:144
Jypeli.GameObjects.VerticalScrollLayout.StartIndex
int StartIndex
Ylhäältä lukien ensimmäisen piirtoalueen sisällä olevan widgetin indeksi.
Definition: VerticalScrollLayout.cs:108
Jypeli.Game
Definition: Content.cs:46
Jypeli.GameObjects.VerticalScrollLayout.EndIndex
int EndIndex
Viimeisen piirtoalueella olevan widgetin jälkeinen indeksi.
Definition: VerticalScrollLayout.cs:113
Jypeli.Key
Key
Näppäimistön näppäin.
Definition: Key.cs:38
Jypeli.ScrollableList.DrawChildObjects
override void DrawChildObjects(ref Matrix parentTransformation, ref Matrix transformation, ref Matrix childTransformation)
Definition: ListWidget.cs:131
Jypeli.Vector.Y
double Y
Definition: Vector.cs:313
Jypeli.ListWidget.Content
ScrollableList< O > Content
Definition: ListWidget.cs:167
Jypeli.Sizing
Sizing
Olion koon asettaminen asettelijan sisällä.
Definition: ILayout.cs:39
Jypeli.GameObjects.VerticalScrollLayout.ScrollUp
void ScrollUp(IList< GameObject > objects)
Definition: VerticalScrollLayout.cs:123
Jypeli.Keyboard.Listen
Listener Listen(Key k, ButtonState state, Action handler, string helpText)
Kuuntelee näppäinten painalluksia.
Definition: Keyboard.cs:161