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;
|
2013-12-06 17:32:32 +00:00
|
|
|
backgroundPage.app_window = window;
|
2013-06-19 11:06:14 +00:00
|
|
|
});
|
|
|
|
|
2014-04-21 22:30:22 +00:00
|
|
|
// Google Analytics BEGIN
|
|
|
|
var ga_config; // google analytics config reference
|
|
|
|
var ga_tracking; // global result of isTrackingPermitted
|
|
|
|
|
2013-08-26 12:41:10 +00:00
|
|
|
var service = analytics.getService('ice_cream_app');
|
2014-04-21 22:30:22 +00:00
|
|
|
service.getConfig().addCallback(function(config) {
|
|
|
|
ga_config = config;
|
|
|
|
ga_tracking = config.isTrackingPermitted();
|
|
|
|
});
|
|
|
|
|
2013-08-26 12:41:10 +00:00
|
|
|
var ga_tracker = service.getTracker('UA-32728876-6');
|
|
|
|
|
|
|
|
ga_tracker.sendAppView('Application Started');
|
2014-04-21 22:30:22 +00:00
|
|
|
// Google Analytics END
|
2013-06-13 11:11:53 +00:00
|
|
|
|
2013-12-18 13:57:27 +00:00
|
|
|
$(document).ready(function() {
|
2014-03-28 23:59:39 +00:00
|
|
|
// translate to user-selected language
|
|
|
|
localize();
|
|
|
|
|
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>');
|
2014-02-10 19:01:08 +00:00
|
|
|
|
|
|
|
// 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];
|
2014-02-10 19:01:08 +00:00
|
|
|
break;
|
|
|
|
case 'ChromeOS':
|
|
|
|
break;
|
|
|
|
case 'Linux':
|
|
|
|
break;
|
|
|
|
case 'UNIX':
|
|
|
|
break;
|
|
|
|
}
|
2014-03-08 05:25:15 +00:00
|
|
|
|
2014-01-18 18:21:30 +00:00
|
|
|
// Tabs
|
2014-07-10 16:14:17 +00:00
|
|
|
var ui_tabs = $('#tabs > ul');
|
|
|
|
$('a', ui_tabs).click(function() {
|
2014-07-09 14:10:02 +00:00
|
|
|
if ($(this).parent().hasClass('active') == false && !GUI.tab_switch_in_progress) { // only initialize when the tab isn't already active
|
2014-04-21 22:30:22 +00:00
|
|
|
var self = this;
|
|
|
|
var index = $(self).parent().index();
|
2014-06-20 09:07:43 +00:00
|
|
|
var tab = $(self).parent().prop('class');
|
2014-04-21 22:30:22 +00:00
|
|
|
|
|
|
|
// if there is no active connection, return
|
2014-06-20 09:07:43 +00:00
|
|
|
if (!configuration_received && tab != 'tab_logging') {
|
|
|
|
GUI.log('You need to <strong>connect</strong> before you can view any of the tabs');
|
2013-04-08 19:10:47 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-03-08 05:25:15 +00:00
|
|
|
|
2014-07-09 14:10:02 +00:00
|
|
|
GUI.tab_switch_in_progress = true;
|
|
|
|
|
2013-11-09 05:14:21 +00:00
|
|
|
GUI.tab_switch_cleanup(function() {
|
2013-12-09 18:34:34 +00:00
|
|
|
// disable previously active tab highlight
|
2014-07-10 16:14:17 +00:00
|
|
|
$('li', ui_tabs).removeClass('active');
|
2014-03-08 05:25:15 +00:00
|
|
|
|
2013-12-09 18:34:34 +00:00
|
|
|
// Highlight selected tab
|
2013-11-09 05:14:21 +00:00
|
|
|
$(self).parent().addClass('active');
|
2014-03-08 05:25:15 +00:00
|
|
|
|
2014-03-15 14:43:08 +00:00
|
|
|
// detach listeners and remove element data
|
|
|
|
$('#content').empty();
|
|
|
|
|
2013-12-09 18:34:34 +00:00
|
|
|
switch (tab) {
|
|
|
|
case 'tab_initial_setup':
|
2014-07-10 16:14:17 +00:00
|
|
|
tabs.initial_setup.initialize();
|
2013-12-09 18:34:34 +00:00
|
|
|
break;
|
|
|
|
case 'tab_pid_tuning':
|
2014-07-10 16:14:17 +00:00
|
|
|
tabs.pid_tuning.initialize();
|
2013-12-09 18:34:34 +00:00
|
|
|
break;
|
|
|
|
case 'tab_receiver':
|
2014-07-10 16:20:09 +00:00
|
|
|
tabs.receiver.initialize();
|
2013-12-09 18:34:34 +00:00
|
|
|
break;
|
|
|
|
case 'tab_auxiliary_configuration':
|
2014-07-10 16:22:50 +00:00
|
|
|
tabs.auxiliary_configuration.initialize();
|
2013-12-09 18:34:34 +00:00
|
|
|
break;
|
|
|
|
case 'tab_servos':
|
2014-07-10 16:24:56 +00:00
|
|
|
tabs.servos.initialize();
|
2013-12-09 18:34:34 +00:00
|
|
|
break;
|
|
|
|
case 'tab_gps':
|
2014-01-24 16:06:54 +00:00
|
|
|
tab_initialize_gps();
|
2013-12-09 18:34:34 +00:00
|
|
|
break;
|
|
|
|
case 'tab_motor_outputs':
|
2014-01-24 16:06:54 +00:00
|
|
|
tab_initialize_motor_outputs();
|
2013-12-09 18:34:34 +00:00
|
|
|
break;
|
|
|
|
case 'tab_sensors':
|
2014-01-24 16:06:54 +00:00
|
|
|
tab_initialize_sensors();
|
2014-03-08 05:25:15 +00:00
|
|
|
break;
|
2013-12-09 18:34:34 +00:00
|
|
|
case 'tab_cli':
|
2014-01-24 16:06:54 +00:00
|
|
|
tab_initialize_cli();
|
2014-03-08 05:25:15 +00:00
|
|
|
break;
|
2014-05-22 10:13:16 +00:00
|
|
|
case 'tab_logging':
|
|
|
|
tab_initialize_logging();
|
|
|
|
break;
|
2013-11-09 05:14:21 +00:00
|
|
|
}
|
2014-07-09 14:10:02 +00:00
|
|
|
|
|
|
|
GUI.tab_switch_in_progress = false;
|
2013-11-09 05:14:21 +00:00
|
|
|
});
|
2013-04-08 19:10:47 +00:00
|
|
|
}
|
|
|
|
});
|
2014-03-08 05:25:15 +00:00
|
|
|
|
2014-07-10 16:14:17 +00:00
|
|
|
tabs.default.initialize();
|
2014-03-08 05:25:15 +00:00
|
|
|
|
2014-04-22 14:16:22 +00:00
|
|
|
// options
|
|
|
|
$('a#options').click(function() {
|
|
|
|
var el = $(this);
|
|
|
|
|
|
|
|
if (!el.hasClass('active')) {
|
|
|
|
el.addClass('active');
|
|
|
|
el.after('<div id="options-window"></div>');
|
|
|
|
$('div#options-window').load('./tabs/options.html', function() {
|
|
|
|
ga_tracker.sendAppView('Options');
|
|
|
|
|
|
|
|
// translate to user-selected language
|
|
|
|
localize();
|
|
|
|
|
|
|
|
// if notifications are enabled, or wasn't set, check the notifications checkbox
|
|
|
|
chrome.storage.local.get('update_notify', function(result) {
|
|
|
|
if (typeof result.update_notify === 'undefined' || result.update_notify) {
|
|
|
|
$('div.notifications input').prop('checked', true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$('div.notifications input').change(function() {
|
|
|
|
var check = $(this).is(':checked');
|
|
|
|
|
|
|
|
chrome.storage.local.set({'update_notify': check});
|
|
|
|
});
|
|
|
|
|
|
|
|
// if tracking is enabled, check the statistics checkbox
|
|
|
|
if (ga_tracking == true) {
|
|
|
|
$('div.statistics input').prop('checked', true);
|
|
|
|
}
|
|
|
|
|
|
|
|
$('div.statistics input').change(function() {
|
|
|
|
var check = $(this).is(':checked');
|
|
|
|
|
|
|
|
ga_tracking = check;
|
|
|
|
|
|
|
|
ga_config.setTrackingPermitted(check);
|
|
|
|
});
|
|
|
|
|
|
|
|
$(this).slideDown();
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
$('div#options-window').slideUp(function() {
|
|
|
|
el.removeClass('active');
|
|
|
|
$(this).empty().remove();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-01-15 23:55:45 +00:00
|
|
|
// listen to all input change events and adjust the value within limits if necessary
|
2014-01-24 15:44:08 +00:00
|
|
|
$("#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
|
|
|
|
2014-01-24 15:44:08 +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
|
2014-06-05 14:08:20 +00:00
|
|
|
} else if (e.keyCode == 109 || e.keyCode == 189) { // minus on numpad and in standard keyboard
|
2014-01-29 19:22:14 +00:00
|
|
|
} else if (e.keyCode == 8 || e.keyCode == 46) { // backspace and delete
|
2014-01-24 15:44:08 +00:00
|
|
|
} 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
|
|
|
|
2014-01-24 15:44:08 +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-01-15 19:25:51 +00:00
|
|
|
}
|
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-01-15 19:25:51 +00:00
|
|
|
}
|
2014-03-08 05:25:15 +00:00
|
|
|
|
2014-01-29 19:22:14 +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
|
|
|
|
2014-01-29 19:22:14 +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));
|
|
|
|
}
|
|
|
|
}
|
2014-01-15 19:25:51 +00:00
|
|
|
});
|
2013-11-08 17:31:19 +00:00
|
|
|
});
|
|
|
|
|
2013-11-13 08:49:03 +00:00
|
|
|
function microtime() {
|
|
|
|
var now = new Date().getTime() / 1000;
|
|
|
|
|
|
|
|
return now;
|
2013-11-20 11:24:37 +00:00
|
|
|
}
|
|
|
|
|
2014-04-12 12:55:20 +00:00
|
|
|
function millitime() {
|
|
|
|
var now = new Date().getTime();
|
|
|
|
|
|
|
|
return now;
|
|
|
|
}
|
|
|
|
|
2014-06-25 07:18:01 +00:00
|
|
|
function bytesToSize(bytes) {
|
2014-06-25 07:42:36 +00:00
|
|
|
if (bytes < 1024) return bytes + ' Bytes';
|
|
|
|
else if (bytes < 1048576) return(bytes / 1024).toFixed(3) + ' KB';
|
|
|
|
else if (bytes < 1073741824) return(bytes / 1048576).toFixed(3) + ' MB';
|
|
|
|
else return (bytes / 1073741824).toFixed(3) + ' GB';
|
2014-06-25 07:18:01 +00:00
|
|
|
}
|
|
|
|
|
2014-01-23 22:47:14 +00:00
|
|
|
/*
|
2014-01-22 14:36:34 +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
|
|
|
|
2014-01-22 14:36:34 +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-01-22 14:36:34 +00:00
|
|
|
}
|
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-22 14:36:34 +00:00
|
|
|
});
|
2014-01-23 22:47:14 +00:00
|
|
|
}
|
|
|
|
*/
|