Client LuaCsForBarotrauma
VideoPlayer.cs
1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
3 using System;
4 using System.Xml.Linq;
5 using Barotrauma.Media;
6 using Barotrauma.IO;
7 using Microsoft.Xna.Framework.Input;
8 
9 namespace Barotrauma
10 {
12  {
13  public bool IsPlaying;
14 
15  private Video currentVideo;
16  private string filePath;
17 
18  private GUIFrame background, videoFrame, textFrame;
19  private GUITextBlock title, textContent, objectiveTitle, objectiveText;
20  private GUICustomComponent videoView;
21  private GUIButton okButton;
22 
23  private Color backgroundColor = new Color(0f, 0f, 0f, 0.8f);
24  private Action callbackOnStop;
25 
26  private Point scaledVideoResolution;
27  private readonly int borderSize = 20;
28  private readonly Point buttonSize = new Point(120, 30);
29  private readonly int titleHeight = 30;
30  private readonly int objectiveFrameHeight = 60;
31  private readonly int textHeight = 25;
32 
33  private bool useTextOnRightSide = false;
34 
35  public class TextSettings
36  {
38  public int Width;
39 
40  public TextSettings(Identifier textTag, int width)
41  {
42  Text = TextManager.GetFormatted(textTag);
43  Width = width;
44  }
45 
46  public TextSettings(XElement element)
47  {
48  Text = TextManager.GetFormatted(element.GetAttributeIdentifier("text", Identifier.Empty));
49  Width = element.GetAttributeInt("width", 450);
50  }
51  }
52 
53  public class VideoSettings
54  {
55  public readonly string File;
56 
57  public VideoSettings(string file)
58  {
59  File = file;
60  }
61  }
62 
63  public VideoPlayer() // GUI elements with size set to Point.Zero are resized based on content
64  {
65  int screenWidth = (int)(GameMain.GraphicsWidth * 0.65f);
66  scaledVideoResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f));
67 
68  int width = scaledVideoResolution.X;
69  int height = scaledVideoResolution.Y;
70 
71  background = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas, Anchor.Center), style: null, color: backgroundColor);
72  videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center), style: "InnerFrame");
73 
74  if (useTextOnRightSide)
75  {
76  textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.CenterLeft, Pivot.CenterLeft), "TextFrame");
77  }
78  else
79  {
80  textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), "TextFrame");
81  }
82 
83  videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); });
84  title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUIStyle.LargeFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left);
85 
86  textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUIStyle.Font, textAlignment: Alignment.TopLeft);
87 
88  objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight, textColor: Color.White);
89  objectiveTitle.Text = TextManager.Get("Tutorial.NewObjective");
90  objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUIStyle.SubHeadingFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight);
91 
92  objectiveTitle.Visible = objectiveText.Visible = false;
93  }
94 
95  public void Play()
96  {
97  IsPlaying = true;
98  }
99 
100  public void Stop()
101  {
102  IsPlaying = false;
103  if (currentVideo == null) return;
104  currentVideo.Dispose();
105  currentVideo = null;
106  }
107 
108  private bool DisposeVideo(GUIButton button, object userData)
109  {
110  Stop();
111  callbackOnStop?.Invoke();
112  return true;
113  }
114 
115  public void Update()
116  {
117  if (currentVideo == null) return;
118  if (currentVideo.IsPlaying) return;
119 
120  currentVideo.Play();
121  }
122 
123  public void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0)
124  {
125  if (!IsPlaying) return;
126  background.AddToGUIUpdateList(ignoreChildren, order);
127  }
128 
129  public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback)
130  {
131  LoadContent(contentPath, videoSettings, textSettings, contentId, startPlayback, LocalizedString.EmptyString, null);
132  }
133 
134  public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback, LocalizedString objective, Action onStop = null)
135  {
136  callbackOnStop = onStop;
137  filePath = contentPath + videoSettings.File;
138 
139  if (!File.Exists(filePath))
140  {
141  DebugConsole.ThrowError("No video found at: " + filePath);
142  DisposeVideo(null, null);
143  return;
144  }
145 
146  if (currentVideo != null)
147  {
148  currentVideo.Dispose();
149  currentVideo = null;
150  }
151 
152  currentVideo = CreateVideo();
153  title.Text = textSettings != null ? TextManager.Get(contentId) : string.Empty;
154  textContent.Text = textSettings != null ? textSettings.Text : string.Empty;
155  objectiveText.Text = objective;
156 
157  AdjustFrames(videoSettings, textSettings);
158 
159  if (startPlayback) Play();
160  }
161 
162  private void AdjustFrames(VideoSettings videoSettings, TextSettings textSettings)
163  {
164  int screenWidth = (int)(GameMain.GraphicsWidth * 0.55f);
165  scaledVideoResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f));
166 
167  background.RectTransform.NonScaledSize = Point.Zero;
168  videoFrame.RectTransform.NonScaledSize = Point.Zero;
169  videoView.RectTransform.NonScaledSize = Point.Zero;
170 
171  title.RectTransform.NonScaledSize = Point.Zero;
172  textFrame.RectTransform.NonScaledSize = Point.Zero;
173  textContent.RectTransform.NonScaledSize = Point.Zero;
174 
175  objectiveText.RectTransform.NonScaledSize = Point.Zero;
176 
177  title.TextScale = textContent.TextScale = objectiveText.TextScale = objectiveTitle.TextScale = GUI.Scale;
178 
179  int scaledBorderSize = (int)(borderSize * GUI.Scale);
180  int scaledTextWidth = 0;
181  if (textSettings != null) scaledTextWidth = useTextOnRightSide ? (int)(textSettings.Width * GUI.Scale) : scaledVideoResolution.X / 2;
182  int scaledTitleHeight = (int)(titleHeight * GUI.Scale);
183  int scaledTextHeight = (int)(textHeight * GUI.Scale);
184  int scaledObjectiveFrameHeight = (int)(objectiveFrameHeight * GUI.Scale);
185 
186  Point scaledButtonSize = new Point((int)(buttonSize.X * GUI.Scale), (int)(buttonSize.Y * GUI.Scale));
187 
189 
190  videoFrame.RectTransform.NonScaledSize = scaledVideoResolution + new Point(scaledBorderSize, scaledBorderSize);
191  videoView.RectTransform.NonScaledSize = scaledVideoResolution;
192  videoFrame.RectTransform.AbsoluteOffset = new Point(0, videoFrame.RectTransform.NonScaledSize.Y);
193 
194  title.RectTransform.NonScaledSize = new Point(scaledTextWidth, scaledTitleHeight);
195  title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
196 
197  if (textSettings != null && !textSettings.Text.IsNullOrEmpty())
198  {
199  textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUIStyle.Font);
200  int wrappedHeight = textSettings.Text.Value.Split('\n').Length * scaledTextHeight;
201 
202  textFrame.RectTransform.NonScaledSize = new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
203 
204  if (useTextOnRightSide)
205  {
206  textFrame.RectTransform.AbsoluteOffset = new Point(scaledVideoResolution.X + scaledBorderSize * 2, 0);
207  }
208  else
209  {
210  textFrame.RectTransform.AbsoluteOffset = new Point(0, scaledVideoResolution.Y + scaledBorderSize * 2);
211  }
212 
213  textContent.RectTransform.NonScaledSize = new Point(scaledTextWidth, wrappedHeight);
214  textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight);
215  }
216 
217  if (!objectiveText.Text.IsNullOrEmpty())
218  {
219  int scaledXOffset = (int)(-10 * GUI.Scale);
220 
221  objectiveTitle.RectTransform.AbsoluteOffset = new Point(scaledXOffset, textContent.RectTransform.Rect.Height + (int)(scaledTextHeight * 1.95f));
222  objectiveText.RectTransform.AbsoluteOffset = new Point(scaledXOffset, textContent.RectTransform.Rect.Height + objectiveTitle.Rect.Height + (int)(scaledTextHeight * 2.25f));
223 
224  textFrame.RectTransform.NonScaledSize += new Point(0, scaledObjectiveFrameHeight);
225  objectiveText.RectTransform.NonScaledSize = new Point(textFrame.Rect.Width, scaledTextHeight);
226  objectiveTitle.Visible = objectiveText.Visible = true;
227  }
228  else
229  {
230  textFrame.RectTransform.NonScaledSize += new Point(0, scaledBorderSize);
231  objectiveTitle.Visible = objectiveText.Visible = false;
232  }
233 
234  if (okButton != null)
235  {
236  textFrame.RemoveChild(okButton);
237  okButton = null;
238  }
239 
240  if (textSettings != null)
241  {
242  if (useTextOnRightSide)
243  {
244  int totalFrameWidth = videoFrame.Rect.Width + textFrame.Rect.Width + scaledBorderSize * 2;
245  int xOffset = videoFrame.Rect.Width / 2 + scaledBorderSize - (videoFrame.Rect.Width / 2 - textFrame.Rect.Width / 2);
246  videoFrame.RectTransform.AbsoluteOffset = new Point(-xOffset, (int)(50 * GUI.Scale));
247  }
248  else
249  {
250  int totalFrameHeight = videoFrame.Rect.Height + textFrame.Rect.Height + scaledBorderSize * 2;
251  int yOffset = videoFrame.Rect.Height / 2 + scaledBorderSize - (videoFrame.Rect.Height / 2 - textFrame.Rect.Height / 2);
252  videoFrame.RectTransform.AbsoluteOffset = new Point(0, -yOffset);
253  }
254 
255  okButton = new GUIButton(new RectTransform(scaledButtonSize, textFrame.RectTransform, Anchor.BottomRight, Pivot.BottomRight) { AbsoluteOffset = new Point(scaledBorderSize, scaledBorderSize) }, TextManager.Get("OK"))
256  {
257  OnClicked = DisposeVideo
258  };
259  }
260  else
261  {
262  videoFrame.RectTransform.AbsoluteOffset = new Point(0, 0);
263 
264  okButton = new GUIButton(new RectTransform(scaledButtonSize, videoFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(scaledBorderSize, scaledBorderSize) }, TextManager.Get("Back"))
265  {
266  OnClicked = DisposeVideo
267  };
268  }
269  }
270 
271  private Video CreateVideo()
272  {
273  Video video = null;
274 
275  try
276  {
277  video = Video.Load(GameMain.Instance.GraphicsDevice, GameMain.SoundManager, filePath);
278  }
279  catch (Exception e)
280  {
281  DebugConsole.ThrowError("Error loading video content " + filePath + "!", e);
282  }
283 
284  return video;
285  }
286 
287  private void DrawVideo(SpriteBatch spriteBatch, Rectangle rect)
288  {
289  if (!IsPlaying) return;
290  spriteBatch.Draw(currentVideo.GetTexture(), rect, Color.White);
291  }
292 
293  public void Remove()
294  {
295  if (currentVideo != null)
296  {
297  currentVideo.Dispose();
298  currentVideo = null;
299  }
300  }
301  }
302 }
virtual void RemoveChild(GUIComponent child)
Definition: GUIComponent.cs:87
virtual void AddToGUIUpdateList(bool ignoreChildren=false, int order=0)
virtual Rectangle Rect
RectTransform RectTransform
GUIComponent that can be used to render custom content on the UI
static int GraphicsWidth
Definition: GameMain.cs:162
static int GraphicsHeight
Definition: GameMain.cs:168
static readonly RawLString EmptyString
static Video Load(GraphicsDevice graphicsDevice, SoundManager soundManager, string filename)
Definition: Video.cs:72
Texture2D GetTexture()
Definition: Video.cs:147
Point AbsoluteOffset
Absolute in pixels but relative to the anchor point. Calculated away from the anchor point,...
Point NonScaledSize
Size before scale multiplications.
TextSettings(Identifier textTag, int width)
Definition: VideoPlayer.cs:40
void AddToGUIUpdateList(bool ignoreChildren=false, int order=0)
Definition: VideoPlayer.cs:123
void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback)
Definition: VideoPlayer.cs:129
void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback, LocalizedString objective, Action onStop=null)
Definition: VideoPlayer.cs:134