| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | import {UIEventSource} from "./UIEventSource"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export abstract class UIElement { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     private static nextId: number = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public readonly id: string; | 
					
						
							|  |  |  |     public readonly _source: UIEventSource<any>; | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |      | 
					
						
							|  |  |  |     private _hideIfEmpty = false; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected constructor(source: UIEventSource<any>) { | 
					
						
							|  |  |  |         this.id = "ui-element-" + UIElement.nextId; | 
					
						
							|  |  |  |         this._source = source; | 
					
						
							|  |  |  |         UIElement.nextId++; | 
					
						
							|  |  |  |         this.ListenTo(source); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-08 13:12:23 +02:00
										 |  |  |     public ListenTo(source: UIEventSource<any>) { | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |         if (source === undefined) { | 
					
						
							| 
									
										
										
										
											2020-07-21 01:37:48 +02:00
										 |  |  |             return this; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         source.addCallback(() => { | 
					
						
							|  |  |  |             self.Update(); | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2020-07-21 01:37:48 +02:00
										 |  |  |         return this; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |     private _onClick: () => void; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public onClick(f: (() => void)) { | 
					
						
							|  |  |  |         this._onClick = f; | 
					
						
							|  |  |  |         this.Update(); | 
					
						
							| 
									
										
										
										
											2020-07-01 17:38:48 +02:00
										 |  |  |         return this; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     Update(): void { | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |         let element = document.getElementById(this.id); | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         if (element === undefined || element === null) { | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |             // The element is not painted
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         element.innerHTML = this.InnerRender(); | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |         if (this._hideIfEmpty) { | 
					
						
							|  |  |  |             if (element.innerHTML === "") { | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |                 element.parentElement.style.display = "none"; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |                 element.parentElement.style.display = undefined; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (this._onClick !== undefined) { | 
					
						
							|  |  |  |             const self = this; | 
					
						
							| 
									
										
										
										
											2020-07-22 12:17:06 +02:00
										 |  |  |             element.onclick = (e) => { | 
					
						
							|  |  |  |                 if(e.consumed){ | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |                 self._onClick(); | 
					
						
							| 
									
										
										
										
											2020-07-22 12:17:06 +02:00
										 |  |  |                 e.consumed = true; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-01 21:21:29 +02:00
										 |  |  |             element.style.pointerEvents = "all"; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |             element.style.cursor = "pointer"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |         this.InnerUpdate(element); | 
					
						
							| 
									
										
										
										
											2020-07-20 09:57:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const i in this) { | 
					
						
							|  |  |  |             const child = this[i]; | 
					
						
							|  |  |  |             if (child instanceof UIElement) { | 
					
						
							|  |  |  |                 child.Update(); | 
					
						
							|  |  |  |             } else if (child instanceof Array) { | 
					
						
							|  |  |  |                 for (const ch of child) { | 
					
						
							|  |  |  |                     if (ch instanceof UIElement) { | 
					
						
							|  |  |  |                         ch.Update(); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |     HideOnEmpty(hide : boolean){ | 
					
						
							|  |  |  |         this._hideIfEmpty = hide; | 
					
						
							|  |  |  |         this.Update(); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     // Called after the HTML has been replaced. Can be used for css tricks
 | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |    protected InnerUpdate(htmlElement: HTMLElement) { | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Render(): string { | 
					
						
							|  |  |  |         return "<span class='uielement' id='" + this.id + "'>" + this.InnerRender() + "</span>" | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AttachTo(divId: string) { | 
					
						
							|  |  |  |         let element = document.getElementById(divId); | 
					
						
							| 
									
										
										
										
											2020-07-20 09:57:19 +02:00
										 |  |  |         if (element === null) { | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |             throw "SEVERE: could not attach UIElement to " + divId; | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |         element.innerHTML = this.Render(); | 
					
						
							|  |  |  |         this.Update(); | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |         return this; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |     public abstract InnerRender(): string; | 
					
						
							| 
									
										
										
										
											2020-07-20 09:57:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public Activate(): void { | 
					
						
							|  |  |  |         for (const i in this) { | 
					
						
							|  |  |  |             const child = this[i]; | 
					
						
							|  |  |  |             if (child instanceof UIElement) { | 
					
						
							|  |  |  |                 child.Activate(); | 
					
						
							|  |  |  |             } else if (child instanceof Array) { | 
					
						
							|  |  |  |                 for (const ch of child) { | 
					
						
							|  |  |  |                     if (ch instanceof UIElement) { | 
					
						
							|  |  |  |                         ch.Activate(); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public IsEmpty(): boolean { | 
					
						
							|  |  |  |         return this.InnerRender() === ""; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 |