Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor function buttons #71

Closed
30 changes: 15 additions & 15 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html HTML>
<html lang="en">
<!--
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -36,17 +36,18 @@
<link href="css/jquery.rotaryswitch.css" rel="stylesheet" type="text/css">
<link href="css/icons.css" rel="stylesheet" type="text/css">
<link href="css/settings.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/roundslider.min.js"></script>
<script type="text/javascript" src="js/jquery.rotaryswitch.js"></script>
<script type="text/javascript" src="js/fnMaster.js"></script>
<script type="text/javascript" src="js/commandController.js"></script>
<script type="text/javascript" src="js/storageController.js"></script>
<script type="text/javascript" src="js/addloco.js"></script>
<script type="text/javascript" src="js/emulator.js"></script>
<script type="text/javascript" src="js/exwebthrottle.js"></script>
<script type="text/javascript" src="js/vendor/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="js/vendor/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/vendor/roundslider.min.js"></script>
<script type="text/javascript" src="js/vendor/jquery.rotaryswitch.js"></script>
<script type="text/javascript" src="js/fnMaster.js"></script>
<script type="text/javascript" src="js/commandController.js"></script>
<script type="text/javascript" src="js/storageController.js"></script>
<script type="text/javascript" src="js/addloco.js"></script>
<script type="text/javascript" src="js/emulator.js"></script>
<script type="text/javascript" src="js/exwebthrottle.js"></script>
<script type="text/javascript" src="js/pwa.js"></script>
<script src="js/ui/functionButtons.js" type="module"></script>

<!--
NOTE: You can replace the above links with these if you like if you will always run when
Expand All @@ -61,7 +62,6 @@

<title>DCC++ EX Web Throttle</title>
<meta name="description" content="Chromium browser based web throttle for a DCC++ EX Command Station to control model trains">
<html lang="en">
</head>

<body>
Expand Down Expand Up @@ -179,7 +179,7 @@
<div class="dir-toggle">
<button class="dir-btn forward selected" id="dir-f" aria-label="forward" ><span class="arrow-up icon-up"></span></button>
<button class="dir-btn stop" id="dir-S" aria-label="stop"> <span class="stop"></span></button>
<button class="dir-btn backward" id="dir-b" aria-label="backward"> <span class="arrow-down icon-down"></button>
<button class="dir-btn backward" id="dir-b" aria-label="backward"> <span class="arrow-down icon-down"></span></button>
</div>
</div>
</div>
Expand Down Expand Up @@ -289,8 +289,8 @@ <h4 class="fn-heading add-loco-head">Add Locomotive</h4>
<input class="column-6" type="text" id="decoder" placeholder="Decoder Name" name="decoder">
</div>
<div class="row">
<label class="column-4"for="map">Function map:*</label>
<input id="function-maps" class="column-6" type="text" id="map" placeholder="Select Map" name="map" required>
<label class="column-4" for="function-maps">Function map:*</label>
<input id="function-maps" class="column-6" type="text" placeholder="Select Map" name="map" required>
</div>
<div class="spacer">

Expand Down
76 changes: 17 additions & 59 deletions js/commandController.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,25 @@ async function readLoop() {
}

function writeToStream(...lines) {
// Stops data being written to nonexistent port if using emulator
let stream = emulatorClass
if (port) {
stream = outputStream.getWriter();
}
const commandLines = lines.map(line => `<${line}>\n`)
writeRawToStream(...commandLines)
}

lines.forEach((line) => {
if (line == "\x03" || line == "echo(false);") {
function writeRawToStream(...lines) {
let stream = emulatorClass
if (port) {
stream = outputStream.getWriter();
}

} else {
displayLog('[SEND]'+line.toString());
}
const packet = `<${line}>\n`;
stream.write(packet)
console.log(packet)
});
lines.forEach((line) => {
if (line == "\x03" || line == "echo(false);") {

} else {
displayLog('[SEND]'+line.toString());
}
stream.write(line)
console.log(line)
});
}

// Transformer for the Web Serial API. Data comes in as a stream so we
Expand Down Expand Up @@ -223,48 +226,3 @@ function displayLog(data){
$("#log-box").append("<br>"+data.toString()+"<br>");
$("#log-box").scrollTop($("#log-box").prop("scrollHeight"));
}

// Function to generate commands for functions F0 to F4
function sendCommandForF0ToF4(fn, opr){
setFunCurrentVal(fn,opr);
cabval = (128+getFunCurrentVal("f1")*1 + getFunCurrentVal("f2")*2 + getFunCurrentVal("f3")*4 + getFunCurrentVal("f4")*8 + getFunCurrentVal("f0")*16);
writeToStream("f "+getCV()+" "+cabval);
console.log("Command: "+ "f "+getCV()+" "+cabval);

}

// Function to generate commands for functions F5 to F8
function sendCommandForF5ToF8(fn, opr){
setFunCurrentVal(fn,opr);
cabval = (176+getFunCurrentVal("f5")*1 + getFunCurrentVal("f6")*2 + getFunCurrentVal("f7")*4 + getFunCurrentVal("f8")*8);
writeToStream("f "+getCV()+" "+cabval);
console.log("Command: "+ "f "+getCV()+" "+cabval);

}

// Function to generate commands for functions F9 to F12
function sendCommandForF9ToF12(fn, opr){
setFunCurrentVal(fn,opr);
cabval = (160+getFunCurrentVal("f9")*1 + getFunCurrentVal("f10")*2 + getFunCurrentVal("f11")*4 + getFunCurrentVal("f12")*8);
writeToStream("f "+getCV()+" "+cabval);
console.log("Command: "+ "f "+getCV()+" "+cabval);

}

// Function to generate commands for functions F13 to F20
function sendCommandForF13ToF20(fn, opr){
setFunCurrentVal(fn,opr);
cabval = (getFunCurrentVal("f13")*1 + getFunCurrentVal("f14")*2 + getFunCurrentVal("f15")*4 + getFunCurrentVal("f16")*8 + getFunCurrentVal("f17")*16 + getFunCurrentVal("f18")*32 + getFunCurrentVal("f19")*64 + getFunCurrentVal("f20")*128);
writeToStream("f "+getCV()+" 222 "+cabval);
console.log("Command: "+ "f "+getCV()+" 222 "+cabval);

}

// Function to generate commands for functions F21 to F28
function sendCommandForF21ToF28(fn, opr){
setFunCurrentVal(fn,opr);
cabval = (getFunCurrentVal("f21")*1 + getFunCurrentVal("f22")*2 + getFunCurrentVal("f23")*4 + getFunCurrentVal("f24")*8 + getFunCurrentVal("f25")*16 + getFunCurrentVal("f26")*32 + getFunCurrentVal("f27")*64 + getFunCurrentVal("f28")*128);
writeToStream("f "+getCV()+" 223 "+cabval);
console.log("Command: "+ "f "+getCV()+" 223 "+cabval);

}
128 changes: 1 addition & 127 deletions js/exwebthrottle.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,92 +319,6 @@ function setSpeedofControllers(){
knob.val(spd).change();
}

// This function will generate commands for each type of function
function generateFnCommand(clickedBtn){

func = clickedBtn.attr('name'); // Gives function name (F1, F2, .... F28)
eventType = clickedBtn.data("type"); // Gives type of button (Press/Hold or Toggle)
btnPressed = clickedBtn.attr("aria-pressed");
//console.log("Function Name=>"+func+" , Button Type=>"+eventType+" , Button Pressed=>"+btnStatus);

switch(func){
case "f0":
case "f1":
case "f2":
case "f3":
case "f4":
{
if(btnPressed=="true"){
sendCommandForF0ToF4(func,1);
}else{
sendCommandForF0ToF4(func,0);
}
break;
}
case "f5":
case "f6":
case "f7":
case "f8":
{
if(btnPressed=="true"){
sendCommandForF5ToF8(func,1);
}else{
sendCommandForF5ToF8(func,0);
}
break;
}
case "f9":
case "f10":
case "f11":
case "f12":
{
if(btnPressed=="true"){
sendCommandForF9ToF12(func,1);
}else{
sendCommandForF9ToF12(func,0);
}
break;
}
case "f13":
case "f14":
case "f15":
case "f16":
case "f17":
case "f18":
case "f19":
case "f20":
{
if(btnPressed=="true"){
sendCommandForF13ToF20(func,1);
}else{
sendCommandForF13ToF20(func,0);
}
break;
}
case "f21":
case "f22":
case "f23":
case "f24":
case "f25":
case "f26":
case "f27":
case "f28":
{
if(btnPressed=="true"){
sendCommandForF21ToF28(func,1);
}else{
sendCommandForF21ToF28(func,0);
}
break;
}
default:
{
alert("Invalid Function");
}

}
}

$(document).ready(function(){
var mode = 0;
// Left Menu
Expand Down Expand Up @@ -709,47 +623,7 @@ $(document).ready(function(){
}
});

// Functions buttons
// Send Instructions to generate command depends the type of Button (press/toggle)
var timer = 0;
$(document)
.on("mousedown", ".fn-btn", function () {
console.log($(this).val);
clickedBtn = $(this);
btnType = clickedBtn.data("type");
if (btnType == "press") {
timer = setInterval(function () {
// MOMENTARY HOLD ON
clickedBtn.attr("aria-pressed", "true");
generateFnCommand(clickedBtn);
console.log("PRESSED HOLD ==> " + clickedBtn.attr("name"));
}, 100);
}
})
.on("mouseup mouserelease", ".fn-btn", function () {
clearInterval(timer);
clickedBtn = $(this);
btnType = clickedBtn.data("type");
btnState = clickedBtn.attr("aria-pressed");
if (btnType == "press") {
// MOMENTARY HOLD OFF
clickedBtn.attr("aria-pressed", "false");
generateFnCommand(clickedBtn);
console.log("RELEASED HOLD ==> " + clickedBtn.attr("name"));
} else {
if (btnState == "false") {
// TOGGLE ON
clickedBtn.attr("aria-pressed", "true");
generateFnCommand(clickedBtn);
console.log("TOGGLE ON ==> " + clickedBtn.attr("name"));
} else {
// TOGGLE OFF
clickedBtn.attr("aria-pressed", "false");
generateFnCommand(clickedBtn);
console.log("TOGGLE OFF ==> " + clickedBtn.attr("name"));
}
}
});


// Hide/Show the Debug console
$("#console-toggle").on("click", function () {
Expand Down
82 changes: 82 additions & 0 deletions js/ui/functionButtons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {cabCommand} from "../vendor/dcc-ex--commands-0.10.0.js"

function sendCabCommand(fn, value) {
setFunCurrentVal(fn, value);
const cab = getCV()
const func = fn.replace("f", "")
const command = cabCommand({cab, func, value})
writeRawToStream(command)
}

function generateFnCommand(funcName, btnPressed) {
const value = btnPressed ? 1 : 0

sendCabCommand(funcName, value)
}

function toggleButtonState(previousBtnState, buttonElement) {
const newBtnState = previousBtnState === 'false'
buttonElement.ariaPressed = newBtnState
buttonElement.setAttribute("aria-pressed", newBtnState) // Firefox support https://developer.mozilla.org/en-US/docs/Web/API/Element/ariaPressed
return newBtnState;
}

const buttonPressIntervals = {}

function functionButtonPressed(buttonElement) {
const {name, ariaPressed, dataset: {type: buttonType}} = buttonElement

if (buttonType !== "press") {
return
}

const newBtnState = toggleButtonState(ariaPressed, buttonElement);

console.debug("PRESSED HOLD ==> " + name);
generateFnCommand(name, newBtnState);

buttonPressIntervals[buttonElement.id] = setInterval(function () {
// MOMENTARY HOLD ON
console.debug("PRESSED HOLD ==> " + name);
generateFnCommand(name, newBtnState);
}, 100);
}

function functionButtonReleased(buttonElement) {
clearInterval(buttonPressIntervals[buttonElement.id]);
const {name, ariaPressed, dataset: {type: buttonType}} = buttonElement
const newBtnState = toggleButtonState(ariaPressed, buttonElement);

if (buttonType === "press") {
console.debug("RELEASED HOLD ==> " + name);
} else {
const action = newBtnState ? "ON" : "OFF"
console.debug(`TOGGLE ${action} ==> ` + name);
}

generateFnCommand(name, newBtnState);
}

function isFunctionButton(target) {
return [...target.classList].includes("fn-btn");
}

// Functions buttons
// Send Instructions to generate command depends the type of Button (press/toggle)
const fnWrapperElement = document.getElementById("fn-wrapper")

if (fnWrapperElement) {
fnWrapperElement.addEventListener("mousedown", (event) => {
const {target} = event
if (isFunctionButton(target)) {
functionButtonPressed(target)
}
})
fnWrapperElement.addEventListener("mouseup", (event) => {
const {target} = event
if (isFunctionButton(target)) {
functionButtonReleased(target)
}
})
}

Loading