source: 2013/30/MiskaK/MW2(My Warfare 2)/Paranneltu Jypeli/Widgets/MessageDisplay.cs @ 4507

Revision 4507, 8.6 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
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: Tero Jäntti, Tomi Karppinen, Janne Nikkanen.
28 */
29
30using System;
31using System.ComponentModel;
32using System.Collections.Generic;
33using Microsoft.Xna.Framework.Graphics;
34using Microsoft.Xna.Framework;
35
36using XnaRect = Microsoft.Xna.Framework.Rectangle;
37using XnaColor = Microsoft.Xna.Framework.Color;
38
39namespace Jypeli.Widgets
40{
41    public class MessageDisplay : Widget
42    {
43        private struct Message
44        {
45            public String Text;
46            public Color Color;
47            public TimeSpan Expires;
48
49            public bool Expired
50            {
51                get { return Expires < Game.Time.SinceStartOfGame; }
52            }
53
54            public TimeSpan TimeLeft
55            {
56                get { return Expired ? TimeSpan.Zero : Expires - Game.Time.SinceStartOfGame; }
57            }
58
59            public Message( string text, Color color, TimeSpan lifetime )
60            {
61                Text = text;
62                Color = color;
63                Expires = Game.Time.SinceStartOfGame + lifetime;
64            }
65        }
66
67        /// <summary>
68        /// Kuinka monta viestiä kerrallaan näytetään.
69        /// </summary>
70        public int MaxMessageCount { get; set; }
71
72        /// <summary>
73        /// Kuinka pitkään yksi viesti näkyy.
74        /// </summary>
75        public TimeSpan MessageTime { get; set; }
76
77        /// <summary>
78        /// Käytettävä fontti.
79        /// </summary>
80        public Font Font
81        {
82            get { return _font; }
83            set
84            {
85                _font = value;
86                fontHeight = value.XnaFont.MeasureString( "A" ).Y;
87                UpdateTexture();
88            }
89        }
90
91        /// <summary>
92        /// Tekstin väri.
93        /// </summary>
94        public Color TextColor { get; set; }
95
96        /// <summary>
97        /// Tekstin taustaväri.
98        /// </summary>
99        public Color BackgroundColor
100        {
101            get { return bgColor; }
102            set
103            {
104                bgColor = value;
105                UpdateTexture();
106            }
107        }
108
109        /// <summary>
110        /// Onko näyttö reaaliaikainen (oletuksena ei)
111        /// Jos on, vanhin viesti poistetaan heti jos viestien maksimimäärä
112        /// tulee täyteen. Jos ei, viesti jää jonoon odottamaan kunnes
113        /// vanhimman viestin näyttöaika tulee täyteen.
114        /// </summary>
115        public bool RealTime { get; set; }
116
117        private Color bgColor = Color.Transparent;
118        private Image bgImage = null;
119        private Font _font;
120        private float fontHeight;
121        private List<Message> messages = new List<Message>();
122        private Queue<String> unseen = new Queue<string>();
123
124        private Timer removeTimer;
125       
126        /// <summary>
127        /// Luo uuden viestinäytön.
128        /// </summary>
129        /// <param name="font">Fontti.</param>
130        public MessageDisplay()
131            : base( Game.Screen.WidthSafe, Game.Screen.HeightSafe )
132        {
133            removeTimer = new Timer();
134            removeTimer.Timeout += removeMessages;
135
136            TextColor = Color.Black;
137            Color = Color.Transparent;
138
139            MaxMessageCount = 20;
140            MessageTime = TimeSpan.FromSeconds( 5 );
141            Font = Font.Default;
142
143            // default position to top-left-corner
144            this.Position = new Vector( Game.Screen.LeftSafe + Game.Screen.WidthSafe / 2,
145                                        Game.Screen.TopSafe - Game.Screen.HeightSafe / 2 );
146        }
147
148        private void removeMessages()
149        {
150            removeTimer.Stop();
151
152            while ( messages.Count > 0 && messages[0].Expired )
153            {
154                messages.RemoveAt( 0 );
155                if ( unseen.Count > 0 ) Add( unseen.Dequeue() );
156            }
157
158            if ( messages.Count > 0 )
159            {
160                removeTimer.Interval = messages[0].TimeLeft.TotalSeconds;
161                removeTimer.Start();
162            }
163
164            UpdateTexture();
165        }
166       
167        protected override void Draw( Matrix parentTransformation, Matrix transformation )
168        {
169            SpriteBatch spriteBatch = Graphics.SpriteBatch;
170            Matrix m =
171                Matrix.CreateTranslation( (float)Position.X, (float)Position.Y, 0 )
172                * parentTransformation;
173
174            spriteBatch.Begin( SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise, null, m );
175
176            if ( bgImage != null )
177                spriteBatch.Draw( bgImage.XNATexture, Vector2.Zero, XnaColor.White );
178
179            for ( int i = 0; i < messages.Count; i++ )
180            {
181                spriteBatch.DrawString( this.Font.XnaFont, messages[i].Text, new Vector2( 0, i * fontHeight ), messages[i].Color.AsXnaColor() );
182            }
183
184            spriteBatch.End();
185
186            base.Draw( parentTransformation, transformation );
187        }
188
189        private void UpdateTexture()
190        {
191            if ( messages.Count == 0 || bgColor == Color.Transparent )
192            {
193                bgImage = null;
194                return;
195            }
196
197            double maxW = 0;
198
199            for ( int i = 0; i < messages.Count; i++ )
200            {
201                Vector2 dims = Font.XnaFont.MeasureString( messages[i].Text );
202                if ( dims.X > maxW ) maxW = dims.X;
203            }
204
205            bgImage = new Image( maxW, messages.Count * fontHeight, bgColor );
206        }
207
208        /// <summary>
209        /// Lisää uuden viestin näkymään.
210        /// </summary>
211        public void Add( string message )
212        {
213            if ( messages.Count > MaxMessageCount )
214            {
215                if ( RealTime )
216                {
217                    messages.RemoveRange( 0, messages.Count - MaxMessageCount + 1 );
218                }
219                else
220                {
221                    unseen.Enqueue( message );
222                    return;
223                }
224            }
225
226            messages.Add( new Message( message, TextColor, MessageTime ) );
227            UpdateTexture();
228
229            if ( !removeTimer.Enabled )
230            {
231                removeTimer.Interval = MessageTime.TotalSeconds;
232                removeTimer.Start();
233            }
234        }
235
236        /// <summary>
237        /// Lisää uuden viestin näkymään.
238        /// </summary>
239        public void Add( string message, Color color )
240        {
241            if ( messages.Count > MaxMessageCount )
242            {
243                if ( RealTime )
244                {
245                    messages.RemoveRange( 0, messages.Count - MaxMessageCount + 1 );
246                }
247                else
248                {
249                    unseen.Enqueue( message );
250                    return;
251                }
252            }
253
254            messages.Add( new Message( message, color, MessageTime ) );
255            UpdateTexture();
256
257            if ( !removeTimer.Enabled )
258            {
259                removeTimer.Interval = MessageTime.TotalSeconds;
260                removeTimer.Start();
261            }
262        }
263
264        /// <summary>
265        /// Poistaa kaikki lisätyt viestit.
266        /// </summary>
267        public void Clear()
268        {
269            messages.Clear();
270            UpdateTexture();
271        }
272    }
273}
Note: See TracBrowser for help on using the repository browser.