Jypeli  5
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 System.Collections.Generic;
32 using Microsoft.Xna.Framework;
33 using Jypeli.GameObjects;
34 using Jypeli.WP7;
35 using System;
36 
37 namespace Jypeli.Widgets
38 {
39  [EditorBrowsable( EditorBrowsableState.Never )]
40  public class ScrollableList<O> : Widget where O : Widget
41  {
42  public bool IsAtTop
43  {
44  get { return _layout.StartIndex == 0; }
45  }
46 
47  public bool IsAtBottom
48  {
49  get { return _layout.EndIndex == _childObjects.Count; }
50  }
51 
52  public int ItemCount { get { return _childObjects.Count; } }
53 
54  private VerticalScrollLayout _layout;
55 
56  public ScrollableList()
57  : base( new VerticalScrollLayout() )
58  {
59  _layout = (VerticalScrollLayout)Layout;
61  HorizontalSizing = Sizing.Expanding;
62  VerticalSizing = Sizing.Expanding;
63  AddedToGame += AddListeners;
64  }
65 
66  void AddListeners()
67  {
68 #if WINDOWS_PHONE
69  Game.TouchPanel.ListenGestureOn( this, GestureType.VerticalDrag, Scroll, null ).InContext( this );
70 #endif
71  }
72 
73 #if WINDOWS_PHONE
74  const double MaxMoves = 5;
75 
76  double velocity = 0;
77  Queue<double> lastMoves = new Queue<double>();
78 
79  void Scroll( Touch touch )
80  {
81  if ( _childObjects == null || _childObjects.Count == 0 )
82  return;
83 
84  // Works better when divided by 2. Don't know why :)
85  double movement = touch.MovementOnScreen.Y / 2;
86 
87  if ( lastMoves.Count >= MaxMoves )
88  lastMoves.Dequeue();
89  lastMoves.Enqueue( movement );
90 
91  velocity = lastMoves.Average();
92 
93  List<GameObject> widgets = _childObjects.FindAll( o => o is Widget );
94  _layout.Scroll( widgets, movement );
95  }
96 
97  public override void Update( Time time )
98  {
99  if ( Math.Abs( velocity ) > float.Epsilon && _childObjects != null && _childObjects.Count > 0 )
100  {
101  List<GameObject> widgets = _childObjects.FindAll( o => o is Widget );
102  _layout.Scroll( widgets, velocity );
103  }
104 
105  velocity *= 0.98;
106  base.Update( time );
107  }
108 #endif
109 
110  public void ScrollUp()
111  {
112  _layout.ScrollUp( Objects.items );
113  }
114 
115  public void ScrollDown()
116  {
117  _layout.ScrollDown( Objects.items );
118  }
119 
120  public override void Clear()
121  {
122  _layout.StartIndex = 0;
123  _layout.EndIndex = 0;
124  base.Clear();
125  }
126 
127  public O this[int index]
128  {
129  get { return (O)_childObjects[index]; }
130  set { _childObjects[index] = value; }
131  }
132 
133  protected internal override void DrawChildObjects( ref Matrix parentTransformation, ref Matrix transformation, ref Matrix childTransformation )
134  {
135  Renderer.BeginDrawingInsideShape( Shape, ref transformation );
136  for ( int i = _layout.StartIndex; i < _layout.EndIndex; i++ )
137  {
138  ( (Widget)Objects[i] ).Draw( childTransformation );
139  }
141  }
142  }
143 
144 
154  [EditorBrowsable( EditorBrowsableState.Never )]
155  public abstract class ListWidget<T, O> : Widget
156  where O : Widget
157  {
158 #if WINDOWS
159  static Image upImage = null;
160  static Image downImage = null;
161  static Image transparentImage = null;
162 
163  PushButton scrollUpButton = null;
164  PushButton scrollDownButton = null;
165 #endif
166 
167  private INotifyList<T> List;
168 
169  internal protected ScrollableList<O> Content;
170 
174  public INotifyList<T> Items
175  {
176  get { return List; }
177  }
178 
179  public ListWidget( INotifyList<T> list )
180  : base( new HorizontalLayout() )
181  {
182  Add( Content = new ScrollableList<O> { Color = Color.Transparent } );
183 #if WINDOWS
184  Add( CreateVerticalScrollPanel() );
185 #endif
186 
187  Bind( list );
188 
189  AddedToGame += AddListeners;
190  }
191 
195  internal protected abstract O CreateWidget( T item );
196 
197  private void AddListeners()
198  {
199  Game.Instance.Keyboard.Listen( Key.Up, ButtonState.Pressed, scrollUp, null ).InContext( this );
200  Game.Instance.Keyboard.Listen( Key.Down, ButtonState.Pressed, scrollDown, null ).InContext( this );
201  }
202 
203 #if WINDOWS
204  private Widget CreateVerticalScrollPanel()
205  {
206  Widget scrollPanel = new Widget( new VerticalLayout() ) { Color = Color.Transparent, HorizontalSizing = Sizing.FixedSize };
207 
208  if ( upImage == null )
209  {
210  upImage = Game.LoadImageFromResources( "UpArrow" );
211  downImage = Game.LoadImageFromResources( "DownArrow" );
212  transparentImage = Image.FromColor( upImage.Width, upImage.Height, Color.Transparent );
213  }
214 
215  scrollUpButton = new PushButton( transparentImage );
216  scrollUpButton.Clicked += scrollUp;
217  scrollPanel.Add( scrollUpButton );
218 
219  scrollPanel.Add( new VerticalSpacer() );
220 
221  scrollDownButton = new PushButton( transparentImage );
222  scrollDownButton.Clicked += scrollDown;
223  scrollPanel.Add( scrollDownButton );
224 
225  return scrollPanel;
226  }
227 #endif
228 
229  protected void Reset()
230  {
231  Content.Clear();
232 
233  foreach ( var item in List )
234  {
235  Content.Add( CreateWidget( item ) );
236  }
237 
238 #if WINDOWS
239  // This is a bit tricky case. Because the clear call above doesn't take
240  // effect immediately, calling UpdateLayout() uses old objects when updating
241  // layout. Thus, let's just wait for at least one update to occur.
242  Game.DoNextUpdate( delegate { if ( !Content.IsAtBottom ) ShowDownButton(); } );
243 #endif
244  }
245 
246 #if WINDOWS
247  private void ShowUpButton()
248  {
249  scrollUpButton.Image = upImage;
250  }
251 #endif
252 
253 #if WINDOWS
254  private void ShowDownButton()
255  {
256  scrollDownButton.Image = downImage;
257  }
258 #endif
259 
260 #if WINDOWS
261  private void Hide(PushButton button)
262  {
263  button.Image = transparentImage;
264  }
265 #endif
266 
267  private void scrollDown()
268  {
269  Content.ScrollDown();
270 
271 #if WINDOWS
272  if ( !Content.IsAtTop )
273  {
274  ShowUpButton();
275  }
276 
277  if ( Content.IsAtBottom )
278  {
279  Hide( scrollDownButton );
280  }
281 #endif
282  }
283 
284  private void scrollUp()
285  {
286  Content.ScrollUp();
287 
288 #if WINDOWS
289  if ( Content.IsAtTop )
290  {
291  Hide( scrollUpButton );
292  }
293 #endif
294  }
295 
296  private void listChanged()
297  {
298  Reset();
299  }
300 
305  public void Bind( INotifyList<T> list )
306  {
307  this.List = list;
308  list.Changed += listChanged;
309  Reset();
310  }
311 
315  public void Unbind()
316  {
317  List.Changed -= listChanged;
318  }
319  }
320 }
static Image LoadImageFromResources(string name)
Definition: Game.cs:1613
static void DoNextUpdate(Action action)
Suorittaa aliohjelman seuraavalla päivityksellä.
Definition: Game.cs:642
Kuvio.
Definition: Shapes.cs:48
static Image FromColor(int imageWidth, int imageHeight, Color color)
Luo yksivärisen kuvan.
Definition: Image.cs:778
Listakomponentti. Voidaan liittää listaan, joka toteuttaa INotifyList-rajapinnan. Tällöin listaan teh...
Definition: ListWidget.cs:155
Kosketuspaneelin kosketus.
Definition: Touch.cs:16
Sizing
Olion koon asettaminen asettelijan sisällä.
Definition: ILayout.cs:38
Image Image
Olion kuva. Voi olla null, jolloin piirretään vain väri.
ButtonState
Napin (minkä tahansa) asento.
Definition: ButtonState.cs:37
Asettelee widgetit riviin vaakasuunnassa.
static Game Instance
Definition: Game.cs:149
void Unbind()
Poistaa yhteyden olemassaolevaan listaan.
Definition: ListWidget.cs:315
Käyttöliittymän komponentti.
Definition: Appearance.cs:9
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:13
Kuva.
Definition: Image.cs:24
static void EndDrawingInsideShape()
Definition: Renderer.cs:257
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:305
static readonly Color Transparent
Läpinäkyvä väri.
Definition: Color.cs:869
double Y
Definition: Vector.cs:275
ListWidget(INotifyList< T > list)
Definition: ListWidget.cs:179
Peliluokka reaaliaikaisille peleille.
Definition: DebugScreen.cs:10
Asettelee widgetit päällekäin, järjestyksessä ylhäältä alas.
Listener ListenGestureOn(GameObject o, GestureType type, TouchHandler handler, string helpText)
Definition: TouchPanel.cs:320
GestureType
Kosketuseleen tyyppi.
Definition: GestureType.cs:10
Keyboard Keyboard
Näppäimistö.
Definition: Game.cs:248
Action Changed
Tapahtuu kun listan sisältö muuttuu.
Definition: INotifyList.cs:17
TouchPanel TouchPanel
Kosketusnäyttö. Vain kännykässä.
Definition: Game.cs:258
Väri.
Definition: Color.cs:13
void Add(IGameObject childObject)
Lisää annetun peliolion tämän olion lapseksi. Lapsiolio liikkuu tämän olion mukana, ja sen paikka ja koko ilmaistaan suhteessa tähän olioon.
Luokka, joka sisältää metodeita kuvioiden ja tekstuurien piirtämiseen 2D-tasossa. ...
Definition: Renderer.cs:51
Vector MovementOnScreen
Kosketuksen liike ruudulla.
Definition: Touch.cs:53
Key
Näppäimistön näppäin.
Definition: Key.cs:37
ScrollableList< O > Content
Definition: ListWidget.cs:169
override void Clear()
Poistaa kaikki lapsioliot.
Definition: ListWidget.cs:120
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:239
Action Clicked
Tapahtuu kun nappia on painettu.
Definition: PushButton.cs:145
Lista, joka ilmoittaa muutoksistaan.
Definition: INotifyList.cs:12