betaflight-configurator/main.js

291 lines
9.9 KiB
JavaScript
Raw Normal View History

2013-06-19 11:06:14 +00:00
// Get access to the background window object
// This object is used to pass current connectionId to the backround page
// so the onClosed event can close the port for us if it was left opened, without this
// users can experience weird behavior if they would like to access the serial bus afterwards.
chrome.runtime.getBackgroundPage(function(result) {
backgroundPage = result;
backgroundPage.app_window = window;
2013-06-19 11:06:14 +00:00
});
2013-08-26 12:41:10 +00:00
// Google Analytics stuff begin
var service = analytics.getService('ice_cream_app');
var ga_tracker = service.getTracker('UA-32728876-6');
ga_tracker.sendAppView('Application Started');
2014-03-08 05:25:15 +00:00
// Google Analytics stuff end
$(document).ready(function() {
// translate to user-selected language
localize();
2014-03-08 05:25:15 +00:00
// bind controls
$('#frame .minimize').click(function() {
chrome.app.window.current().minimize();
2014-03-08 05:25:15 +00:00
});
$('#frame .maximize').click(function() {
2014-02-22 08:52:28 +00:00
chrome.app.window.current().maximize();
});
2014-03-08 05:25:15 +00:00
$('#frame .close').click(function() {
chrome.app.window.current().close();
2014-02-03 05:21:26 +00:00
});
2014-03-08 05:25:15 +00:00
2014-02-03 05:21:26 +00:00
// alternative - window.navigator.appVersion.match(/Chrome\/([0-9.]*)/)[1];
2014-03-08 05:25:15 +00:00
GUI.log('Running - OS: <strong>' + GUI.operating_system + '</strong>, ' +
2014-02-03 08:38:16 +00:00
'Chrome: <strong>' + window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/,"$1") + '</strong>, ' +
'Configurator: <strong>' + chrome.runtime.getManifest().version + '</strong>');
// notification messages for various operating systems
switch (GUI.operating_system) {
case 'Windows':
break;
case 'MacOS':
2014-02-26 05:49:38 +00:00
// var main_chromium_version = window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/,"$1").split('.')[0];
break;
case 'ChromeOS':
break;
case 'Linux':
break;
case 'UNIX':
break;
}
2014-03-08 05:25:15 +00:00
// Tabs
2013-04-13 00:43:23 +00:00
var tabs = $('#tabs > ul');
2013-04-08 19:10:47 +00:00
$('a', tabs).click(function() {
if ($(this).parent().hasClass('active') == false) { // only initialize when the tab isn't already active
2014-01-18 11:09:12 +00:00
if (configuration_received == false) { // if there is no active connection, return
GUI.log('You need to connect before you can view any of the tabs', 'red');
2013-04-08 19:10:47 +00:00
return;
}
2014-03-08 05:25:15 +00:00
var self = this;
2014-03-08 05:25:15 +00:00
GUI.tab_switch_cleanup(function() {
2013-12-09 18:34:34 +00:00
// disable previously active tab highlight
$('li', tabs).removeClass('active');
2014-03-08 05:25:15 +00:00
2013-12-09 18:34:34 +00:00
// get tab class name (there should be only one class listed)
var tab = $(self).parent().prop('class');
2014-03-08 05:25:15 +00:00
2013-12-09 18:34:34 +00:00
// Highlight selected tab
$(self).parent().addClass('active');
2014-03-08 05:25:15 +00:00
// detach listeners and remove element data
$('#content').empty();
2013-12-09 18:34:34 +00:00
switch (tab) {
case 'tab_initial_setup':
tab_initialize_initial_setup();
2013-12-09 18:34:34 +00:00
break;
case 'tab_pid_tuning':
tab_initialize_pid_tuning();
2013-12-09 18:34:34 +00:00
break;
case 'tab_receiver':
tab_initialize_receiver();
2013-12-09 18:34:34 +00:00
break;
case 'tab_auxiliary_configuration':
tab_initialize_auxiliary_configuration();
2013-12-09 18:34:34 +00:00
break;
case 'tab_servos':
tab_initialize_servos();
2013-12-09 18:34:34 +00:00
break;
case 'tab_gps':
tab_initialize_gps();
2013-12-09 18:34:34 +00:00
break;
case 'tab_motor_outputs':
tab_initialize_motor_outputs();
2013-12-09 18:34:34 +00:00
break;
case 'tab_sensors':
tab_initialize_sensors();
2014-03-08 05:25:15 +00:00
break;
2013-12-09 18:34:34 +00:00
case 'tab_cli':
tab_initialize_cli();
2014-03-08 05:25:15 +00:00
break;
}
});
2013-04-08 19:10:47 +00:00
}
});
2014-03-08 05:25:15 +00:00
tab_initialize_default();
2014-03-08 05:25:15 +00:00
2014-01-15 23:55:45 +00:00
// listen to all input change events and adjust the value within limits if necessary
$("#content").on('focus', 'input[type="number"]', function() {
2014-01-16 00:58:07 +00:00
var element = $(this);
var val = element.val();
2014-03-08 05:25:15 +00:00
2014-01-16 00:58:07 +00:00
if (!isNaN(val)) {
element.data('previousValue', parseFloat(val));
}
});
2014-03-08 05:25:15 +00:00
$("#content").on('keydown', 'input[type="number"]', function(e) {
// whitelist all that we need for numeric control
if ((e.keyCode >= 96 && e.keyCode <= 105) || (e.keyCode >= 48 && e.keyCode <= 57)) { // allow numpad and standard number keypad
} else if(e.keyCode == 109 || e.keyCode == 189) { // minus on numpad and in standard keyboard
} else if (e.keyCode == 8 || e.keyCode == 46) { // backspace and delete
} else if (e.keyCode == 190 || e.keyCode == 110) { // allow and decimal point
} else if ((e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13) { // allow arrows, enter
} else {
// block everything else
e.preventDefault();
}
});
2014-03-08 05:25:15 +00:00
$("#content").on('change', 'input[type="number"]', function() {
2014-01-16 00:58:07 +00:00
var element = $(this);
var min = parseFloat(element.prop('min'));
var max = parseFloat(element.prop('max'));
var step = parseFloat(element.prop('step'));
var val = parseFloat(element.val());
2014-03-08 05:25:15 +00:00
2014-01-15 23:55:45 +00:00
// only adjust minimal end if bound is set
2014-01-16 00:58:07 +00:00
if (element.prop('min')) {
if (val < min) element.val(min);
}
2014-03-08 05:25:15 +00:00
2014-01-15 23:55:45 +00:00
// only adjust maximal end if bound is set
2014-01-16 00:58:07 +00:00
if (element.prop('max')) {
if (val > max) element.val(max);
}
2014-03-08 05:25:15 +00:00
2014-01-16 00:58:07 +00:00
// if entered value is illegal use previous value instead
if (isNaN(val)) {
element.val(element.data('previousValue'));
}
2014-03-08 05:25:15 +00:00
2014-01-16 00:58:07 +00:00
// if step is not set or step is int and value is float use previous value instead
if (isNaN(step) || step % 1 === 0) {
if (val % 1 !== 0) {
element.val(element.data('previousValue'));
}
}
2014-03-08 05:25:15 +00:00
// if step is set and is float and value is int, convert to float, keep decimal places in float according to step *experimental*
if (!isNaN(step) && step % 1 !== 0) {
var decimal_places = String(step).split('.')[1].length;
2014-03-08 05:25:15 +00:00
if (val % 1 === 0) {
element.val(val.toFixed(decimal_places));
} else if (String(val).split('.')[1].length != decimal_places) {
element.val(val.toFixed(decimal_places));
}
}
});
});
2013-11-13 08:49:03 +00:00
function microtime() {
var now = new Date().getTime() / 1000;
return now;
}
2014-01-23 22:47:14 +00:00
/*
function add_custom_spinners() {
var spinner_element = '<div class="spinner"><div class="up"></div><div class="down"></div></div>';
2014-03-08 05:25:15 +00:00
$('input[type="number"]').each(function() {
var input = $(this);
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
// only add new spinner if one doesn't already exist
if (!input.next().hasClass('spinner')) {
var isInt = true;
if (input.prop('step') == '') {
2014-01-22 15:02:55 +00:00
isInt = true;
} else {
2014-01-22 16:05:34 +00:00
if (input.prop('step').indexOf('.') == -1) {
isInt = true;
} else {
isInt = false;
}
}
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
// make space for spinner
input.width(input.width() - 16);
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
// add spinner
input.after(spinner_element);
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
// get spinner refference
var spinner = input.next();
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
// bind UI hooks to spinner
$('.up', spinner).click(function() {
up();
});
2014-03-08 05:25:15 +00:00
$('.up', spinner).mousedown(function() {
2014-01-22 16:05:34 +00:00
GUI.timeout_add('spinner', function() {
GUI.interval_add('spinner', function() {
up();
}, 100, true);
}, 250);
});
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
$('.up', spinner).mouseup(function() {
GUI.timeout_remove('spinner');
GUI.interval_remove('spinner');
});
2014-03-08 05:25:15 +00:00
$('.up', spinner).mouseleave(function() {
2014-01-22 16:05:34 +00:00
GUI.timeout_remove('spinner');
GUI.interval_remove('spinner');
});
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
$('.down', spinner).click(function() {
down();
});
2014-03-08 05:25:15 +00:00
$('.down', spinner).mousedown(function() {
2014-01-22 16:05:34 +00:00
GUI.timeout_add('spinner', function() {
GUI.interval_add('spinner', function() {
down();
}, 100, true);
}, 250);
});
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
$('.down', spinner).mouseup(function() {
GUI.timeout_remove('spinner');
GUI.interval_remove('spinner');
});
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
$('.down', spinner).mouseleave(function() {
GUI.timeout_remove('spinner');
GUI.interval_remove('spinner');
});
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
var up = function() {
if (isInt) {
var current_value = parseInt(input.val());
input.val(current_value + 1);
} else {
var current_value = parseFloat(input.val());
var step = parseFloat(input.prop('step'));
var step_decimals = input.prop('step').length - 2;
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
input.val((current_value + step).toFixed(step_decimals));
}
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
input.change();
};
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
var down = function() {
if (isInt) {
var current_value = parseInt(input.val());
input.val(current_value - 1);
} else {
var current_value = parseFloat(input.val());
var step = parseFloat(input.prop('step'));
var step_decimals = input.prop('step').length - 2;
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
input.val((current_value - step).toFixed(step_decimals));
}
2014-03-08 05:25:15 +00:00
2014-01-22 16:05:34 +00:00
input.change();
};
}
});
2014-01-23 22:47:14 +00:00
}
*/