0032433: Visualization, TKService - introduce Wasm_Window implementing Aspect_Window...
[occt.git] / src / Wasm / Wasm_Window.hxx
diff --git a/src/Wasm/Wasm_Window.hxx b/src/Wasm/Wasm_Window.hxx
new file mode 100644 (file)
index 0000000..5485d25
--- /dev/null
@@ -0,0 +1,185 @@
+// Created by: Kirill Gavrilov
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Wasm_Window_HeaderFile
+#define _Wasm_Window_HeaderFile
+
+#include <Aspect_Window.hxx>
+
+#include <Aspect_VKey.hxx>
+#include <Aspect_Handle.hxx>
+#include <Graphic3d_Vec2.hxx>
+
+class Aspect_WindowInputListener;
+
+struct EmscriptenMouseEvent;
+struct EmscriptenWheelEvent;
+struct EmscriptenTouchEvent;
+struct EmscriptenKeyboardEvent;
+struct EmscriptenUiEvent;
+
+//! This class defines WebAssembly window (HTML5 canvas) intended for creation of OpenGL (WebGL) context.
+//!
+//! Note that canvas may define an independent dimensions for backing store (WebGL buffer to render)
+//! and for CSS (logical units to present buffer onto screen).
+//! These dimensions differ when browser is dragged into a high pixel density screen (HiDPI),
+//! or when user scales page in the browser (in both cases window.devicePixelRatio JavaScript property becomes not equal to 1.0).
+//!
+//! By default, Wasm_Window::DoResize() will scale backing store of a canvas basing on DevicePixelRatio() scale factor
+//! to ensure canvas content being rendered with the native resolution and not stretched by browser.
+//! This, however, might have side effects:
+//! - a slow GPU might experience performance issues on drawing into larger buffer (e.g. HiDPI);
+//! - user interface displayed in 3D Viewer (e.g. AIS presentations) should be scaled proportionally to be accessible,
+//!   which might require extra processing at application level.
+//! Consider changing ToScaleBacking flag passed to Wasm_Window constructor in case of issues.
+class Wasm_Window : public Aspect_Window
+{
+  DEFINE_STANDARD_RTTIEXT(Wasm_Window, Aspect_Window)
+public:
+
+  //! Convert Emscripten mouse buttons into Aspect_VKeyMouse.
+  Standard_EXPORT static Aspect_VKeyMouse MouseButtonsFromNative (unsigned short theButtons);
+
+  //! Convert DOM virtual key into Aspect_VKey.
+  Standard_EXPORT static Aspect_VKey VirtualKeyFromNative (Standard_Integer theKey);
+
+public:
+
+  //! Wraps existing HTML5 canvas into window.
+  //! @param[in] theCanvasId target HTML element id defined in a querySelector() syntax
+  //! @param[in] theToScaleBacking when TRUE, window will automatically scale backing store of canvas
+  //!                              basing on DevicePixelRatio() scale factor within DoResize()
+  Standard_EXPORT Wasm_Window (const TCollection_AsciiString& theCanvasId,
+                               const bool theToScaleBacking = true);
+
+  //! Destroys the window.
+  Standard_EXPORT virtual ~Wasm_Window();
+
+  //! Return true if window is not hidden.
+  virtual Standard_Boolean IsMapped() const Standard_OVERRIDE { return myIsMapped; }
+
+  //! Change window mapped flag to TRUE.
+  virtual void Map()   const Standard_OVERRIDE { myIsMapped = Standard_True; }
+
+  //! Change window mapped flag to FALSE.
+  virtual void Unmap() const Standard_OVERRIDE { myIsMapped = Standard_False; }
+
+  //! Resize window.
+  //! In case of ToScaleBacking flag, this method will resize the backing store of canvas
+  //! basing on DevicePixelRatio() scale factor and CSS canvas size.
+  Standard_EXPORT virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE;
+
+  //! Apply the mapping change to the window.
+  virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }
+
+  //! Returns window ratio equal to the physical width/height dimensions.
+  Standard_EXPORT virtual Standard_Real Ratio() const Standard_OVERRIDE;
+
+  //! Returns The Window POSITION in PIXEL
+  Standard_EXPORT virtual void Position (Standard_Integer& theX1,
+                                         Standard_Integer& theY1,
+                                         Standard_Integer& theX2,
+                                         Standard_Integer& theY2) const Standard_OVERRIDE;
+
+  //! Return the window size in pixels.
+  Standard_EXPORT virtual void Size (Standard_Integer& theWidth,
+                                     Standard_Integer& theHeight) const Standard_OVERRIDE;
+
+  //! Set new window size in logical (density-independent units).
+  //! Backing store will be resized basing on DevicePixelRatio().
+  Standard_EXPORT void SetSizeLogical (const Graphic3d_Vec2d& theSize);
+
+  //! Set new window size in pixels.
+  //! Logical size of the element will be resized basing on DevicePixelRatio().
+  Standard_EXPORT void SetSizeBacking (const Graphic3d_Vec2i& theSize);
+
+  //! Returns canvas id.
+  const TCollection_AsciiString& CanvasId() const { return myCanvasId; }
+
+  //! Current EGL implementation in Emscripten accepts only 0 for native window id.
+  virtual Aspect_Drawable NativeHandle() const Standard_OVERRIDE { return 0; }
+
+  //! Always returns 0 for this class.
+  virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE { return 0; }
+
+  //! Always returns 0 for this class.
+  virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return 0; }
+
+  //! Return device pixel ratio (logical to backing store scale factor).
+  virtual Standard_Real DevicePixelRatio() const Standard_OVERRIDE { return myDevicePixelRatio; }
+
+  //! Invalidate entire window content through generation of Expose event.
+  Standard_EXPORT virtual void InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp) Standard_OVERRIDE;
+
+public:
+
+  //! Process a single window message.
+  //! @param[in,out] theListener listener to redirect message
+  //! @param[in] theEventType message type to process
+  //! @param[in] theEvent message to process
+  //! @return TRUE if message has been processed
+  Standard_EXPORT virtual bool ProcessMessage (Aspect_WindowInputListener& theListener,
+                                               int theEventType, const void* theEvent);
+
+  //! Process a mouse input message.
+  //! @param[in,out] theListener listener to redirect message
+  //! @param[in] theEventType message type to process
+  //! @param[in] theEvent message to process
+  //! @return TRUE if message has been processed
+  Standard_EXPORT virtual bool ProcessMouseEvent (Aspect_WindowInputListener& theListener,
+                                                  int theEventType, const EmscriptenMouseEvent* theEvent);
+
+  //! Process a (mouse) wheel input message.
+  //! @param[in,out] theListener listener to redirect message
+  //! @param[in] theEventType message type to process
+  //! @param[in] theEvent message to process
+  //! @return TRUE if message has been processed
+  Standard_EXPORT virtual bool ProcessWheelEvent (Aspect_WindowInputListener& theListener,
+                                                  int theEventType, const EmscriptenWheelEvent* theEvent);
+
+  //! Process a mouse input message.
+  //! @param[in,out] theListener listener to redirect message
+  //! @param[in] theEventType message type to process
+  //! @param[in] theEvent message to process
+  //! @return TRUE if message has been processed
+  Standard_EXPORT virtual bool ProcessTouchEvent (Aspect_WindowInputListener& theListener,
+                                                  int theEventType, const EmscriptenTouchEvent* theEvent);
+
+  //! Process a keyboard input message.
+  //! @param[in,out] theListener listener to redirect message
+  //! @param[in] theEventType message type to process
+  //! @param[in] theEvent message to process
+  //! @return TRUE if message has been processed
+  Standard_EXPORT virtual bool ProcessKeyEvent (Aspect_WindowInputListener& theListener,
+                                               int theEventType, const EmscriptenKeyboardEvent* theEvent);
+
+  //! Process a UI input message (like window resize).
+  //! @param[in,out] theListener listener to redirect message
+  //! @param[in] theEventType message type to process
+  //! @param[in] theEvent message to process
+  //! @return TRUE if message has been processed
+  Standard_EXPORT virtual bool ProcessUiEvent (Aspect_WindowInputListener& theListener,
+                                               int theEventType, const EmscriptenUiEvent* theEvent);
+
+protected:
+
+  TCollection_AsciiString  myCanvasId;
+  Graphic3d_Vec2i          mySize;
+  Standard_Real            myDevicePixelRatio;
+  Standard_Boolean         myToScaleBacking;
+  mutable Standard_Boolean myIsMapped;
+
+};
+
+#endif // _Wasm_Window_HeaderFile