@ce.
+
+Size of the canvas can be also overriden by specifying one of the
+@cb{.css} .width-* @ce CSS classes on the @cb{.html}
@ce:
+
+Width | CSS class
+--------------- | ---------
+240px | @cb{.css} .width-240 @ce
+320px | @cb{.css} .width-320 @ce
+360px | @cb{.css} .width-360 @ce
+480px | @cb{.css} .width-480 @ce
+600px | @cb{.css} .width-600 @ce
+640px | @cb{.css} .width-640 @ce (default)
+800px | @cb{.css} .width-800 @ce
+
+For example, for a 480x640 canvas (3:4, portrait) you would use
+@cb{.html}
@ce. Besides the
+predefined classes above, it's also possible to specify your own by adding a
+@cb{.css} width @ce style to the @cb{.css} div#sizer @ce --- for example, a
+1024x768 canvas would be @cb{.html}
@ce.
+Again note that if the canvas is larger than window width, it gets
+automatically scaled down, preserving its aspect ratio.
+
+It's also possible to stretch the canvas to occupy the full page using the
+@cb{.css} .fullsize @ce CSS class set to @cb{.css} div#container @ce. In this
+case it's advised to remove all other elements (such as the @cb{.html}
@ce
+element) from the page to avoid them affecting the canvas. Combining
+@cb{.css} .fullsize @ce with the other @cb{.css} .aspect-* @ce or
+@cb{.css} .width-* @ce classes is not supported.
+
+@section platforms-html5-events Controlling event behavior
+
+@subsection platforms-html5-events-keyboard Keyboard events
+
+By default, the graphical Emscripten application grabs all keyboard input
+anywhere on the page (so e.g. @m_class{m-label m-default} **F5** or opening
+browser console via a keyboard shortcut doesn't work). If you don't want it to
+grab keyboard input at all, set @cb{.js} Module.doNotCaptureKeyboard @ce to
+@cb{.js} true @ce, either by modifying the `EmscriptenApplication.js` file or
+directly in the HTML source:
+
+@code{.html}
+
+@endcode
+
+The above is implicitly set for windowless apps, because these don't have any
+event loop.
+
+Another solution is to specify the element on which it should capture keybard
+using @cb{.js} Module.keyboardListeningElement @ce --- it requires the actual
+element instance (*not* just its ID). The element then needs to be activated
+(for example with a mouse click) in order to start receiving input. The
+@cb{.html} @ce element is a bit special in this regard --- in order to
+make it receive keyboard input, you have to add a `tabindex` attribute to it
+like this:
+
+@code{.html}
+
+@endcode
+
+After that, the canvas can be focused with a @m_class{m-label m-default} **Tab**
+key. But because Emscripten eats all mouse input, the `mousedown` event won't
+be propagated to focus the canvas unlesss you do that manually:
+
+@code{.js}
+Module.keyboardListeningElement = Module.canvas;
+Module.canvas.addEventListener('mousedown', function(event) {
+ event.target.focus();
+});
+@endcode
+
+@subsection platforms-html5-events-contextmenu Context menu
+
+By default, the canvas opens a browser-specific popup menu on right click. That
+allows the user to for example save a screenshot of the canvas, but if you are
+handling right click directly in your app, you may want to disable the default
+behavior:
+
+@code{.js}
+Module.canvas.addEventListener('contextmenu', function(event) {
+ event.preventDefault();
+}, true);
+@endcode
+
@section platforms-html5-environment Terminal output, environment and command-line arguments
When running console apps using Node.js, command-line arguments and terminal
output work like usual.
-For graphics apps in the browser, `EmscriptenApplication.js` redirects all
+For graphical apps in the browser, `EmscriptenApplication.js` redirects all
output (thus also @ref Corrade::Utility::Debug "Debug",
@ref Corrade::Utility::Warning "Warning" and @ref Corrade::Utility::Error "Error")
to JavaScript console. For windowless apps, `WindowlessEmscriptenApplication.js`
@@ -380,14 +505,14 @@ following scenarios are possible:
- By default, the size of Emscripten heap is restricted to 16 MB. That might
not be enough if you have large compiled-in resources or allocate large
- amount of memory. This can be solved either with:
+ amount of memory. This can be solved with either of these:
- Adding `-s TOTAL_MEMORY=<bytes>` to compiler/linker flags, where
<bytes> is the new heap size
- Adding `-s ALLOW_MEMORY_GROWTH=1` to compiler/linker flags. This is
useful in case you don't know how much memory you need in advance and
[might disable some optimizations](https://kripken.github.io/emscripten-site/docs/optimizing/Optimizing-Code.html#memory-growth).
- - Setting `Module { TOTAL_MEMORY: <bytes>; }` in the JavaScript
- driver file
+ - Setting @cb{.js} Module { TOTAL_MEMORY: ; } @ce in the
+ JavaScript driver file
- Sometimes Chromium-based browsers refuse to create WebGL context on a
particular page, while on other sites it works and the same page works in
other browsers such as Firefox. This can be caused by Chromium running for
diff --git a/src/Magnum/Audio/al-info.html b/src/Magnum/Audio/al-info.html
index 439e1a16d..2b5d8600a 100644
--- a/src/Magnum/Audio/al-info.html
+++ b/src/Magnum/Audio/al-info.html
@@ -1,18 +1,22 @@
-
-
- Magnum AL Info
-
-
-
-
- Magnum AL Info
-
+
+
+
+
Magnum AL Info
+
+
+
+
+
Magnum AL Info
+
+
+
Initialization...
-
+
-
-
+
+
+
diff --git a/src/Magnum/Platform/EmscriptenApplication.js b/src/Magnum/Platform/EmscriptenApplication.js
index fa467e1da..fabf4c71d 100644
--- a/src/Magnum/Platform/EmscriptenApplication.js
+++ b/src/Magnum/Platform/EmscriptenApplication.js
@@ -1,3 +1,28 @@
+/*
+ This file is part of Magnum.
+
+ Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
+ Vladimír Vondruš
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
var Module = {
preRun: [],
postRun: [],
@@ -12,6 +37,13 @@ var Module = {
console.log(Array.prototype.slice.call(arguments).join(' '));
},
+ onAbort: function() {
+ Module.canvas.style.opacity = 0.333;
+ Module.canvas.style.zIndex = -1;
+ Module.setStatus("Oops :(");
+ Module.setStatusDescription("The app crashed. Refresh the page or check the browser console for details.");
+ },
+
canvas: document.getElementById('module'),
setStatus: function(message) {
@@ -20,7 +52,7 @@ var Module = {
},
setStatusDescription: function(message) {
- var statusDescription = document.getElementById('statusDescription');
+ var statusDescription = document.getElementById('status-description');
if(statusDescription) statusDescription.innerHTML = message;
},
@@ -31,7 +63,7 @@ var Module = {
if(left) {
Module.setStatus('Downloading...');
- Module.setStatusDescription((this.totalDependencies - left) + '/' + this.totalDependencies);
+ Module.setStatusDescription((this.totalDependencies - left) + ' / ' + this.totalDependencies);
} else {
Module.setStatus('Download complete');
Module.setStatusDescription('');
@@ -54,7 +86,3 @@ for(var i = 0; i != args.length; ++i) {
}
Module.setStatus('Downloading...');
-
-Module.canvas.addEventListener('contextmenu', function(event) {
- event.preventDefault();
-}, true);
diff --git a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp
index c5f2a909f..0618bde32 100644
--- a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp
+++ b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp
@@ -28,8 +28,25 @@
namespace Magnum { namespace Platform { namespace Test {
struct Sdl2ApplicationTest: Platform::Application {
- explicit Sdl2ApplicationTest(const Arguments& arguments): Platform::Application{arguments} {}
+ /* For testing resize events */
+ explicit Sdl2ApplicationTest(const Arguments& arguments): Platform::Application{arguments, Configuration{}.setWindowFlags(Configuration::WindowFlag::Resizable)} {}
+
void drawEvent() override {}
+
+ /* For testing HiDPI resize events */
+ void viewportEvent(ViewportEvent& event) override {
+ Debug{} << "viewport event" << event.windowSize() << event.framebufferSize() << event.dpiScaling();
+ }
+
+ /* For testing event coordinates */
+ void mousePressEvent(MouseEvent& event) override {
+ Debug{} << event.position();
+ }
+
+ /* For testing keyboard capture */
+ void keyPressEvent(KeyEvent& event) override {
+ Debug{} << event.keyName();
+ }
};
}}}
diff --git a/src/Magnum/Platform/Test/Sdl2ApplicationTest.html b/src/Magnum/Platform/Test/Sdl2ApplicationTest.html
index c65d07ca3..38db474e9 100644
--- a/src/Magnum/Platform/Test/Sdl2ApplicationTest.html
+++ b/src/Magnum/Platform/Test/Sdl2ApplicationTest.html
@@ -1,18 +1,28 @@
-
-
- Magnum Sdl2Application Test
-
-
-
- Magnum Sdl2Application Test
-
-
+
+
+
Magnum Sdl2Application Test
+
+
+
+
+
Magnum Sdl2Application Test
+
+
+
Initialization...
-
+
-
-
+
+
+
+
diff --git a/src/Magnum/Platform/Test/WindowlessEglApplicationTest.html b/src/Magnum/Platform/Test/WindowlessEglApplicationTest.html
index 96b63d442..2092f4449 100644
--- a/src/Magnum/Platform/Test/WindowlessEglApplicationTest.html
+++ b/src/Magnum/Platform/Test/WindowlessEglApplicationTest.html
@@ -1,19 +1,22 @@
-
-
- Magnum WindowlessEglApplication Test
-
-
-
- Magnum WindowlessEglApplication Test
-
+
+
+
Magnum WindowlessEglApplication Test
+
+
+
+
+
Magnum WindowlessEglApplication Test
+
+
+
diff --git a/src/Magnum/Platform/WebApplication.css b/src/Magnum/Platform/WebApplication.css
index 7cd10e08a..7bdc13888 100644
--- a/src/Magnum/Platform/WebApplication.css
+++ b/src/Magnum/Platform/WebApplication.css
@@ -1,65 +1,155 @@
+/*
+ This file is part of Magnum.
+
+ Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
+ Vladimír Vondruš
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+/* Colors kept in sync with m.css dark theme, http://mcss.mosra.cz */
+
+*, ::before, ::after { box-sizing: border-box; }
+
body {
- margin: 0px;
- padding: 0px;
- font-family: sans-serif;
- background-color: #111111;
- color: #aaaaaa;
+ margin: 1rem;
+ padding: 0;
+ font-family: sans-serif;
+ font-size: 16px;
+ background-color: #2f363f; /*var(--background-color)*/
+ color: #dcdcdc; /*var(--color)*/
}
-
h1 {
- text-align: center;
- font-size: 20px;
+ text-align: center;
+ font-size: 1.75rem;
+ font-weight: 600;
}
+/* #container makes the canvas occupy the whole page width
+ #sizer centers it
+ #expander does aspect ratio preservation
+ #listener snaps to #expander edges
+ #listener::before does the border, which finally goes below the canvas */
+#container {
+ margin: 1rem -1rem 1rem -1rem;
+}
+#sizer {
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 100%;
+ width: 640px;
+}
+#expander {
+ position: relative;
+}
#listener {
- border-style: solid;
- border-color: #333333;
- border-width: 1px;
- padding: 1px;
- width: 640px;
- height: 480px;
- margin-left: auto;
- margin-right: auto;
- margin-top: 20px;
- margin-bottom: 20px;
- position: relative;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+#listener::before {
+ position: absolute;
+ content: ' ';
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: -1;
+ border-style: solid;
+ border-width: 0.125rem;
+ border-radius: 0.2rem; /*var(--border-radius)*/
+ border-color: #405363; /*var(--line-color)*/
}
-#module {
- width: 640px;
- height: 480px;
- z-index: 10;
+/* Canvas size and aspect ratio knobs */
+#container.fullsize {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ margin: 0;
+}
+#container.fullsize #sizer, #container.fullsize #expander {
+ width: 100%; height: 100%;
}
-#status {
- position: absolute;
- width: 640px;
- text-align: center;
- top: 200px;
- font-size: 30px;
- font-weight: bold;
- z-index: 9;
+#container.width-240 #sizer { width: 240px; }
+#container.width-320 #sizer { width: 320px; }
+#container.width-360 #sizer { width: 360px; }
+#container.width-480 #sizer { width: 480px; }
+#container.width-600 #sizer { width: 600px; }
+#container.width-640 #sizer, #container #sizer {
+ width: 640px; /* default */
}
+#container.width-800 #sizer { width: 800px; }
-#statusDescription {
- position: absolute;
- width: 640px;
- text-align: center;
- top: 250px;
- font-size: 15px;
- z-index: 9;
+#container.aspect-1-1 #expander { padding-bottom: 100%; }
+#container.aspect-4-3 #expander, #container:not(.fullsize) #expander {
+ padding-bottom: 75%; /* default */
}
+#container.aspect-3-4 #expander { padding-bottom: 133.3333%; }
+#container.aspect-3-2 #expander { padding-bottom: 66.6667%; }
+#container.aspect-2-3 #expander { padding-bottom: 150%; }
+#container.aspect-16-9 #expander { padding-bottom: 56.25% }
+#container.aspect-9-16 #expander { padding-bottom: 177.7778% }
+#container.aspect-2-1 #expander { padding-bottom: 50%; }
+#container.aspect-1-2 #expander { padding-bottom: 200%; }
+#module, pre#log {
+ max-width: 100%;
+ width: 100%;
+ height: 100%;
+ z-index: 10;
+ border-radius: 0.2rem; /*var(--border-radius)*/
+}
+#module {
+ margin-bottom: -0.25rem; /* otherwise there's scrollbar w/ fullsize (why?) */
+}
+#status, #status-description {
+ position: absolute;
+ text-align: center;
+ width: 100%;
+ z-index: 9;
+}
+#status {
+ top: 10%;
+ font-size: 1.5rem;
+ font-weight: 600;
+}
+#status-description {
+ top: 22.5%;
+ padding-left: 2rem;
+ padding-right: 2rem;
+}
#module.hidden {
- display: none;
+ display: none;
}
-
-#log {
- width: 640px;
- height: 480px;
- overflow-y: scroll;
- overflow-x: hidden;
- white-space: pre-wrap;
- z-index: 10;
- margin: 0;
+pre#log {
+ padding: 0.5rem 1rem;
+ overflow-x: auto;
+ margin-top: 0; /* stupid defaults */
+ color: #e6e6e6; /*var(--code-color)*/
+ background-color: #282e36; /*var(--code-background-color)*/
+ font-size: 0.8rem; /* so 80 columns fits into 640 pixels */
}
+
+/* kate: indent-width 2; */
diff --git a/src/Magnum/Platform/WindowlessEmscriptenApplication.js b/src/Magnum/Platform/WindowlessEmscriptenApplication.js
index 64fea5f67..1484b5673 100644
--- a/src/Magnum/Platform/WindowlessEmscriptenApplication.js
+++ b/src/Magnum/Platform/WindowlessEmscriptenApplication.js
@@ -1,9 +1,36 @@
+/*
+ This file is part of Magnum.
+
+ Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
+ Vladimír Vondruš
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
var Module = {
preRun: [],
postRun: [],
arguments: [],
+ doNotCaptureKeyboard: true,
+
printErr: function(message) {
var log = document.getElementById('log');
log.innerHTML += Array.prototype.slice.call(arguments).join(' ') + '\n';
@@ -14,6 +41,8 @@ var Module = {
log.innerHTML += Array.prototype.slice.call(arguments).join(' ') + '\n';
},
+ /* onAbort not handled here, as the output is printed directly on the page */
+
canvas: document.getElementById('module'),
setStatus: function(message) {
@@ -22,7 +51,7 @@ var Module = {
},
setStatusDescription: function(message) {
- var statusDescription = document.getElementById('statusDescription');
+ var statusDescription = document.getElementById('status-description');
if(statusDescription) statusDescription.innerHTML = message;
},
@@ -33,9 +62,9 @@ var Module = {
if(left) {
Module.setStatus('Downloading...');
- Module.setStatusDescription((this.totalDependencies - left) + '/' + this.totalDependencies);
+ Module.setStatusDescription((this.totalDependencies - left) + ' / ' + this.totalDependencies);
} else {
- Module.setStatus('');
+ Module.setStatus('Download complete');
Module.setStatusDescription('');
document.getElementById('log').style.display = 'block';
}
@@ -57,9 +86,4 @@ for(var i = 0; i != args.length; ++i) {
}
Module.setStatus('Downloading...');
-
document.getElementById('log').style.display = 'none';
-
-if(Module.canvas) Module.canvas.addEventListener('contextmenu', function(event) {
- event.preventDefault();
-}, true);
diff --git a/src/Magnum/Platform/gl-info.html b/src/Magnum/Platform/gl-info.html
index d845b4d67..5041a6836 100644
--- a/src/Magnum/Platform/gl-info.html
+++ b/src/Magnum/Platform/gl-info.html
@@ -1,19 +1,22 @@
-
-
- Magnum GL Info
-
-
-
-
- Magnum GL Info
-
+
+
+
+
Magnum GL Info
+
+
+
+
+
Magnum GL Info
+
+
+