/// <summary>The request has timed out.</summary> public void TimedOut() { statusCode = 408; Dom.Event e = new Dom.Event(); e.SetTrusted(); e.EventType = "timeout"; dispatchEvent(e); // RS4: readyState = 4; }
/// <summary>Requests this element (e.g. a video) to go fullscreen.</summary> public void requestFullscreen() { if (htmlDocument.fullscreenElement == this) { // Already fullscreen: return; } // Trigger fullscreen event: Dom.Event e = new Dom.Event("fullscreenchange"); e.SetTrusted(false); if (!dispatchEvent(e)) { // Cancelled it. return; } if (htmlDocument.fullscreenElement != null) { // Cancel it: htmlDocument.exitFullscreen(); } // Apply element: htmlDocument.fullscreenElement = this; // Cache the current parent: CachedFullscreenParent = parentNode; if (parentNode != null) { // Can't actually do anything with it anyway otherwise - it's already filling the screen! // Remove it from the DOM: parentNode.removeChild(this); // Add it elsewhere: htmlDocument.html.appendChild(this); // Cache ele style: CachedFullscreenStyle = style.cssText; // Set basic style: style.cssText = "width:100%;height:100%;left:0px;top:0px;right:0px;bottom:0px;position:fixed;"; } // Set (note that this triggers a CSS event): setAttribute("fullscreen", "1"); // Update local style: Style.Computed.RefreshLocal(); }
internal override bool ResourceStatus(EventTarget package, int status) { if (base.ResourceStatus(package, status)) { // Run the onload event if we're in an iframe: if (window.iframe != null) { // Dispatch to the element too (don't bubble): Dom.Event e = new Dom.Event("load"); e.SetTrusted(false); window.iframe.dispatchEvent(e); } return(true); } return(false); }
/// <summary>A callback used when the graphic has been loaded and is ready for display.</summary> public void ImageReady(ImagePackage package) { if (Image == null || !Image.Loaded) { return; } // Dispatch load (don't bubble, default): Dom.Event e = new Dom.Event("load"); e.SetTrusted(false); RenderData.Node.dispatchEvent(e); RequestLayout(); if (Image != null && Filtering != FilterMode.Point) { Image.Contents.FilterMode = Filtering; } }
/// <summary>Sets the option at the given index as the selected one.</summary> /// <param name="index">The index of the option to select.</param> /// <param name="element">The element at the given index.</param> /// <param name="runOnChange">True if the onchange event should run.</param> private void SetSelected(int index, HtmlOptionElement element, bool runOnChange) { if (element == SelectedNode_) { return; } Dom.Event e = new Dom.Event("change"); e.SetTrusted(false); // Cache previous: int prevIndex = SelectedIndex_; HtmlOptionElement prevNode = SelectedNode_; // Update current (so onchange gets the correct value): SelectedNode_ = element; SelectedIndex_ = index; if (runOnChange) { if (!dispatchEvent(e)) { // Restore to previous: SelectedIndex_ = prevIndex; SelectedNode_ = prevNode; return; } } // Update placeholder: if (SelectedNode_ == null) { // Clear the option text: Placeholder.innerHTML = ""; index = -1; } else { Placeholder.innerHTML = SelectedNode_.innerHTML; } }
/// <summary>Call this to begin a marquee.</summary> public void Start() { if (Active) { return; } Active = true; // Doesn't bubble: Dom.Event e = new Dom.Event("start"); e.SetTrusted(false); if (dispatchEvent(e)) { // Start our timer: Timer = new UITimer(false, ScrollDelay, OnTick); Timer.Document = document_; } }
/// <summary>Call this to stop a scrolling marquee.</summary> public void Stop() { if (!Active) { return; } // Doesn't bubble: Dom.Event e = new Dom.Event("stop"); e.SetTrusted(false); if (dispatchEvent(e)) { Active = false; // Stop and clear the timer: Timer.Stop(); Timer = null; } }
/// <summary>Called when the marquee wraps.</summary> private void Wrapped() { if (Loop == -1) { return; } Loop--; if (Loop == 0) { // Stop the marquee: Stop(); // Fire the finish event: // Doesn't bubble: Dom.Event e = new Dom.Event("finish"); e.SetTrusted(false); dispatchEvent(e); } }
/// <summary>Sets how many pixels of space this renderer has. The actual world space size is dictated by this and /// <see cref="PowerUI.WorldUI.SetResolution"/>. The amount of pixels and pixels per world unit (resolution).</summary> /// <param name="widthPX">The width in pixels.</param> /// <param name="heightPX">The height in pixels.</param> public virtual bool SetDimensions(int widthPX, int heightPX) { if (widthPX == pixelWidth && heightPX == pixelHeight) { return(false); } if (widthPX != pixelWidth) { pixelWidth = widthPX; document.Viewport.Width = widthPX; } if (heightPX != pixelHeight) { pixelHeight = heightPX; PixelHeightF = (float)pixelHeight; document.Viewport.Height = heightPX; } // Update ratio: Ratio = (float)pixelWidth / PixelHeightF; // Reset the origin position: SetOrigin(OriginLocation.x, OriginLocation.y); // Fire the resize event: if (document.body != null) { Dom.Event e = new Dom.Event("resize"); e.SetTrusted(); document.dispatchEvent(e); } return(true); }
/// <summary> Checks if the screen size changed and repaints if it did. /// Called by <see cref="UI.Update"/>.</summary> public static void Update() { if (UI.GUICamera == null) { // PowerUI is offline. return; } bool changedX = false; bool changedY = false; if (UnityEngine.Screen.width != ScreenX) { ScreenX = UnityEngine.Screen.width; ScreenXFloat = (float)ScreenX; changedX = true; } if (UnityEngine.Screen.height != ScreenY) { ScreenY = UnityEngine.Screen.height; ScreenYFloat = (float)ScreenY; changedY = true; } HtmlDocument document = UI.document; // Device orientation changed? bool landscape = IsLandscape(); Css.MediaType media; if (PreviousOrientation == DeviceOrientation.Unknown) { // First time. Straight set it: PreviousOrientation = landscape?DeviceOrientation.LandscapeLeft : DeviceOrientation.Portrait; } else { // Changed? if (landscape && PreviousOrientation != DeviceOrientation.LandscapeLeft) { // Orientation changed! Update previous: PreviousOrientation = landscape?DeviceOrientation.LandscapeLeft : DeviceOrientation.Portrait; // Inform main UI media rules: media = document.MediaIfExists; if (media != null) { // Nudge it! media.Landscape = landscape; } // Fire the rotation event now (on the window): // We're using absolute here because 'deviceorientation' is the actual angle of the device. DeviceOrientationEvent e = new DeviceOrientationEvent("deviceorientationabsolute"); e.absolute = true; e.SetTrusted(); document.window.dispatchEvent(e); } } if (!changedX && !changedY) { return; } // Nudge the matrices: UI.GUICamera.ResetWorldToCameraMatrix(); UI.GUICamera.ResetProjectionMatrix(); UI.GUICamera.ResetAspect(); // Firstly, find the bottom left and top right corners at UI.CameraDistance z units away (zero z-index): Vector3 bottomLeft = UI.GUICamera.ScreenToWorldPoint(new Vector3(0f, 0f, UI.CameraDistance)); Vector3 topRight = UI.GUICamera.ScreenToWorldPoint(new Vector3(ScreenX, ScreenY, UI.CameraDistance)); // With those, we can now find the size of the screen in world units: WorldSize.x = topRight.x - bottomLeft.x; WorldSize.y = topRight.y - bottomLeft.y; // Finally, calculate WorldPerPixel at zero depth: // Mapping PX to world units: WorldPerPixel.x = WorldSize.x / (float)ScreenX; WorldPerPixel.y = WorldSize.y / (float)ScreenY; // Set where the origin is. All rendering occurs relative to this point. // It's offset by 0.2 pixels to target a little closer to the middle of each pixel. This helps Pixel filtering look nice and clear. WorldScreenOrigin.y = bottomLeft.y + (0.4f * WorldPerPixel.y); WorldScreenOrigin.x = bottomLeft.x - (0.4f * WorldPerPixel.x); // Update main document's viewport: document.Viewport.Update(ScreenXFloat, ScreenYFloat); // Fire the resize event (doesn't bubble): Dom.Event resize = new Dom.Event("resize"); resize.SetTrusted(false); document.window.dispatchEvent(resize); // Inform main UI media rules: media = document.MediaIfExists; // Resize: if (changedX) { int w = (int)ScreenXFloat; document.RequestLayout(); if (media != null) { // Nudge it! media.Width = w; } } if (changedY) { int h = (int)ScreenYFloat; document.RequestLayout(); if (media != null) { // Nudge it! media.Height = h; } } }
/// <summary>Sets the value of this input box, optionally as a html string.</summary> /// <param name="value">The value to set.</param> /// <param name="html">True if the value can safely contain html.</param> public void SetValue(string value, bool html) { // Trigger onchange: Dom.Event e = new Dom.Event("change"); e.SetTrusted(false); if (!dispatchEvent(e)) { return; } if (MaxLength != int.MaxValue) { // Do we need to clip it? if (value != null && value.Length > MaxLength) { // Yep! value = value.Substring(0, MaxLength); } } if (value == null || CaretIndex > value.Length) { MoveCaret(0); } if (Value == null) { defaultValue = value; } // Update the value: this["value"] = Value = value; if (!IsBoolInput()) { if (Hidden) { // Unfortunately the new string(char,length); constructor isn't reliable. // Build the string manually here. StringBuilder sb = new StringBuilder("", value.Length); for (int i = 0; i < value.Length; i++) { sb.Append('*'); } if (html) { innerHTML = sb.ToString(); } else { textContent = sb.ToString(); } } else { if (html) { innerHTML = value; } else { textContent = value; } } } }
/// <summary>Scrolls this scrollbar by the given number of pixels, optionally relative to a fixed point on the bar. /// Note that this may fail if the scrollbar cannot scroll any further.</summary> /// <param name="pixels">The number of pixels to scroll this bar by.</param> /// <param name="fromCurrent">True if pixels is relative to where the thumb currently is. False if pixels is relative /// to where the bar was when the mouse was clicked. See e.g. <see cref="PowerUI.VScrollTabTag.StartY"/>.</param> /// <param name="scrollTarget">True if the target should also be scrolled.</param> public void ScrollBy(float pixels, bool fromCurrent, bool scrollTarget) { // Scroll it by pixels from Start. float newLocation = pixels; float currentPosition = Position; LayoutBox box = RenderData.FirstBox; if (fromCurrent) { newLocation += currentPosition; } else { newLocation += Start; } // Get the size of the button before the tab: float sizeBefore = StartArrowSize; float barSize = BarSize; float max = barSize + sizeBefore; if (IsVertical) { max -= box.Height; } else { max -= box.Width; } if (newLocation < sizeBefore) { newLocation = sizeBefore; } else if (newLocation > max) { newLocation = max; } if (newLocation == currentPosition) { return; } if (IsVertical) { Style.top = newLocation + "fpx"; } else { Style.left = newLocation + "fpx"; } // Fire a change event on the scrollbar: Dom.Event e = new Dom.Event("change"); e.SetTrusted(); ScrollBar.dispatchEvent(e); if (scrollTarget) { // Get info for the target: HtmlElement target = ScrollBar.scrollTarget; ComputedStyle targetCs = target.style.Computed; box = targetCs.FirstBox; if (target != null && box != null) { // Get the progress: float progress = (newLocation - sizeBefore) / barSize; // Update CSS: if (IsVertical) { targetCs.ChangeTagProperty("scroll-top", new Css.Units.DecimalUnit(progress * box.ContentHeight)); } else { targetCs.ChangeTagProperty("scroll-left", new Css.Units.DecimalUnit(progress * box.ContentWidth)); } // And request a redraw: target.htmlDocument.RequestLayout(); } } }
/// <summary>Sets the pressure level.</summary> public void SetPressure(float v) { // Was it up before? bool wasUp = (Pressure == 0f); // Set pressure: Pressure = v; // If it's non-zero then we'll need to grab the clicked object: if (v == 0f) { if (wasUp) { // No change. } else { // It's up now. Clear: EventTarget oldActivePressed = ActivePressedTarget; // Clear: ActivePressedTarget = null; if (oldActivePressed != null) { // Refresh CSS (active; applies to parents too): EventTarget current = oldActivePressed; while (current != null) { // Get it as a renderable node: IRenderableNode irn = (current as IRenderableNode); if (irn != null) { irn.ComputedStyle.RefreshLocal(); } current = current.eventTargetParentNode; } } // Trigger up event. MouseEvent e = new MouseEvent(DocumentX, DocumentY, ButtonID, false); e.trigger = this; e.SetModifiers(); e.EventType = "mouseup"; if (oldActivePressed == null) { Input.Unhandled.dispatchEvent(e); } else { oldActivePressed.dispatchEvent(e); } // Click if needed: if (oldActivePressed == ActiveOverTarget && DragStatus == 0) { // Click! e.Reset(); e.trigger = this; e.SetModifiers(); e.EventType = "click"; if (oldActivePressed == null) { Input.Unhandled.dispatchEvent(e); } else if (oldActivePressed.dispatchEvent(e)) { // Clear the selection if necessary: HtmlElement h = (oldActivePressed as HtmlElement); if (h != null) { // Clear selection if there is one: (h.document as HtmlDocument).clearSelection(); } } } if (FireTouchEvents) { // Trigger a touchend event too: TouchEvent te = new TouchEvent("touchend"); te.trigger = this; te.SetModifiers(); te.SetTrusted(); te.clientX = DocumentX; te.clientY = DocumentY; if (oldActivePressed == null) { Input.Unhandled.dispatchEvent(te); } else { oldActivePressed.dispatchEvent(te); } } if (DragStatus == DRAGGING) { // Trigger dragend: DragEvent de = new DragEvent("dragend"); de.trigger = this; de.SetModifiers(); de.SetTrusted(); de.clientX = ScreenX; de.clientY = ScreenY; if (oldActivePressed.dispatchEvent(de)) { // Trigger a drop event next: de.Reset(); de.EventType = "drop"; if (ActiveOverTarget != null && ActiveOverTarget.dispatchEvent(de)) { // Proceed to try and drop it into the dropzone (ActiveOver). } } } else if (DragStatus == SELECTING) { // Finished selection - trigger selectionend: Dom.Event sc = new Dom.Event("selectionend"); sc.SetTrusted(); // Dispatch on the element: oldActivePressed.dispatchEvent(sc); } // Always clear drag status: DragStatus = 0; MinDragDistance = 0f; } } else if (wasUp) { // It was up and it's now just gone down. // Cache position: DownDocumentX = DocumentX; DownDocumentY = DocumentY; // Cache down: ActivePressedTarget = ActiveOverTarget; // Trigger down event. if (ActivePressedTarget != null) { // Refresh CSS (active; applies to parents too): EventTarget current = ActivePressedTarget; while (current != null) { // Get it as a renderable node: IRenderableNode irn = (current as IRenderableNode); if (irn != null) { irn.ComputedStyle.RefreshLocal(); } current = current.eventTargetParentNode; } } // Trigger down event. MouseEvent e = new MouseEvent(DocumentX, DocumentY, ButtonID, true); e.trigger = this; e.EventType = "mousedown"; e.SetModifiers(); if (ActivePressedTarget == null) { Input.Unhandled.dispatchEvent(e); } else { ActivePressedTarget.dispatchEvent(e); } if (FireTouchEvents) { // Trigger a touchend event too: TouchEvent te = new TouchEvent("touchstart"); te.trigger = this; te.clientX = DocumentX; te.clientY = DocumentY; te.SetTrusted(); te.SetModifiers(); if (ActivePressedTarget == null) { Input.Unhandled.dispatchEvent(te); } else { ActivePressedTarget.dispatchEvent(te); } } } }