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:
parent
edafee7b22
commit
2ba681573f
5 changed files with 178 additions and 104 deletions
File diff suppressed because one or more lines are too long
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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>→</kbd> / <kbd>←</kbd>: {{ _("X Axis") }} +/-<br>
|
||||
<kbd>↑</kbd> / <kbd>↓</kbd>: {{ _("Y Axis") }} +/-<br>
|
||||
<kbd>W</kbd>, <kbd>{{ _("Page↑") }}</kbd> / <kbd>S</kbd>, <kbd>{{ _("Page↓") }}</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') }} (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">
|
||||
|
|
|
|||
Loading…
Reference in a new issue