Key controls are now enabled when you mouse over the webcam picture, indicated by an overlay

Also moved key control help in that overlay
This commit is contained in:
Gina Häußge 2015-01-12 09:40:45 +01:00
parent edafee7b22
commit 2ba681573f
5 changed files with 178 additions and 104 deletions

File diff suppressed because one or more lines are too long

View file

@ -26,6 +26,15 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
self.feedbackControlLookup = {};
self.keycontrolActive = ko.observable(false);
self.keycontrolHelpActive = ko.observable(false);
self.keycontrolPossible = ko.computed(function() {
return self.isOperational() && !self.isPrinting() && self.loginState.isUser() && !$.browser.mobile;
});
self.showKeycontrols = ko.computed(function() {
return self.keycontrolActive() && self.keycontrolPossible();
});
self.settings.printerProfiles.currentProfileData.subscribe(function() {
self._updateExtruderCount();
self.settings.printerProfiles.currentProfileData().extruder.count.subscribe(self._updateExtruderCount);
@ -236,9 +245,6 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
callback();
}
if (data === undefined)
return;
};
self.displayMode = function(customControl) {
@ -264,66 +270,109 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
self.requestData();
};
self.keycontrolText = ko.observable("Nothing");
self.onFocus = function(data, event) {
if (!self.settings.feature_keyboardControl()) return;
self.keycontrolActive(true);
};
self.onMouseOver = function(data, event) {
if (!self.settings.feature_keyboardControl()) return;
$("#webcam_container").focus();
self.keycontrolActive(true);
};
self.onMouseOut = function(data, event) {
if (!self.settings.feature_keyboardControl()) return;
$("#webcam_container").blur();
self.keycontrolActive(false);
};
self.toggleKeycontrolHelp = function() {
self.keycontrolHelpActive(!self.keycontrolHelpActive());
};
self.onKeyDown = function(data, event) {
if (!self.settings.feature_keyboardControl()) return;
var button = undefined;
var visualizeClick = true;
self.doKeyControl = function(data, event) {
switch(event.which) {
case 37: // left arrow key
event.preventDefault();
self.keycontrolText("Left (X-)");
self.sendJogCommand('x',-1);
return;
// X-
button = $("#control-xdec");
break;
case 38: // up arrow key
event.preventDefault();
self.keycontrolText("Up (Y+)");
self.sendJogCommand('y',1);
return;
// Y+
button = $("#control-yinc");
break;
case 39: // right arrow key
event.preventDefault();
self.keycontrolText("Right (X+)");
self.sendJogCommand('x',1);
return;
// X+
button = $("#control-xinc");
break;
case 40: // down arrow key
event.preventDefault();
self.keycontrolText("Down (Y-)");
self.sendJogCommand('y',-1);
return;
case 49: // number 1: Distance 0.1
event.preventDefault();
self.keycontrolText("Distance 0.1");
distbtn1.click();
return;
case 50: // number 2: Distance 1
event.preventDefault();
self.keycontrolText("Distance 1");
distbtn2.click();
return;
case 51: // number 3: Distance 10
event.preventDefault();
self.keycontrolText("Distance 10");
distbtn3.click();
return;
case 52: // number 4: Distance 100
event.preventDefault();
self.keycontrolText("Distance 100");
distbtn4.click();
return;
case 87: // w key: z lift up
event.preventDefault();
self.keycontrolText("Z Lift up (Z+)");
self.sendJogCommand('z',1);
return;
case 83: // s key: z lift down
event.preventDefault();
self.keycontrolText("Z Lift down (Z-)");
self.sendJogCommand('z',-1);
return;
// Y-
button = $("#control-ydec");
break;
case 49: // number 1
case 97: // numpad 1
// Distance 0.1
button = $("#control-distance01");
visualizeClick = false;
break;
case 50: // number 2
case 98: // numpad 2
// Distance 1
button = $("#control-distance1");
visualizeClick = false;
break;
case 51: // number 3
case 99: // numpad 3
// Distance 10
button = $("#control-distance10");
visualizeClick = false;
break;
case 52: // number 4
case 100: // numpad 4
// Distance 100
button = $("#control-distance100");
visualizeClick = false;
break;
case 33: // page up key
case 87: // w key
// z lift up
button = $("#control-zinc");
break;
case 34: // page down key
case 83: // s key
// z lift down
button = $("#control-zdec");
break;
case 36: // home key
// xy home
button = $("#control-xyhome");
break;
case 35: // end key
// z home
button = $("#control-zhome");
break;
default:
event.preventDefault();
self.keycontrolText("no known shortcut");
return false;
}
if (button === undefined) {
return false;
} else {
event.preventDefault();
if (visualizeClick) {
button.addClass("active");
setTimeout(function() {
button.removeClass("active");
}, 150);
}
button.click();
}
};
}

View file

@ -391,14 +391,6 @@ function GcodeViewModel(loginStateViewModel, settingsViewModel) {
} else {
var output = [];
output.push(gettext("Model size") + ": " + model.width.toFixed(2) + "mm × " + model.depth.toFixed(2) + "mm × " + model.height.toFixed(2) + "mm");
if (model.filament.length == 0) {
output.push(gettext("Total filament used") + ": " + model.filament.toFixed(2) + gettext("mm"));
} else {
for (var i = 0; i < model.filament.length; i++) {
output.push(gettext("Total filament used") + " (" + gettext("Tool") + " " + i + "): " + model.filament[i].toFixed(2) + gettext("mm"));
}
}
output.push(gettext("Estimated print time") + ": " + formatDuration(model.printTime));
output.push(gettext("Estimated layer height") + ": " + model.layerHeight.toFixed(2) + gettext("mm"));
output.push(gettext("Layer count") + ": " + model.layersPrinted.toFixed(0) + " " + gettext("printed") + ", " + model.layersTotal.toFixed(0) + " " + gettext("visited"));

View file

@ -410,6 +410,10 @@ ul.dropdown-menu li a {
#webcam_container {
width: 100%;
position: relative;
outline: none;
//min-height: 440px;
.flipH {
-webkit-transform: scaleX(-1);
@ -425,6 +429,40 @@ ul.dropdown-menu li a {
-webkit-transform: scaleX(-1) scaleY(-1);
-moz-transform: scaleX(-1) scaleY(-1);
}
.keycontrol_overlay {
position: absolute;
left: 10px;
right: 10px;
bottom: 10px;
background: rgba(0, 0, 0, 0.5);
font-size: 85%;
color: white;
padding: 0;
kbd {
border: 1px solid #eeeeee;
border-radius: 3px;
margin-left: 2px;
margin-right: 2px;
font-size: 90%;
padding: 2px;
min-width: 1em;
}
.keycontrol_overlay_heading {
position: relative;
padding: 10px;
font-weight: bold;
}
.keycontrol_overlay_column {
position: relative;
width: 45%;
padding: 10px;
float: left;
}
}
}
/** GCODE file manager */
@ -493,12 +531,14 @@ ul.dropdown-menu li a {
text-align: left;
}
.jog-panel > div {
text-align: center;
}
.jog-panel {
>div {
text-align: center;
}
.jog-panel > div.distance {
text-align: left;
>div.distance {
text-align: left;
}
}
.box {

View file

@ -353,8 +353,26 @@
</div>
<div class="tab-pane" id="control">
{% if webcamStream %}
<div id="webcam_container">
<div id="webcam_container" tabindex="0" data-bind="event: { keydown: onKeyDown, mouseover: onMouseOver, mouseout: onMouseOut, focus: onFocus }">
<img id="webcam_image" data-bind="css: { flipH: settings.webcam_flipH(), flipV: settings.webcam_flipV() }">
<div class="keycontrol_overlay" data-bind="visible: showKeycontrols">
<div class="keycontrol_overlay_heading">{{ _("Keyboard controls active") }} <a href="#" data-bind="click: toggleKeycontrolHelp"><i data-bind="css: { 'icon-chevron-down': !keycontrolHelpActive(), 'icon-chevron-up': keycontrolHelpActive() }"></i></a></div>
<div data-bind="visible: keycontrolHelpActive">
<div class="keycontrol_overlay_column">
<kbd>&rarr;</kbd> / <kbd>&larr;</kbd>: {{ _("X Axis") }} +/-<br>
<kbd>&uarr;</kbd> / <kbd>&darr;</kbd>: {{ _("Y Axis") }} +/-<br>
<kbd>W</kbd>, <kbd>{{ _("Page&uarr;") }}</kbd> / <kbd>S</kbd>, <kbd>{{ _("Page&darr;") }}</kbd>: {{ _("Z Axis") }} +/-
</div>
<div class="keycontrol_overlay_column">
<kbd>Home</kbd>: {{ _("Home X/Y") }}<br>
<kbd>End</kbd>: {{ _("Home Z") }}<br>
<kbd>1</kbd>, <kbd>2</kbd>, <kbd>3</kbd>, <kbd>4</kbd>: {{ _("Stepsize") }} 0.1, 1, 10, 100mm
</div>
</div>
</div>
</div>
<div data-bind="visible: keycontrolPossible">
<small>{{ _("Hint: If you move your mouse over the picture, you enter keyboard control mode.") }}</small>
</div>
{% endif %}
@ -363,66 +381,41 @@
<div class="jog-panel">
<h1>X/Y</h1>
<div>
<button class="btn box" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('y',1) }"><i class="icon-arrow-up"></i></button>
<button class="btn box" id="control-yinc" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('y',1) }"><i class="icon-arrow-up"></i></button>
</div>
<div>
<button class="btn box pull-left" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('x',-1) }"><i class="icon-arrow-left"></i></button>
<button class="btn box pull-left" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendHomeCommand(['x', 'y']) }"><i class="icon-home"></i></button>
<button class="btn box pull-left" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('x',1) }"><i class="icon-arrow-right"></i></button>
<button class="btn box pull-left" id="control-xdec" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('x',-1) }"><i class="icon-arrow-left"></i></button>
<button class="btn box pull-left" id="control-xyhome" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendHomeCommand(['x', 'y']) }"><i class="icon-home"></i></button>
<button class="btn box pull-left" id="control-xinc" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('x',1) }"><i class="icon-arrow-right"></i></button>
</div>
<div>
<button class="btn box" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('y',-1) }"><i class="icon-arrow-down"></i></button>
<button class="btn box" id="control-ydec" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('y',-1) }"><i class="icon-arrow-down"></i></button>
</div>
</div>
<!-- Z jogging control panel -->
<div class="jog-panel">
<h1>Z</h1>
<div>
<button class="btn box" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('z',1) }"><i class="icon-arrow-up"></i></button>
<button class="btn box" id="control-zinc" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('z',1) }"><i class="icon-arrow-up"></i></button>
</div>
<div>
<button class="btn box" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendHomeCommand(['z']) }"><i class="icon-home"></i></button>
<button class="btn box" id="control-zhome" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendHomeCommand(['z']) }"><i class="icon-home"></i></button>
</div>
<div>
<button class="btn box" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('z',-1) }"><i class="icon-arrow-down"></i></button>
<button class="btn box" id="control-zdec" data-bind="enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendJogCommand('z',-1) }"><i class="icon-arrow-down"></i></button>
</div>
</div>
<!-- Jog distance -->
<div class="distance">
<div class="btn-group" data-toggle="buttons-radio" id="jog_distance">
<button type="button" id="distbtn1" class="btn distance" data-distance="0.1" data-bind="enable: loginState.isUser()">0.1</button>
<button type="button" id="distbtn2" class="btn distance" data-distance="1" data-bind="enable: loginState.isUser()">1</button>
<button type="button" id="distbtn3" class="btn distance active" data-distance="10" data-bind="enable: loginState.isUser()">10</button>
<button type="button" id="distbtn4" class="btn distance" data-distance="100" data-bind="enable: loginState.isUser()">100</button>
<button type="button" id="control-distance01" class="btn distance" data-distance="0.1" data-bind="enable: loginState.isUser()">0.1</button>
<button type="button" id="control-distance1" class="btn distance" data-distance="1" data-bind="enable: loginState.isUser()">1</button>
<button type="button" id="control-distance10" class="btn distance active" data-distance="10" data-bind="enable: loginState.isUser()">10</button>
<button type="button" id="control-distance100" class="btn distance" data-distance="100" data-bind="enable: loginState.isUser()">100</button>
</div>
</div>
<!-- Shortcut Control -->
<div class="keycontrol">
<h1>{{ _('Key-Control') }}</h1>
<div class="keycontroltext">
<small>
{{ _('Arrow keys') }}:<br>
W, S:<br>
1-4:
</small>
</div>
<div class="keycontroltext">
<small>
<strong>X+,X-, Y+,Y-</strong><br>
<strong>{{ _('lift up/down (Z+,Z-)') }}</strong><br>
<strong>{{ _('Distance') }}&nbsp;(0.1, 1..)</strong>
</small>
</div>
<div class="keycontrolinput">
<input type="text" data-bind="value: $root.keycontrolText, valueUpdate: 'keyup', enable: isOperational() && !isPrinting() && loginState.isUser(), event: { keydown: doKeyControl }"></input>
</div>
<div class="keycontrol">
<em>{{ _('Click into Textfield and press key<br>for control') }}</em>
</div>
</div>
</div>
<!-- Extrusion control panel -->
<div class="jog-panel" style="display: none;" data-bind="visible: loginState.isUser">