Support "full-screen" mode to the extent that supported browsers support it (and thanks for your support!)
This commit is contained in:
parent
d6b4b9c438
commit
8dadbb2da9
4 changed files with 95 additions and 21 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
||||||
<control type="led" label="Scroll" binding="scroll-lock" padleft="8px"/>
|
<control type="led" label="Scroll" binding="scroll-lock" padleft="8px"/>
|
||||||
<control type="button" binding="lockPointer" padleft="8px">Lock Pointer</control>
|
<control type="button" binding="lockPointer" padleft="8px">Lock Pointer</control>
|
||||||
|
<control type="button" binding="fullScreen" padleft="8px">Full Screen</control>
|
||||||
</control>
|
</control>
|
||||||
</menu>
|
</menu>
|
||||||
</video>
|
</video>
|
||||||
|
|
|
||||||
|
|
@ -134,20 +134,20 @@ function Keyboard(parmsKbd)
|
||||||
this.msAutoRelease = 50;
|
this.msAutoRelease = 50;
|
||||||
this.msInjectDelay = 300; // number of milliseconds between injected keystrokes
|
this.msInjectDelay = 300; // number of milliseconds between injected keystrokes
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HACK: We set fAllDown to false to ignore all down/up events for keys not explicitly marked as ONDOWN;
|
||||||
|
* even though that prevents those keys from being repeated properly (ie, at the simulation's repeat rate
|
||||||
|
* rather than the browser's repeat rate), it's the safest thing to do when dealing with international keyboards,
|
||||||
|
* because our mapping tables are designed for US keyboards, and testing all the permutations of international
|
||||||
|
* keyboards and web browsers is more work than I can take on right now. TODO: Dig into this some day.
|
||||||
|
*/
|
||||||
|
this.fAllDown = false;
|
||||||
|
|
||||||
this.setReady();
|
this.setReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.subclass(Component, Keyboard);
|
Component.subclass(Component, Keyboard);
|
||||||
|
|
||||||
/*
|
|
||||||
* HACK: We set ALL_ONDOWN to false to ignore all down/up events for keys not explicitly marked as ONDOWN;
|
|
||||||
* even though that prevents those keys from being repeated properly (ie, at the simulation's repeat rate
|
|
||||||
* rather than the browser's repeat rate), it's the safest thing to do when dealing with international keyboards,
|
|
||||||
* because our mapping tables are designed for US keyboards, and testing all the permutations of international
|
|
||||||
* keyboards and web browsers is more work than I can take on right now. TODO: Dig into this some day.
|
|
||||||
*/
|
|
||||||
Keyboard.ALL_ONDOWN = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alphanumeric and other common (printable) ASCII codes.
|
* Alphanumeric and other common (printable) ASCII codes.
|
||||||
*
|
*
|
||||||
|
|
@ -1128,16 +1128,18 @@ Keyboard.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* notifyEscape(fDisabled)
|
* notifyEscape(fDisabled, fAllDown)
|
||||||
*
|
*
|
||||||
* When ESC is used by the browser to disable pointer lock, this gives us the option of mapping a different key to ESC.
|
* When ESC is used by the browser to disable pointer lock, this gives us the option of mapping a different key to ESC.
|
||||||
*
|
*
|
||||||
* @this {Keyboard}
|
* @this {Keyboard}
|
||||||
* @param {boolean} fDisabled
|
* @param {boolean} fDisabled
|
||||||
|
* @param {boolean} [fAllDown] (an experimental option to re-enable processing of all onkeydown/onkeyup events)
|
||||||
*/
|
*/
|
||||||
Keyboard.prototype.notifyEscape = function(fDisabled)
|
Keyboard.prototype.notifyEscape = function(fDisabled, fAllDown)
|
||||||
{
|
{
|
||||||
this.fEscapeDisabled = fDisabled;
|
this.fEscapeDisabled = fDisabled;
|
||||||
|
if (fAllDown !== undefined) this.fAllDown = fAllDown;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2050,7 +2052,7 @@ Keyboard.prototype.onKeyDown = function(event, fDown)
|
||||||
/*
|
/*
|
||||||
* Don't simulate any key not explicitly marked ONDOWN, as well as any key sequence with the CMD key held.
|
* Don't simulate any key not explicitly marked ONDOWN, as well as any key sequence with the CMD key held.
|
||||||
*/
|
*/
|
||||||
if (!Keyboard.ALL_ONDOWN && fPass && fDown || !!(this.bitsState & Keyboard.STATE.CMDS)) fIgnore = true;
|
if (!this.fAllDown && fPass && fDown || !!(this.bitsState & Keyboard.STATE.CMDS)) fIgnore = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fPass) {
|
if (!fPass) {
|
||||||
|
|
@ -2093,7 +2095,7 @@ Keyboard.prototype.onKeyPress = function(event)
|
||||||
event = event || window.event;
|
event = event || window.event;
|
||||||
var keyCode = event.which || event.keyCode;
|
var keyCode = event.which || event.keyCode;
|
||||||
|
|
||||||
if (Keyboard.ALL_ONDOWN) {
|
if (this.fAllDown) {
|
||||||
var simCode = this.checkActiveKey();
|
var simCode = this.checkActiveKey();
|
||||||
if (simCode && this.isAlphaKey(simCode) && this.isAlphaKey(keyCode) && simCode != keyCode) {
|
if (simCode && this.isAlphaKey(simCode) && this.isAlphaKey(keyCode) && simCode != keyCode) {
|
||||||
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
if (!COMPILED && this.messageEnabled(Messages.KEYS)) {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
if (typeof module !== 'undefined') {
|
if (typeof module !== 'undefined') {
|
||||||
var web = require("./../../shared/lib/weblib");
|
var web = require("./../../shared/lib/weblib");
|
||||||
var Component = require("./../../shared/lib/component");
|
var Component = require("./../../shared/lib/component");
|
||||||
var Messages = require("./messages");
|
var Messages = require("./messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ if (typeof module !== 'undefined') {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Video(parmsVideo, canvas, context, textarea)
|
* Video(parmsVideo, canvas, context, textarea, container)
|
||||||
*
|
*
|
||||||
* The Video component can be configured with the following (parmsVideo) properties:
|
* The Video component can be configured with the following (parmsVideo) properties:
|
||||||
*
|
*
|
||||||
|
|
@ -93,8 +93,9 @@ if (typeof module !== 'undefined') {
|
||||||
* @param {Object} [canvas]
|
* @param {Object} [canvas]
|
||||||
* @param {Object} [context]
|
* @param {Object} [context]
|
||||||
* @param {Object} [textarea]
|
* @param {Object} [textarea]
|
||||||
|
* @param {Object} [container]
|
||||||
*/
|
*/
|
||||||
function Video(parmsVideo, canvas, context, textarea)
|
function Video(parmsVideo, canvas, context, textarea, container)
|
||||||
{
|
{
|
||||||
Component.call(this, "Video", parmsVideo, Video, Messages.VIDEO);
|
Component.call(this, "Video", parmsVideo, Video, Messages.VIDEO);
|
||||||
|
|
||||||
|
|
@ -192,6 +193,31 @@ function Video(parmsVideo, canvas, context, textarea)
|
||||||
this.fHasFocus = false;
|
this.fHasFocus = false;
|
||||||
|
|
||||||
var video = this;
|
var video = this;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All the gross code to handle full-screen support across all supported browsers (standards? hello?)
|
||||||
|
*/
|
||||||
|
this.container = container;
|
||||||
|
if (this.container) {
|
||||||
|
this.container.doFullScreen = container['requestFullscreen'] || container['msRequestFullscreen'] || container['mozRequestFullScreen'] || container['webkitRequestFullscreen'];
|
||||||
|
var onFullScreenChange = function() {
|
||||||
|
var fFullScreen = (document['fullscreenElement'] || document['mozFullScreenElement'] || document['webkitFullscreenElement'] || document['msFullscreenElement']);
|
||||||
|
video.notifyFullScreen(fFullScreen? true : false);
|
||||||
|
};
|
||||||
|
if ('onfullscreenchange' in document) {
|
||||||
|
document.addEventListener('fullscreenchange', onFullScreenChange, false);
|
||||||
|
} else if ('onmozfullscreenchange' in document) {
|
||||||
|
document.addEventListener('mozfullscreenchange', onFullScreenChange, false);
|
||||||
|
} else if ('onwebkitfullscreenchange' in document) {
|
||||||
|
document.addEventListener('webkitfullscreenchange', onFullScreenChange, false);
|
||||||
|
} else if ('onmsfullscreenchange' in document) {
|
||||||
|
document.addEventListener('msfullscreenchange', onFullScreenChange, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All the gross code to handle pointer-locking support across all supported browsers (standards? hello?)
|
||||||
|
*/
|
||||||
if (this.inputScreen) {
|
if (this.inputScreen) {
|
||||||
this.inputScreen.onfocus = function onFocusScreen() {
|
this.inputScreen.onfocus = function onFocusScreen() {
|
||||||
return video.onFocusChange(true);
|
return video.onFocusChange(true);
|
||||||
|
|
@ -2010,6 +2036,18 @@ Video.prototype.setBinding = function(sHTMLType, sBinding, control)
|
||||||
|
|
||||||
switch (sBinding) {
|
switch (sBinding) {
|
||||||
|
|
||||||
|
case "fullScreen":
|
||||||
|
if (this.container && this.container.doFullScreen) {
|
||||||
|
control.onclick = function onClickFullScreen() {
|
||||||
|
if (DEBUG) video.printMessage("fullScreen()");
|
||||||
|
video.doFullScreen();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if (DEBUG) this.log("FullScreen API not available");
|
||||||
|
control.parentNode.removeChild(control);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
case "lockPointer":
|
case "lockPointer":
|
||||||
this.sLockMessage = control.textContent;
|
this.sLockMessage = control.textContent;
|
||||||
if (this.inputScreen && this.inputScreen.lockPointer) {
|
if (this.inputScreen && this.inputScreen.lockPointer) {
|
||||||
|
|
@ -2062,6 +2100,39 @@ Video.prototype.getInput = function(mouse)
|
||||||
return this.inputScreen;
|
return this.inputScreen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* doFullScreen()
|
||||||
|
*
|
||||||
|
* @this {Video}
|
||||||
|
* @return {boolean} true if request successful, false if not (eg, failed OR not supported)
|
||||||
|
*/
|
||||||
|
Video.prototype.doFullScreen = function()
|
||||||
|
{
|
||||||
|
var fSuccess = false;
|
||||||
|
if (this.container) {
|
||||||
|
if (this.container.doFullScreen) {
|
||||||
|
this.container.style.width = this.container.style.height = "100%";
|
||||||
|
this.container.style.backgroundColor = "black";
|
||||||
|
this.container.doFullScreen();
|
||||||
|
fSuccess = true;
|
||||||
|
}
|
||||||
|
this.setFocus();
|
||||||
|
}
|
||||||
|
return fSuccess;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* notifyFullScreen(fFullScreen)
|
||||||
|
*
|
||||||
|
* @this {Video}
|
||||||
|
* @param {boolean} fFullScreen
|
||||||
|
*/
|
||||||
|
Video.prototype.notifyFullScreen = function(fFullScreen)
|
||||||
|
{
|
||||||
|
this.printMessage("notifyFullScreen(" + fFullScreen + ")", true);
|
||||||
|
if (this.kbd) this.kbd.notifyEscape(fFullScreen);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lockPointer()
|
* lockPointer()
|
||||||
*
|
*
|
||||||
|
|
@ -3753,10 +3824,10 @@ Video.prototype.setMode = function(nMode, fForce)
|
||||||
Video.prototype.setPixel = function(imageData, x, y, rgb)
|
Video.prototype.setPixel = function(imageData, x, y, rgb)
|
||||||
{
|
{
|
||||||
var index = (x + y * imageData.width) * rgb.length;
|
var index = (x + y * imageData.width) * rgb.length;
|
||||||
imageData.data[index + 0] = rgb[0];
|
imageData.data[index] = rgb[0];
|
||||||
imageData.data[index + 1] = rgb[1];
|
imageData.data[index+1] = rgb[1];
|
||||||
imageData.data[index + 2] = rgb[2];
|
imageData.data[index+2] = rgb[2];
|
||||||
imageData.data[index + 3] = rgb[3];
|
imageData.data[index+3] = rgb[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -5235,7 +5306,7 @@ Video.init = function()
|
||||||
* Now we can create the Video object, record it, and wire it up to the associated document elements.
|
* Now we can create the Video object, record it, and wire it up to the associated document elements.
|
||||||
*/
|
*/
|
||||||
var eContext = eCanvas.getContext("2d");
|
var eContext = eCanvas.getContext("2d");
|
||||||
var video = new Video(parmsVideo, eCanvas, eContext, eTextArea /* || eInput */);
|
var video = new Video(parmsVideo, eCanvas, eContext, eTextArea /* || eInput */, eVideo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;
|
* Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue