IMHOTEP Framework
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Pages
PatientBriefing.cs
1 using UnityEngine;
2 using UnityEngine.UI;
3 using UnityEngine.EventSystems;
4 using System;
5 using System.IO;
6 using System.Collections;
7 using System.Collections.Generic;
8 using System.Text.RegularExpressions;
9 using System.ComponentModel;
10 
11 public class PatientBriefing : MonoBehaviour
12 {
13 
14  public GameObject textObj;
15  public GameObject tabButton;
16  public GameObject emptyFiller;
17  public GameObject rawImageObj;
18  public GameObject scrollView;
19  public GameObject viewPort;
20  private Text text;
21 
22  //True if HTML Renderer has finished
23  private bool htmlRendered = false;
24 
25  //Variables for thread
26  string html = "";
27  int imageWidth = 1;
28  int imageHeight = 1;
29  byte[] imageArray;
30 
31  void Update()
32  {
33  if (htmlRendered)
34  {
35  htmlRendered = false;
36 
37  // Create a new texture ARGB32 (32 bit with alpha) and no mipmaps
38  Texture2D texture = new Texture2D(imageWidth, imageHeight, TextureFormat.ARGB32, false);
39  texture.LoadImage(imageArray);
40  texture.Apply();
41  // connect texture to material of GameObject this script is attached to
42  rawImageObj.GetComponent<RawImage>().material.mainTexture = texture;
43 
44  //Resize rect transform component of raw image
45  rawImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(imageWidth, imageHeight);
46  rawImageObj.GetComponent<RectTransform>().anchoredPosition = new Vector2(imageWidth / 2, -imageHeight / 2);
47 
48  textObj.SetActive(false);
49  rawImageObj.SetActive(true);
50  //Set scroll content
51  scrollView.GetComponent<ScrollRect>().content = rawImageObj.GetComponent<RectTransform>();
52  }
53  }
54 
55  // Use this for initialization
56  void OnEnable()
57  {
58  tabButton.SetActive(false);
59  rawImageObj.SetActive(false);
60 
61  text = textObj.GetComponent<Text>();
62  string msg = bold("Patient Information");
63  msg += "\n\nNo patient loaded.";
64  text.text = msg;
65 
66  PatientEventSystem.startListening(PatientEventSystem.Event.PATIENT_Loaded, eventNewPatientLoaded);
67  PatientEventSystem.startListening(PatientEventSystem.Event.PATIENT_Closed, eventPatientClosed);
68 
69  Patient loadedPatient = Patient.getLoadedPatient();
70  Debug.Log("Loaded patient: " + loadedPatient);
71  if (loadedPatient != null)
72  {
73  eventNewPatientLoaded(loadedPatient);
74  }
75  else
76  {
77  eventPatientClosed();
78  }
79  }
80 
81  void eventNewPatientLoaded(object obj)
82  {
83  Patient patient = obj as Patient;
84  if (patient != null)
85  {
86 
87  clearTabs();
88 
89  // Create Tabs according to the loaded tab names:
90  List<string> tabNames = patient.getAdditionalInfoTabs();
91  for (int i = 0; i < tabNames.Count; i++)
92  {
93  GameObject newButton = GameObject.Instantiate(tabButton);
94  newButton.SetActive(true);
95  newButton.name = tabNames[i];
96  newButton.transform.Find("Text").GetComponent<Text>().text = tabNames[i];
97  newButton.transform.SetParent(tabButton.transform.parent, false);
98 
99  Button b = newButton.GetComponent<Button>();
100  b.onClick.AddListener(() => selectTab(b));
101  }
102 
103  // Move the empty filler to the back of the list:
104  emptyFiller.transform.SetAsLastSibling ();
105 
106  if (tabButton.transform.parent.childCount > 2)
107  {
108  // Select the first tab which is not the tabButton prefab:
109  selectTab(tabButton.transform.parent.GetChild(1).GetComponent<Button>());
110  }
111  }
112  }
113 
114  private void selectTab(Button b)
115  {
116  foreach (Transform child in tabButton.transform.parent)
117  {
118  if( child.gameObject != emptyFiller )
119  UI.Core.instance.unselectTab(child.GetComponent<Button>());
120  }
121  UI.Core.instance.selectTab(b);
122 
123  string tabName = b.GetComponentInChildren<Text>().text;
124  Patient loadedPatient = Patient.getLoadedPatient();
125  if (loadedPatient == null)
126  {
127  return;
128 
129  }
130  Debug.Log("Loading tab: " + tabName);
131 
132 
133 
134  string result = "";
135  bool htmlFound = false;
136  foreach (Patient.AdditionalInformation info in loadedPatient.getAdditionalInfo())
137  {
138 
139  // Add all info for this tab to the string:
140  if (info.tabName == tabName)
141  {
142  // If HTML found, render the html and skip the text
143  if (info.type == "HTML")
144  {
145  htmlFound = true;
146  showHTML(info);
147  break;
148  }
149 
150  result += "<b>" + info.name + "</b>" + "\n\n";
151  result += info.content + "\n\n";
152  }
153  }
154  if (!htmlFound)
155  {
156  showText(result);
157  }
158  return;
159 
160  }
161 
162  private void showText(string result)
163  {
164  textObj.SetActive(true);
165  rawImageObj.SetActive(false);
166  scrollView.GetComponent<ScrollRect>().content = textObj.GetComponent<RectTransform>();
167  text.text = result;
168  return;
169  }
170 
171  private void showHTML(Patient.AdditionalInformation info)
172  {
173  rawImageObj.SetActive(false);
174  html = info.content;
175  //The width of the viewport (can be resized)
176  int widthOfViewport = (int)viewPort.GetComponent<RectTransform>().rect.width - 17;
177  //int widthOfStretchedRawImage = (int)rawImageObj.GetComponent<RawImage>().rectTransform.rect.width;
178  widthOfViewport = Math.Max(1, widthOfViewport); //prevent widthOfStrechedRawImage to be less then 1
179  int widthBody = findBodyWidth(info.content);
180 
181  //If body with in html file is taller the space in the viewport, the body width attribute in html file is set to widthOfStretchedRawImage
182  if (widthBody > widthOfViewport)
183  {
184  html = rewriteBodyWidth(info.content, widthOfViewport);
185  }
186 
187  ThreadUtil t = new ThreadUtil(this.showHTMLWorker, this.showHTMLCallback);
188  t.Run();
189 
190  return;
191  }
192 
193  private void showHTMLCallback(object sender, RunWorkerCompletedEventArgs e)
194  {
195  if (e.Cancelled)
196  {
197  Debug.Log("[PatientBriefing.cs] HTML Rendering cancelled");
198  }
199  else if (e.Error != null)
200  {
201  Debug.LogError("[PatientBriefing.cs] HTML Rendering Error");
202  }
203  else
204  {
205  htmlRendered = true;
206  }
207  return;
208  }
209 
210  private void showHTMLWorker(object sender, DoWorkEventArgs e)
211  {
212  System.Drawing.Bitmap image = (System.Drawing.Bitmap)TheArtOfDev.HtmlRenderer.WinForms.HtmlRender.RenderToImageGdiPlus(html);
213  imageWidth = image.Width;
214  imageHeight = image.Height;
215  using (MemoryStream ms = new MemoryStream())
216  {
217  image.Save(ms, image.RawFormat);
218  imageArray = ms.ToArray();
219  }
220  }
221 
222  private int findBodyWidth(string input){
223  //Find first "width:??px";
224  string pattern = "width:\\s*\\d+px\\s*;";
225  Regex rgx = new Regex(pattern);
226  if(!rgx.IsMatch(input)){
227  //If there is no match
228  return Int32.MaxValue;
229  }
230  string width = rgx.Match(input).Value;
231 
232  //Get int from string
233  string pattern2 = "\\d+";
234  Regex rgx2 = new Regex(pattern2);
235  int widthInt = Int32.MaxValue;
236  if (!Int32.TryParse (rgx2.Match (width).Value, out widthInt)) {
237  Debug.LogError ("HTML parsing error");
238  }
239  return widthInt;
240  }
241 
242  private string rewriteBodyWidth(string input, int width)
243  {
244  string pattern = "width:\\s*\\d+px\\s*;";
245  string replacement = "width:"+ width + "px;";
246  Regex rgx = new Regex(pattern);
247  //If a width attribute is found
248  if (rgx.IsMatch(input))
249  {
250  string result = rgx.Replace(input, replacement);
251  return result;
252  }
253 
254  //Else, add width attribute to body
255  string pattern2 = "<body ";
256  string replacement2 = "<body width:" + width + "px;";
257  Regex rgx2 = new Regex(pattern2);
258  string result2 = rgx2.Replace(input, replacement2);
259  return result2;
260  }
261 
262  private void clearTabs()
263  {
264  foreach (Transform child in tabButton.transform.parent)
265  {
266  if (child.gameObject != tabButton && child.gameObject != emptyFiller)
267  {
268  UnityEngine.Object.Destroy(child.gameObject);
269  }
270  }
271  }
272 
273  void eventPatientClosed(object obj = null)
274  {
275  string msg = bold("Patient Information");
276  msg += "\n\n";
277 
278  msg += bold("Patient Name: ") + "No patient loaded.";
279 
280  text.text = msg;
281  }
282 
283  private string bold(string input)
284  {
285  return "<b>" + input + "</b>";
286  }
287 }