Compare commits
171 Commits
Author | SHA1 | Date | |
---|---|---|---|
4827688635
|
|||
b71bc81c0d
|
|||
a6ddd48abb
|
|||
8c0161b181
|
|||
3cf1aa7f49
|
|||
313a069d4c | |||
34d974b03b | |||
1de52c939f | |||
950a1fb029 | |||
5a167091cc | |||
57a81dbee3 | |||
acaf6898fd | |||
37bbb9208d | |||
6b2ef81b12 | |||
1e5ee117c5 | |||
db4164f621 | |||
bfd645d7a1 | |||
99cf344d93
|
|||
291ff8ed80
|
|||
cda1a573d6
|
|||
6506f6fe1c
|
|||
eec13e4934
|
|||
81366af7f1
|
|||
1b7af71d29
|
|||
c02f357d84 | |||
fffe4a8641 | |||
585c1608b8
|
|||
5a6b92bb5f
|
|||
54aeaacf86 | |||
3afd518399
|
|||
65dc2d81a3 | |||
22f6b3922e | |||
e5475bc099 | |||
301fe0e906 | |||
36fce6bf25
|
|||
e0ee932fff
|
|||
71576d7686
|
|||
2b4141fed3
|
|||
c5dd493cb0
|
|||
daede8799a
|
|||
f00f7601f4
|
|||
bd7e324a31
|
|||
9764db9789
|
|||
681a00b3ed
|
|||
79046d7bd0
|
|||
4b0f8e86b4
|
|||
bcddcfc311
|
|||
fe45ed8010
|
|||
0323920a0d
|
|||
fcc80b5843
|
|||
9e5756ceef
|
|||
e317d25977
|
|||
75ec2590f6
|
|||
80621bda22
|
|||
c5c6e37dfb | |||
b03ea9ded7 | |||
a341052c40 | |||
acea3c7d4d | |||
79f509da74 | |||
bff259008f | |||
36cfe78205 | |||
2c6aaf82f4 | |||
043ba99ea9 | |||
3c69f013fc | |||
650411bac4 | |||
b66d41a98b | |||
218ebc67d9 | |||
70288fc69f | |||
1bb5d16082 | |||
a37ae5eb70 | |||
63b6761044 | |||
b9a087c169 | |||
fd12f7ad2a | |||
41563454af | |||
6873052b6e | |||
7125374fa3 | |||
00d996d8dd | |||
b987828a25 | |||
d0c59ac659 | |||
6178e4fc22 | |||
3c42b43fe6 | |||
2b31e81f50 | |||
4ea7928fd5 | |||
50de3dad87 | |||
acce17b82c | |||
6c8f113861 | |||
a4989b4eb0 | |||
37ce571b9c | |||
6810f7432f | |||
e542ce0178 | |||
8865416331 | |||
1529874094 | |||
2fae44f387 | |||
4f421c84d5 | |||
b21c5d3b2c | |||
98d1215d7a | |||
7a10457f99 | |||
f31575b50c | |||
980e20818f | |||
e9aca78c9c | |||
a56f5decc7 | |||
02a21ec747 | |||
24258da42d | |||
37bb44066b | |||
1d7da26dcd | |||
999da37e11 | |||
7d46a4de96 | |||
870e8a06a2 | |||
8fa4456fa3 | |||
9b41a0f8b8 | |||
3aae5954f2 | |||
b3ab9cfb1a | |||
d38dac9c4d | |||
1c17252b93 | |||
22f1806692 | |||
3a905e646a | |||
36a94bebe9 | |||
5ba42e3361 | |||
11422a3b43 | |||
ec0b519fe3 | |||
74d984128b | |||
82adb0f1e1 | |||
6219d4302b | |||
5b2cec59db | |||
c437b11409 | |||
33daac87f1 | |||
3b3dee7e9a | |||
5fb64d4e73 | |||
30a91bdb85 | |||
600e46c457 | |||
2b4f0fde90 | |||
65be33cd81 | |||
41f43d1484 | |||
477e8e6459 | |||
92a1189762 | |||
b992260506 | |||
e86f1cd95c | |||
9717f6c239 | |||
8803eaa37d | |||
e7a09d0640 | |||
9093e8d01e | |||
e771320e6a | |||
7646d4e629 | |||
c901ff9408 | |||
cb5f00cbc0 | |||
845ee0f2cd | |||
35336208de | |||
d9648152ef | |||
27a33e55e7 | |||
b421b84b11 | |||
f1012b2fe2 | |||
cc633a7c85 | |||
40b13430cb | |||
dda4e9e771 | |||
1390b73218 | |||
5f7f8dd4e5 | |||
7e4dbd7e03 | |||
6dabc32905 | |||
feedd21413 | |||
851c363aba | |||
c72bff5b2e | |||
679bf1a5c1 | |||
8150ba8f82 | |||
4af48ce87d | |||
ad9033cfe3 | |||
bf8c19c3fc | |||
9ec0f20f2a | |||
f7be52d075 | |||
dc007a981a | |||
697e8cc861 | |||
48b57e8c99 |
58
.clang-format
Executable file
@ -0,0 +1,58 @@
|
||||
---
|
||||
# Based on Webkit style
|
||||
BasedOnStyle: Webkit
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 120
|
||||
---
|
||||
Language: Cpp
|
||||
Standard: Cpp11
|
||||
# Pointers aligned to the left
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
AccessModifierOffset: -4
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
# C++ standard headers (no .h)
|
||||
- Regex: '<[[:alnum:]_-]+>'
|
||||
Priority: 1
|
||||
# Extenal libraries (with .h)
|
||||
- Regex: '<[[:alnum:]_./-]+>'
|
||||
Priority: 2
|
||||
# Headers from same folder
|
||||
- Regex: '"[[:alnum:]_.-]+"'
|
||||
Priority: 3
|
||||
# Headers from other folders
|
||||
- Regex: '"[[:alnum:]_/.-]+"'
|
||||
Priority: 4
|
||||
IndentCaseLabels: false
|
||||
NamespaceIndentation: All
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpacesInAngles: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
UseTab: Never
|
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
10
.gitignore
vendored
@ -26,3 +26,13 @@
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Linux
|
||||
# =========================
|
||||
|
||||
# Backup files produced by some editors
|
||||
*~
|
||||
*.bak
|
||||
|
||||
|
||||
.vscode/
|
||||
|
279
ESPUI_blocks.js
Normal file
@ -0,0 +1,279 @@
|
||||
// This is a block definition for projects like roboblocks
|
||||
//
|
||||
// Main Block
|
||||
Facilino.LANG_COLOUR_HTML = '#BDBDBD';
|
||||
Facilino.LANG_COLOUR_ESPUI = '#B1B1B1';
|
||||
|
||||
Blockly.Blocks['espui'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_HTML'),
|
||||
subcategory: Facilino.locales.getKey('LANG_SUBCATERGORY_ESPUI'),
|
||||
helpUrl: Facilino.getHelpUrl('espui'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
category_colour: Facilino.LANG_COLOUR_HTML,
|
||||
colour: Facilino.LANG_COLOUR_ESPUI,
|
||||
init: function() {
|
||||
var wifiOptions = [['No', false],['Yes', true]];
|
||||
this.appendDummyInput().appendField('UI Title:').appendField(new Blockly.FieldTextInput(Facilino.locales.getKey('LANG_ESPUI_ESPUI_TITLE')), 'ui_name');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_ESPUI_HOTSPOT')).appendField(new Blockly.FieldDropdown(wifiOptions), 'wifi_option');
|
||||
this.appendStatementInput('ui_elements').setCheck('ui_element');
|
||||
this.setColour(Facilino.LANG_COLOUR_ESPUI);
|
||||
this.setTooltip(Facilino.locales.getKey('LANG_ESPUI_ESPUI_TOOLTIP'));
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var wifi_option = block.getFieldValue('wifi_option');
|
||||
var ui_elements = Blockly.Arduino.statementToCode(block, 'ui_elements');
|
||||
Blockly.Arduino.definitions_['define_wifi_h'] = '#include <WiFi.h>';
|
||||
Blockly.Arduino.definitions_['define_espui_h'] = '#include <ESPUI.h>';
|
||||
Blockly.Arduino.setups_['setup_espui'] = '\n';
|
||||
if(wifi_option){
|
||||
Blockly.Arduino.setups_['setup_espui'] +=
|
||||
' Serial.begin(115200);\n\n' +
|
||||
' WiFi.mode(WIFI_AP);\n' +
|
||||
' WiFi.softAP("' + ui_name + '");\n' +
|
||||
' Serial.print("IP address: ");\n' +
|
||||
' Serial.println(WiFi.softAPIP());\n\n';
|
||||
}
|
||||
Blockly.Arduino.setups_['setup_espui'] += ui_elements;
|
||||
Blockly.Arduino.setups_['setup_espui'] += ' ESPUI.begin("' + ui_name + '");\n';
|
||||
return null;
|
||||
};
|
||||
|
||||
//Elements
|
||||
|
||||
Blockly.Blocks['espui_button'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_HTML'),
|
||||
subcategory: Facilino.locales.getKey('LANG_SUBCATERGORY_ESPUI'),
|
||||
helpUrl: Facilino.getHelpUrl('espui_button'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
category_colour: Facilino.LANG_COLOUR_HTML,
|
||||
colour: Facilino.LANG_COLOUR_ESPUI,
|
||||
init: function() {
|
||||
var colour = new Blockly.FieldColour('#000000');
|
||||
colour.setColours(['#000000','#40e0d0','#50c878','#3498dc','#687894','#e4d422','#eb8921','#e32636']).setColumns(2);
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_BUTTON_BUTTON')).appendField(new Blockly.FieldTextInput(Facilino.locales.getKey('LANG_ESPUI_NAME')), 'ui_name');
|
||||
//this.appendDummyInput().appendField('UI Color').appendField(new Blockly.FieldDropdown(colorOptions), 'ui_color');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_COLOR')).appendField(colour, 'ui_color');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_TEXT')).appendField(new Blockly.FieldTextInput(Facilino.locales.getKey('LANG_ESPUI_TEXT')), 'button_text');
|
||||
this.setColour(Facilino.LANG_COLOUR_ESPUI);
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip(Facilino.locales.getKey('LANG_ESPUI_BUTTON_TOOLTIP'));
|
||||
this.appendStatementInput('on_down').appendField(new Blockly.FieldImage('img/blocks/button_pressed.svg', 24*options.zoom, 24*options.zoom)).setCheck(null);
|
||||
this.appendStatementInput('on_up').appendField(new Blockly.FieldImage('img/blocks/button_released.svg', 24*options.zoom, 24*options.zoom)).setCheck(null);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_button'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var color = block.getFieldValue('ui_color');
|
||||
var colorOptions = {"#000000": "COLOR_NONE", "#40e0d0": "COLOR_TURQUOISE", "#50c878": "COLOR_EMERALD", "#3498dc": "COLOR_PETERRIVER", "#687894": "COLOR_WETASPHALT", "#e4d422": "COLOR_SUNFLOWER", "#eb8921": "COLOR_CARROT", "#e32636": "COLOR_ALIZARIN"};
|
||||
var ui_color = colorOptions[color];
|
||||
var button_text = block.getFieldValue('button_text');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
var on_down = Blockly.Arduino.statementToCode(block, 'on_down');
|
||||
var on_up = Blockly.Arduino.statementToCode(block, 'on_up');
|
||||
Blockly.Arduino.definitions_['define_ui_button_' + ui_name_clean] =
|
||||
'void button_' + ui_name_clean + '(Control c, int type) {\n' +
|
||||
' switch(type){\n' +
|
||||
' case B_DOWN:\n' +
|
||||
on_down + '\n break;\n' +
|
||||
' case B_UP:\n' +
|
||||
on_up + '\n break;\n' +
|
||||
' }\n' +
|
||||
'}\n';
|
||||
var code = ' ESPUI.button("' + ui_name + '", &button_' + ui_name_clean + ', ' + ui_color + ', "' + button_text + '");\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['espui_label'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_HTML'),
|
||||
subcategory: Facilino.locales.getKey('LANG_SUBCATERGORY_ESPUI'),
|
||||
helpUrl: Facilino.getHelpUrl('espui_label'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
category_colour: Facilino.LANG_COLOUR_HTML,
|
||||
colour: Facilino.LANG_COLOUR_ESPUI,
|
||||
init: function() {
|
||||
var colour = new Blockly.FieldColour('#000000');
|
||||
colour.setColours(['#000000','#40e0d0','#50c878','#3498dc','#687894','#e4d422','#eb8921','#e32636']).setColumns(2);
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_LABEL_LABEL')).appendField(new Blockly.FieldTextInput(Facilino.locales.getKey('LANG_ESPUI_NAME')), 'ui_name');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_COLOR')).appendField(colour, 'ui_color');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_TEXT')).appendField(new Blockly.FieldTextInput('value'), 'start_value');
|
||||
this.setColour(Facilino.LANG_COLOUR_ESPUI);
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip(Facilino.locales.getKey('LANG_ESPUI_LABEL_TOOLTIP'));
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_label'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var ui_color = block.getFieldValue('ui_color');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
var start_value = block.getFieldValue('start_value');
|
||||
var code = ' ESPUI.label("' + ui_name + '", ' + ui_color + ', "' + start_value + '");\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['espui_switcher'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_HTML'),
|
||||
subcategory: Facilino.locales.getKey('LANG_SUBCATERGORY_ESPUI'),
|
||||
helpUrl: Facilino.getHelpUrl('espui_switcher'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
category_colour: Facilino.LANG_COLOUR_HTML,
|
||||
colour: Facilino.LANG_COLOUR_ESPUI,
|
||||
init: function() {
|
||||
var colour = new Blockly.FieldColour('#000000');
|
||||
colour.setColours(['#000000','#40e0d0','#50c878','#3498dc','#687894','#e4d422','#eb8921','#e32636']).setColumns(2);
|
||||
var stateOptions = [['Off', 'false'],['On', 'true']];
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_SWITCH_SWITCH')).appendField(new Blockly.FieldTextInput(Facilino.locales.getKey('LANG_ESPUI_NAME')), 'ui_name');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_COLOR')).appendField(colour, 'ui_color');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_STATE')).appendField(new Blockly.FieldDropdown(stateOptions), 'switcher_state');
|
||||
this.setColour(Facilino.LANG_COLOUR_ESPUI);
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip('A web interface button');
|
||||
this.appendStatementInput('on_on').appendField(new Blockly.FieldImage('img/blocks/switch_on.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_off').appendField(new Blockly.FieldImage('img/blocks/switch_off.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_switcher'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var color = block.getFieldValue('ui_color');
|
||||
var colorOptions = {"#000000": "COLOR_NONE", "#40e0d0": "COLOR_TURQUOISE", "#50c878": "COLOR_EMERALD", "#3498dc": "COLOR_PETERRIVER", "#687894": "COLOR_WETASPHALT", "#e4d422": "COLOR_SUNFLOWER", "#eb8921": "COLOR_CARROT", "#e32636": "COLOR_ALIZARIN"};
|
||||
var ui_color = colorOptions[color];
|
||||
var switcher_state = block.getFieldValue('switcher_state');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
var on_on = Blockly.Arduino.statementToCode(block, 'on_down');
|
||||
var on_off = Blockly.Arduino.statementToCode(block, 'on_up');
|
||||
Blockly.Arduino.definitions_['define_ui_switcher_' + ui_name_clean] =
|
||||
'void switcher_' + ui_name_clean + '(Control c, int type) {\n' +
|
||||
' switch(type){\n' +
|
||||
' case S_ACTIVE:\n' +
|
||||
on_on + '\n break;\n' +
|
||||
' case S_INACTIVE:\n' +
|
||||
on_off + '\n break;\n' +
|
||||
' }\n' +
|
||||
'}\n';
|
||||
var code = ' ESPUI.switcher("' + ui_name + '", ' + switcher_state + ', &switcher_' + ui_name_clean + ', ' + ui_color + ');\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['espui_pad'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_HTML'),
|
||||
subcategory: Facilino.locales.getKey('LANG_SUBCATERGORY_ESPUI'),
|
||||
helpUrl: Facilino.getHelpUrl('espui_pad'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
category_colour: Facilino.LANG_COLOUR_HTML,
|
||||
colour: Facilino.LANG_COLOUR_ESPUI,
|
||||
init: function() {
|
||||
var colour = new Blockly.FieldColour('#000000');
|
||||
colour.setColours(['#000000','#40e0d0','#50c878','#3498dc','#687894','#e4d422','#eb8921','#e32636']).setColumns(2);
|
||||
var centerOptions = [['Yes', 'false'],['No', 'true']];
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_PAD_PAD')).appendField(new Blockly.FieldTextInput(Facilino.locales.getKey('LANG_ESPUI_NAME')), 'ui_name');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_COLOR')).appendField(colour, 'ui_color');
|
||||
this.appendDummyInput().appendField(Facilino.locales.getKey('LANG_ESPUI_PAD_CENTER')).appendField(new Blockly.FieldDropdown(centerOptions), 'pad_center');
|
||||
this.setColour(Facilino.LANG_COLOUR_ESPUI);
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip('A web interface button');
|
||||
this.appendStatementInput('on_down_for').appendField(new Blockly.FieldImage('img/blocks/controller_up_pressed.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_up_for').appendField(new Blockly.FieldImage('img/blocks/controller_up_released.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_down_back').appendField(new Blockly.FieldImage('img/blocks/controller_down_pressed.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_up_back').appendField(new Blockly.FieldImage('img/blocks/controller_down_released.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_down_left').appendField(new Blockly.FieldImage('img/blocks/controller_right_pressed.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_up_left').appendField(new Blockly.FieldImage('img/blocks/controller_right_released.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_down_right').appendField(new Blockly.FieldImage('img/blocks/controller_left_pressed.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_up_right').appendField(new Blockly.FieldImage('img/blocks/controller_left_released.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_down_center').appendField(new Blockly.FieldImage('img/blocks/controller_center_pressed.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_up_center').appendField(new Blockly.FieldImage('img/blocks/controller_center_released.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.lastOption=this.getFieldValue('pad_center');
|
||||
},
|
||||
onchange() {
|
||||
if (this.lastOption!==this.getFieldValue('pad_center'))
|
||||
{
|
||||
if (this.getFieldValue('pad_center')==='false')
|
||||
{
|
||||
try{
|
||||
|
||||
this.removeInput('on_down_center');
|
||||
this.removeInput('on_up_center');
|
||||
this.appendStatementInput('on_down_center').appendField(new Blockly.FieldImage('img/blocks/controller_center_pressed.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
this.appendStatementInput('on_up_center').appendField(new Blockly.FieldImage('img/blocks/controller_center_released.svg', 24*options.zoom, 24*options.zoom)).setCheck('code');
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try{
|
||||
this.removeInput('on_down_center');
|
||||
this.removeInput('on_up_center');
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
}
|
||||
}
|
||||
this.lastOption=this.getFieldValue('pad_center');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_pad'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var color = block.getFieldValue('ui_color');
|
||||
var colorOptions = {"#000000": "COLOR_NONE", "#40e0d0": "COLOR_TURQUOISE", "#50c878": "COLOR_EMERALD", "#3498dc": "COLOR_PETERRIVER", "#687894": "COLOR_WETASPHALT", "#e4d422": "COLOR_SUNFLOWER", "#eb8921": "COLOR_CARROT", "#e32636": "COLOR_ALIZARIN"};
|
||||
var ui_color = colorOptions[color];
|
||||
var pad_center = block.getFieldValue('pad_center');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
var on_down_for = Blockly.Arduino.statementToCode(block, 'on_down_for');
|
||||
var on_up_for = Blockly.Arduino.statementToCode(block, 'on_up_for');
|
||||
var on_down_back = Blockly.Arduino.statementToCode(block, 'on_down_back');
|
||||
var on_up_back = Blockly.Arduino.statementToCode(block, 'on_up_back');
|
||||
var on_down_left = Blockly.Arduino.statementToCode(block, 'on_down_left');
|
||||
var on_up_left = Blockly.Arduino.statementToCode(block, 'on_up_left');
|
||||
var on_down_right = Blockly.Arduino.statementToCode(block, 'on_down_right');
|
||||
var on_up_right = Blockly.Arduino.statementToCode(block, 'on_up_right');
|
||||
var on_down_center = Blockly.Arduino.statementToCode(block, 'on_down_center');
|
||||
var on_up_center = Blockly.Arduino.statementToCode(block, 'on_up_center');
|
||||
Blockly.Arduino.definitions_['define_ui_pad_' + ui_name_clean] =
|
||||
'void pad_' + ui_name_clean + '(Control c, int type) {\n' +
|
||||
' switch(type){\n' +
|
||||
' case P_FOR_DOWN:\n' +
|
||||
on_down_for + '\n break;\n' +
|
||||
' case P_FOR_UP:\n' +
|
||||
on_up_for + '\n break;\n' +
|
||||
|
||||
' case P_BACK_DOWN:\n' +
|
||||
on_down_back + '\n break;\n' +
|
||||
' case P_BACK_UP:\n' +
|
||||
on_up_back + '\n break;\n' +
|
||||
|
||||
' case P_RIGHT_DOWN:\n' +
|
||||
on_down_left + '\n break;\n' +
|
||||
' case P_RIGHT_UP:\n' +
|
||||
on_up_left + '\n break;\n' +
|
||||
|
||||
' case P_LEFT_DOWN:\n' +
|
||||
on_down_right + '\n break;\n' +
|
||||
' case P_LEFT_UP:\n' +
|
||||
on_up_right + '\n break;\n' +
|
||||
|
||||
' case P_CENTER_DOWN:\n' +
|
||||
on_down_center + '\n break;\n' +
|
||||
' case P_CENTER_UP:\n' +
|
||||
on_up_center + '\n break;\n' +
|
||||
' }\n' +
|
||||
'}\n';
|
||||
var code = ' ESPUI.pad("' + ui_name + '", ' + pad_center + ', &pad_' + ui_name_clean + ', ' + ui_color + ');\n';
|
||||
return code;
|
||||
};
|
361
README.md
@ -1,138 +1,369 @@
|
||||
# ESPUI
|
||||
|
||||

|
||||
|
||||
ESPUI is a simple library to make a web user interface for your projects using
|
||||
the **ESP8266** or the **ESP32** It uses web sockets and lets you create,
|
||||
control, and update elements on your GUI through multiple devices like phones
|
||||
and tablets.
|
||||
|
||||
ESPUI is a simple library to make a web user interface for your projects using the **ESP8266** or the **ESP32**
|
||||
It uses web sockets and lets you create, control, and update elements on your GUI through multiple devices like phones and tablets.
|
||||
ESPUI uses simple Arduino-style syntax for creating a solid, functioning user
|
||||
interface without too much boilerplate code.
|
||||
|
||||
ESPUI uses simple Arduino-style syntax for creating a solid, functioning user interface without too much boilerplate code.
|
||||
So if you either don't know how or just don't want to waste time: this is your
|
||||
simple solution user interface without the need of internet connectivity or any
|
||||
additional servers.
|
||||
|
||||
So if you either don't know how or just don't want to waste time: this is your simple solution user interface without the need of internet connectivity or any additional servers.
|
||||
The Library runs fine on any kind of **ESP8266** and **ESP32** (NodeMCU Boards, usw)
|
||||
|
||||
I completely rewrote the EasyUI Library created by ayushsharma82 [Here](https://github.com/ayushsharma82/)
|
||||
Now it uses ESPAsyncWebserver and is mainly to be used with the ESP32 Processor.
|
||||
## Changelog for 2.0:
|
||||
|
||||
- ArduinoJSON 6.10.0 Support
|
||||
- split pad into pad and padWithCenter
|
||||
- Cleaned Order or parameters on switch
|
||||
- cleaned Order of parameters on pad
|
||||
- Changes all numbers to actually be numbers (slider value, number value, min and max)
|
||||
|
||||
### Added features
|
||||
|
||||
- Tabs by @eringerli #45
|
||||
- Generic API by @eringerli
|
||||
- Min Max on slider by @eringerli
|
||||
- OptionList by @eringerli
|
||||
- Public Access to ESPAsyncServer
|
||||
- Graph Widget (Persist save graph in local storage #10)
|
||||
|
||||
## Further Roadmap
|
||||
|
||||
- Slider css issues
|
||||
- implement Gauge
|
||||
- File upload ?
|
||||
|
||||
## Dependencies
|
||||
|
||||
This library is dependent on the following libraries to function properly.
|
||||
|
||||
- [ESPAsyncWebserver](https://github.com/me-no-dev/ESPAsyncWebServer)
|
||||
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson)
|
||||
|
||||
**Plus for ESP8266**
|
||||
- [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP)
|
||||
|
||||
**Additionally necessary for ESP32**
|
||||
- [AsyncTCP](https://github.com/me-no-dev/AsyncTCP)
|
||||
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson) (Last tested with
|
||||
version 6.10.0)
|
||||
|
||||
- (_For ESP8266_) [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP)
|
||||
- (_For ESP32_) [AsyncTCP](https://github.com/me-no-dev/AsyncTCP)
|
||||
|
||||
## How to Install
|
||||
|
||||
Make sure all the dependencies are installed, then install like so:
|
||||
|
||||
#### Directly Through Arduino IDE
|
||||
#### Using PlattformIO (_recommended_)
|
||||
|
||||
You can find this Library in the Arduino IDE library manager
|
||||
Go to Sketch > Include Library > Library Manager > Search for "ESPUI" > Install
|
||||
Just include this library as a dependency on lib_deps like so:
|
||||
|
||||
#### Manual Install
|
||||
```
|
||||
lib_deps =
|
||||
ESPUI
|
||||
ESPAsyncWebserver
|
||||
ESPAsyncTCP # or AsyncTCP on ESP32
|
||||
```
|
||||
|
||||
For Windows: Download the [Repository](https://github.com/s00500/ESPUI/archive/master.zip) and extract the .zip in Documents>Arduino>Libraries>{Place "ESPUI" folder Here}
|
||||
#### Directly Through Arduino IDE (_recommended_)
|
||||
|
||||
For Linux: Download the [Repository](https://github.com/s00500/ESPUI/archive/master.zip) and extract the .zip in Sketchbook/Libraries/{Place "ESPUI" folder Here}
|
||||
You can find this Library in the Arduino IDE library manager Go to Sketch >
|
||||
Include Library > Library Manager > Search for "ESPUI" > Install
|
||||
|
||||
For macOs: Download the [Repository](https://github.com/s00500/ESPUI/archive/master.zip) and extract the .zip in ~/Documents/Arduino/libraries/{Place "ESPUI" folder Here}
|
||||
#### Manual Install Arduino IDE
|
||||
|
||||
#### Manually through IDE
|
||||
_For Windows:_ Download the
|
||||
[Repository](https://github.com/s00500/ESPUI/archive/master.zip) and extract the
|
||||
.zip in Documents>Arduino>Libraries>{Place "ESPUI" folder Here}
|
||||
|
||||
Download the [Repository](https://github.com/s00500/ESPUI/archive/master.zip), Go to Sketch>Include Library>Add .zip Library> Select the Downloaded .zip File.
|
||||
_For Linux:_ Download the
|
||||
[Repository](https://github.com/s00500/ESPUI/archive/master.zip) and extract the
|
||||
.zip in Sketchbook/Libraries/{Place "ESPUI" folder Here}
|
||||
|
||||
## Getting started (Filesystem upload)
|
||||
_For macOs:_ Download the
|
||||
[Repository](https://github.com/s00500/ESPUI/archive/master.zip) and extract the
|
||||
.zip in ~/Documents/Arduino/libraries/{Place "ESPUI" folder Here}
|
||||
|
||||
ESPUI **NEEDS** its files burnt on the SPIFFS filesystem on the ESP. **Without this ESPUI will NOT work at all**
|
||||
There are now two ways to do this: you can either use the upload tool or you use the library function `ESPUI.prepareFileSystem()`
|
||||
Go to Sketch>Include Library>Add .zip Library> Select the Downloaded .zip File.
|
||||
|
||||
#### Simple filesystem preparation (recomended)
|
||||
## Getting started
|
||||
|
||||
Just open the example sketch **prepareFileSystem** and run it on the ESP, (give it 5 - 10 seconds),
|
||||
The library will create all needed files.
|
||||
Congratulations, you are done, from now on you just need to to this again when there is a library update, or when you want to use another chip :-)
|
||||
Now you can upload your normal sketch, when you do not call the `ESPUI.prepareFileSystem()` function the compiler will strip out all the unnecessary that is already saved in the chip's filesystem and you have more programm memory to work with.
|
||||
ESPUI serves several files to the browser to build up its web interface. This
|
||||
can be achieved in 2 ways: _PROGMEM_ or _SPIFFS_
|
||||
|
||||
_When `ESPUI.begin()` is called the default is serving files from Memory and
|
||||
ESPUI should work out of the box!_
|
||||
|
||||
#### Manual way (mainly for development)
|
||||
**OPTIONAL:** But if this causes your program to _use too much memory_ you can
|
||||
burn the files into the SPIFFS filesystem on the ESP. There are now two ways to
|
||||
do this: you can either use the ESP file upload tool or you use the library
|
||||
function `ESPUI.prepareFileSystem()`
|
||||
|
||||
To do this download and install me-no-devs wonderful [ESP32 sketch data uploader](https://github.com/me-no-dev/arduino-esp32fs-plugin) or for ESP8266 [ESP8266 sketch data uploader](https://github.com/esp8266/arduino-esp8266fs-plugin)
|
||||
#### Simple filesystem preparation (_recommended_)
|
||||
|
||||
Then open the **gui** example sketch and select "Upload Sketch Data" from the Tools menu for your processor.
|
||||
Now you are set to go and use any code you want to with this library
|
||||
Just open the example sketch **prepareFileSystem** and run it on the ESP, (give
|
||||
it up to 30 seconds, you can see the status on the Serial Monitor), The library
|
||||
will create all needed files. Congratulations, you are done, from now on you
|
||||
just need to to this again when there is a library update, or when you want to
|
||||
use another chip :-) Now you can upload your normal sketch, when you do not call
|
||||
the `ESPUI.prepareFileSystem()` function the compiler will strip out all the
|
||||
unnecessary strings that are already saved in the chip's filesystem and you have
|
||||
more program memory to work with.
|
||||
|
||||
## User interface Elements
|
||||
- Label (updateable)
|
||||
- Button
|
||||
- Switch (updateable)
|
||||
- Control pad
|
||||
- Control pad with center button
|
||||
- Slider
|
||||
|
||||
Checkout the example for the usage
|
||||
- Label
|
||||
- Button
|
||||
- Switch
|
||||
- Control pad
|
||||
- Control pad with center button
|
||||
- Slider
|
||||
- Text Input
|
||||
- Numberinput
|
||||
- Graph
|
||||
- Option select
|
||||
|
||||
## Roadmap :
|
||||
Checkout the example for the usage or see the detailed info below
|
||||
|
||||
- ~~Setup SPIFFS using values in program memory~~
|
||||
- ~~ESP8266 support~~
|
||||
- Document slider
|
||||
- proper return value (as int and not as string) for slider
|
||||
- Maybe a slider range setting, meanwhile please use map()
|
||||
- Improve slider stability
|
||||
- Improve general stability
|
||||
## Available colors:
|
||||
|
||||
- Turquoise
|
||||
- Emerald
|
||||
- Peterriver
|
||||
- Wetasphalt
|
||||
- Sunflower
|
||||
- Carrot
|
||||
- Alizarin
|
||||
- Dark
|
||||
- None
|
||||
|
||||
(Use like `ControlColor::Sunflower`)
|
||||
|
||||
## Documentation
|
||||
|
||||
The heart of ESPUI is [ESPAsyncWebserver](https://github.com/me-no-dev/ESPAsyncWebServer).
|
||||
ESPUI's frontend is based on [Skeleton CSS](http://getskeleton.com/) and jQuery-like lightweight [zepto.js](https://zeptojs.com/) for Handling Click Events Etc. The communication between the *ESP32* and the client browser works using web sockets.
|
||||
ESPUI does not need network access and can be used in standalone access point mode.
|
||||
All assets are loaded from the internal SPIFFS filesystem of the ESP32.
|
||||
|
||||
This section will explain in detail how the Library is to be used from the Arduino code side. As of now the Facilino blocks are not implemented.
|
||||
In the arduino setup() routine the interface can be customised by adding UI Elements. This is done by calling the corresponding library methods on the Library object ESPUI. Eg: ESPUI.button(“button”, &myCallback); creates a button in the interface that calls the “myCallback” function when changed. All buttons and items call their callback whenever there is a state change from them. This means the button will call the callback when it is pressed and also again when it is released. To separate different events an integer number with the event name is passed to the callback function that can be handled in a switch(){}case{} statement. Here is an overview of the currently implemented different elements of the UI library:
|
||||
The heart of ESPUI is
|
||||
[ESPAsyncWebserver](https://github.com/me-no-dev/ESPAsyncWebServer). ESPUI's
|
||||
frontend is based on [Skeleton CSS](http://getskeleton.com/) and jQuery-like
|
||||
lightweight [zepto.js](https://zeptojs.com/) for Handling Click Events Etc. The
|
||||
communication between the _ESP_ and the client browser works using web
|
||||
sockets. ESPUI does not need network access and can be used in standalone access
|
||||
point mode, all resources are loaded directly from the ESPs memory.
|
||||
|
||||
This section will explain in detail how the Library is to be used from the
|
||||
Arduino code side. In the arduino `setup()` routine the interface can be customised by adding UI Elements.
|
||||
This is done by calling the corresponding library methods on the Library object
|
||||
`ESPUI`. Eg: `ESPUI.button("button", &myCallback);` creates a button in the
|
||||
interface that calls the `myCallback(Control *sender, int value)` function when changed. All buttons and
|
||||
items call their callback whenever there is a state change from them. This means
|
||||
the button will call the callback when it is pressed and also again when it is
|
||||
released. To separate different events an integer number with the event name is
|
||||
passed to the callback function that can be handled in a `switch(){}case{}`
|
||||
statement. Here is an overview of the currently implemented different elements
|
||||
of the UI library:
|
||||
|
||||
#### Button
|
||||
|
||||

|
||||
|
||||
Buttons have a name and a callback value. They have one event for press and one for release.
|
||||
Buttons have a name and a callback value. They have one event for press (`B_DOWN`) and one
|
||||
for release (`B_UP`).
|
||||
|
||||
- B_DOWN
|
||||
- B_UP
|
||||
|
||||
#### Switch
|
||||
|
||||

|
||||
|
||||
Switches sync their state on all connected devices. This means when you change their value they change visibly on all tablets or computers that currently display the interface. They also have two types of events: one for turning on and one for turning off.
|
||||
Switches sync their state on all connected devices. This means when you change
|
||||
their value they change visibly on all tablets or computers that currently
|
||||
display the interface. They also have two types of events: one when turning on (`S_ACTIVE`)
|
||||
and one when turning off (`S_INACTIVE`).
|
||||
|
||||
- S_ACTIVE
|
||||
- S_INACTIVE
|
||||
|
||||
#### Buttonpad
|
||||
|
||||

|
||||
|
||||
Button pads come in two flavours: with or without a center button. They are very useful for con-trolling all kinds of movements of vehicles or also of course our walking robots. They use a single callback per pad and have 8 or 10 different event types to differentiate the button actions.
|
||||
Button pads come in two flavours: with or without a center button. They are very
|
||||
useful for con-trolling all kinds of movements of vehicles or also of course our
|
||||
walking robots. They use a single callback per pad and have 8 or 10 different
|
||||
event types to differentiate the button actions.
|
||||
|
||||
- P_LEFT_DOWN
|
||||
- P_LEFT_UP
|
||||
- P_RIGHT_DOWN
|
||||
- P_RIGHT_UP
|
||||
- P_FOR_DOWN
|
||||
- P_FOR_UP
|
||||
- P_BACK_DOWN
|
||||
- P_BACK_UP
|
||||
- P_CENTER_DOWN
|
||||
- P_CENTER_UP
|
||||
|
||||
#### Labels
|
||||
|
||||

|
||||
|
||||
Labels are a nice tool to get information from the robot to the user interface. This can be done to show states, values of sensors and configuration parameters. To send data from the code use ESP.print(labelId, “Text”); . Labels get a name on creation and a initial value. The name is not changeable once the UI initialised.
|
||||
Labels are a nice tool to get information from the robot to the user interface.
|
||||
This can be done to show states, values of sensors and configuration parameters.
|
||||
To send data from the code use `ESP.print(labelId, "Text");` . Labels get a name
|
||||
on creation and a initial value. The name is not changeable once the UI
|
||||
initialised.
|
||||
|
||||
Labels automatically wrap your text. If you want them to have multiple lines use
|
||||
the normal `<br>` tag in the string you print to the label
|
||||
|
||||
#### Slider
|
||||
|
||||
There is also an slider component now, needs to be documented though
|
||||

|
||||
|
||||
#### Initialisation of the UI
|
||||
The Slider can be used to slide through a value from 1 to 100. Slides provide
|
||||
realtime data, are touch compatible and can be used to for example control a
|
||||
Servo. The current value is shown while the slider is dragged in a little bubble
|
||||
over the handle. In the Callback the slider does not return an int but a String.
|
||||
Use the .toInt function to convert the value, see the **gui** example to check how it works.
|
||||
|
||||
After all the elements are configured you can use ESPUI.begin(“Some Title”); to start the UI interface. Make sure you setup a working network connection or AccesPoint **before** (See example). The web interface can then be used from multiple devices at once and also shows an connection status in the top bar.
|
||||
The library is designed to be easy to use and can still be extended with a lot of more functionality.
|
||||
A slider usually only sends a new value when it is released to save the esps from being spammed with values. This behaviour can be cahnged globally using a property of the ESPUI object before `begin()`:
|
||||
|
||||
```
|
||||
ESPUI.sliderContinuous = true;
|
||||
ESPUI.begin("ESPUI Control");
|
||||
```
|
||||
|
||||
#### Number Input
|
||||
|
||||

|
||||
|
||||
The numberinput can be used to directly input numbers to your program. You can
|
||||
enter a Value into it and when you are done with your change it is sent to the
|
||||
ESP.
|
||||
|
||||
A number box needs to have a min and a max value. To set it up just use:
|
||||
|
||||
`ESPUI.number("Numbertest", &numberCall, ControlColor::Alizarin, 5, 0, 10);`
|
||||
|
||||
#### Text Input
|
||||
|
||||

|
||||
|
||||
The textinput works very similar like the number input but with a string. You
|
||||
can enter a String into it and when you are done with your change it is sent to
|
||||
the ESP.
|
||||
|
||||
#### Graph
|
||||
|
||||

|
||||
|
||||
The graph widget can display graph points with timestamp at wich they arrive
|
||||
|
||||
Use `ESPUI.addGraphPoint(graphId, random(1, 50));` to add a new value at the current time, use `ESPUI.clearGraph(graphId)` to clear the entire graph.
|
||||
Graph points are saved in the browser in **localstorage** to be persistant, clear local storageto remove the points or use clearGraph() from a bbutton callback to provide a clear button.
|
||||
|
||||
#### Option select
|
||||
|
||||

|
||||

|
||||
|
||||
The option select works by first creating a select widget like so
|
||||
|
||||
`uint16_t select1 = ESPUI.addControl( ControlType::Select, "Select:", "", ControlColor::Alizarin, tab1, &selectExample );`
|
||||
|
||||
And then adding Options to it like seperate widgets, specifying the select as the parent:
|
||||
|
||||
```
|
||||
ESPUI.addControl( ControlType::Option, "Option1", "Opt1", ControlColor::Alizarin, select1 );
|
||||
ESPUI.addControl( ControlType::Option, "Option2", "Opt2", ControlColor::Alizarin, select1 );
|
||||
ESPUI.addControl( ControlType::Option, "Option3", "Opt3", ControlColor::Alizarin, select1 );
|
||||
```
|
||||
|
||||
Check the **tabbedGui** example for a working demo
|
||||
|
||||
### Using Tabs
|
||||
|
||||

|
||||
|
||||
Tabs can be used to organize your widgets in pages. Check the tabbedGui example.
|
||||
Tabs can be created using the generic functions like so:
|
||||
`ESPUI.addControl( ControlType::Tab, "Settings 1", "Settings 1" );`
|
||||
|
||||
Then all widgets for the tab need to be added to it by specifying the tab as the parrent (widgets not added to a tab will be shown above the tab selctor)
|
||||
|
||||
`ESPUI.addControl( ControlType::Text, "Text Title:", "a Text Field", ControlColor::Alizarin, tab1, &textCall );`
|
||||
|
||||
### Initialisation of the UI
|
||||
|
||||
After all the elements are configured you can use `ESPUI.begin("Some Title");`
|
||||
to start the UI interface. (Or `ESPUI.beginSPIFFS("Some Title");` respectively)
|
||||
Make sure you setup a working network connection or AccesPoint **before** (See
|
||||
gui.ino example). The web interface can then be used from multiple devices at once and
|
||||
also shows an connection status in the top bar.
|
||||
|
||||
### Advanced: Generic creation and updates of control widgets
|
||||
|
||||
There are 2 generic functions to create and update controls, to see them in action check the **gui-generic-api** example.
|
||||
|
||||
To create a generic control use:
|
||||
`uint16_t switchOne = ESPUI.addControl(ControlType::Switcher, "Switch one", "", ControlColor::Alizarin, Control::noParent, &switchExample);`
|
||||
|
||||
Then its value can be updated by doing:
|
||||
|
||||
`ESPUI.updateControlValue(status, "Start");`
|
||||
|
||||
You can also update other parameters of the control like its color using:
|
||||
|
||||
```
|
||||
ESPUI.getControl(switchOne)->color = ControlColor::Carrot;
|
||||
ESPUI.updateControl(switchOne);
|
||||
```
|
||||
|
||||
### Log output
|
||||
|
||||
ESPUI has several different log levels. You can set them using the
|
||||
`ESPUI.setVerbosity(Verbosity::VerboseJSON)` function.
|
||||
|
||||
Loglevels are:
|
||||
|
||||
- `Verbosity::Quiet` (default)
|
||||
- `Verbosity::Verbose`
|
||||
- `Verbosity::VerboseJSON`
|
||||
|
||||
VerboseJSON outputs the most debug information.
|
||||
|
||||
### Advanced properties
|
||||
|
||||
If you have many different widgets it might be necessary to adjust the JSON Buffers used internally in ESPUI before .begin() :
|
||||
|
||||
```
|
||||
ESPUI.jsonUpdateDocumentSize = 2000; // This is the default, and this value is not affected by the amount of widgets
|
||||
ESPUI.jsonInitialDocumentSize = 8000; // This is the default, adjust when you have too many widgets or options
|
||||
ESPUI.begin("ESPUI Control");
|
||||
```
|
||||
|
||||
# Notes for Development
|
||||
|
||||
If you want to work on the HTML/CSS/JS files, do make changes in the _data_
|
||||
directory. When you need to transfer that code to the ESP, run
|
||||
`tools/prepare_static_ui_sources.py -a` (this script needs **python3** with the
|
||||
modules **htmlmin**, **jsmin** and **csscompressor**). This will generate a) minified files
|
||||
next to the original files and b) the C header files in `src` that contain the minified and
|
||||
gzipped HTML/CSS/JS data. Alternatively, you can specify the `--source` and `--target` arguments to the
|
||||
`prepare_static_ui_sources.py` script (run the script without arguments for
|
||||
help) if you want to use different locations.
|
||||
|
||||
If you don't have a python environment, you need to minify and gzip the
|
||||
HTML/CSS/JS files manually. I wrote a little useful jsfiddle for this,
|
||||
[see here](https://jsfiddle.net/s00500/yvLbhuuv/).
|
||||
|
||||
If you change something in HTML/CSS/JS and want to create a pull request, please
|
||||
do include the minified versions and corresponding C header files in your
|
||||
commits. (Do **NOT** commit all the minified versions for the non changed files)
|
||||
|
||||
# Contribute
|
||||
Liked this Library? You can **support** me by sending me a :coffee: [Coffee](https://paypal.me/lukasbachschwell/3).
|
||||
|
||||
Liked this Library? You can **support** me by sending me a :coffee:
|
||||
[Coffee](https://paypal.me/lukasbachschwell/5).
|
||||
|
||||
Otherwise I really welcome **Pull Requests**.
|
||||
|
339
blocks.js
@ -1,339 +0,0 @@
|
||||
// This is a block definition for projects like roboblocks
|
||||
//
|
||||
// Main Block
|
||||
Blockly.Blocks['espui'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_BLOCKS'),
|
||||
helpUrl: Facilino.getHelpUrl('espui'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
init: function() {
|
||||
var wifiOptions = [
|
||||
['No', false],
|
||||
['Yes', true]
|
||||
];
|
||||
this.appendDummyInput()
|
||||
.appendField('ESPUI Title:')
|
||||
.appendField(new Blockly.FieldTextInput('string'), 'ui_name');
|
||||
this.appendDummyInput()
|
||||
.appendField('Enable Wifi Hotspot Code:')
|
||||
.appendField(new Blockly.FieldDropdown(wifiOptions), 'wifi_option');
|
||||
this.appendStatementInput('ui_elements')
|
||||
.setCheck('ui_element');
|
||||
this.setColour("#37d1f9");
|
||||
this.setTooltip("Creates a webinterface on the ESP32");
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var wifi_option = block.getFieldValue('wifi_option');
|
||||
var ui_elements = Blockly.Arduino.statementToCode(block, 'ui_elements');
|
||||
Blockly.Arduino.definitions_['define_wifi_h'] = '#include <WiFi.h>';
|
||||
Blockly.Arduino.definitions_['define_espui_h'] = '#include <ESPUI.h>';
|
||||
Blockly.Arduino.setups_['setup_espui'] = '\n';
|
||||
if(wifi_option){
|
||||
Blockly.Arduino.setups_['setup_espui'] +=
|
||||
' Serial.begin(115200);\n\n' +
|
||||
' WiFi.mode(WIFI_AP);\n' +
|
||||
' WiFi.softAP("' + ui_name + '");\n' +
|
||||
' Serial.print("IP address: ");\n' +
|
||||
' Serial.println(WiFi.softAPIP());\n\n';
|
||||
}
|
||||
Blockly.Arduino.setups_['setup_espui'] += ui_elements;
|
||||
Blockly.Arduino.setups_['setup_espui'] += ' ESPUI.begin("' + ui_name + '");\n';
|
||||
return null;
|
||||
};
|
||||
|
||||
//Elements
|
||||
|
||||
Blockly.Blocks['espui_button'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_BLOCKS'),
|
||||
helpUrl: Facilino.getHelpUrl('espui'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
init: function() {
|
||||
var colorOptions = [
|
||||
['none', 'COLOR_NONE'],
|
||||
['turquoise', 'COLOR_TURQUOISE'],
|
||||
['emerald', 'COLOR_EMERALD'],
|
||||
['peterriver', 'COLOR_PETERRIVER'],
|
||||
['wet asphalt', 'COLOR_WETASPHALT'],
|
||||
['sunflower', 'COLOR_SUNFLOWER'],
|
||||
['carrot', 'COLOR_CARROT'],
|
||||
['alizarin', 'COLOR_ALIZARIN'],
|
||||
];
|
||||
this.appendDummyInput()
|
||||
.appendField('ESPUI Button')
|
||||
.appendField(new Blockly.FieldTextInput('name'), 'ui_name');
|
||||
this.appendDummyInput()
|
||||
.appendField('UI Color')
|
||||
.appendField(new Blockly.FieldDropdown(colorOptions), 'ui_color');
|
||||
this.appendDummyInput()
|
||||
.appendField('Button Text')
|
||||
.appendField(new Blockly.FieldTextInput('name'), 'button_text');
|
||||
this.setColour("#3357c7");
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip('A web interface button');
|
||||
this.appendStatementInput('on_down')
|
||||
.appendField('Pressed:')
|
||||
.setCheck(null);
|
||||
this.appendStatementInput('on_up')
|
||||
.appendField('Released:')
|
||||
.setCheck(null);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_button'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var ui_color = block.getFieldValue('ui_color');
|
||||
var button_text = block.getFieldValue('button_text');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
var on_down = Blockly.Arduino.statementToCode(block, 'on_down');
|
||||
var on_up = Blockly.Arduino.statementToCode(block, 'on_up');
|
||||
Blockly.Arduino.definitions_['define_ui_button_' + ui_name_clean] =
|
||||
'void button_' + ui_name_clean + '(Control c, int type) {\n' +
|
||||
' switch(type){\n' +
|
||||
' case B_DOWN:\n' +
|
||||
on_down + '\n break;\n' +
|
||||
' case B_UP:\n' +
|
||||
on_up + '\n break;\n' +
|
||||
' }\n' +
|
||||
'}\n';
|
||||
|
||||
var code = ' ESPUI.button("' + ui_name + '", &button_' + ui_name_clean + ', ' + ui_color + ', "' + button_text + '");\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['espui_label'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_BLOCKS'),
|
||||
helpUrl: Facilino.getHelpUrl('espui'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
init: function() {
|
||||
var colorOptions = [
|
||||
['none', 'COLOR_NONE'],
|
||||
['turquoise', 'COLOR_TURQUOISE'],
|
||||
['emerald', 'COLOR_EMERALD'],
|
||||
['peterriver', 'COLOR_PETERRIVER'],
|
||||
['wet asphalt', 'COLOR_WETASPHALT'],
|
||||
['sunflower', 'COLOR_SUNFLOWER'],
|
||||
['carrot', 'COLOR_CARROT'],
|
||||
['alizarin', 'COLOR_ALIZARIN'],
|
||||
];
|
||||
this.appendDummyInput()
|
||||
.appendField('ESPUI Label')
|
||||
.appendField(new Blockly.FieldTextInput('label'), 'ui_name');
|
||||
this.appendDummyInput()
|
||||
.appendField('UI Color')
|
||||
.appendField(new Blockly.FieldDropdown(colorOptions), 'ui_color');
|
||||
this.appendDummyInput()
|
||||
.appendField('Initial Value:')
|
||||
.appendField(new Blockly.FieldTextInput('value'), 'start_value');
|
||||
this.setColour("#3357c7");
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip('A web interface label you can update from your code');
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_label'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var ui_color = block.getFieldValue('ui_color');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
var start_value = block.getFieldValue('start_value');
|
||||
|
||||
var code = ' ESPUI.label("' + ui_name + '", ' + ui_color + ', "' + start_value + '");\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['espui_switcher'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_BLOCKS'),
|
||||
helpUrl: Facilino.getHelpUrl('espui'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
init: function() {
|
||||
var colorOptions = [
|
||||
['none', 'COLOR_NONE'],
|
||||
['turquoise', 'COLOR_TURQUOISE'],
|
||||
['emerald', 'COLOR_EMERALD'],
|
||||
['peterriver', 'COLOR_PETERRIVER'],
|
||||
['wet asphalt', 'COLOR_WETASPHALT'],
|
||||
['sunflower', 'COLOR_SUNFLOWER'],
|
||||
['carrot', 'COLOR_CARROT'],
|
||||
['alizarin', 'COLOR_ALIZARIN'],
|
||||
];
|
||||
var stateOptions = [
|
||||
['Off', 'false'],
|
||||
['On', 'true'],
|
||||
];
|
||||
this.appendDummyInput()
|
||||
.appendField('ESPUI Switcher')
|
||||
.appendField(new Blockly.FieldTextInput('name'), 'ui_name');
|
||||
this.appendDummyInput()
|
||||
.appendField('UI Color')
|
||||
.appendField(new Blockly.FieldDropdown(colorOptions), 'ui_color');
|
||||
this.appendDummyInput()
|
||||
.appendField('Initial state')
|
||||
.appendField(new Blockly.FieldDropdown(stateOptions), 'switcher_state');
|
||||
this.setColour("#3357c7");
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip('A web interface button');
|
||||
this.appendStatementInput('on_on')
|
||||
.appendField('When swithed on:')
|
||||
.setCheck(null);
|
||||
this.appendStatementInput('on_off')
|
||||
.appendField('When swithed off:')
|
||||
.setCheck(null);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_switcher'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var ui_color = block.getFieldValue('ui_color');
|
||||
var switcher_state = block.getFieldValue('switcher_state');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
var on_on = Blockly.Arduino.statementToCode(block, 'on_down');
|
||||
var on_off = Blockly.Arduino.statementToCode(block, 'on_up');
|
||||
Blockly.Arduino.definitions_['define_ui_switcher_' + ui_name_clean] =
|
||||
'void switcher_' + ui_name_clean + '(Control c, int type) {\n' +
|
||||
' switch(type){\n' +
|
||||
' case S_ACTIVE:\n' +
|
||||
on_on + '\n break;\n' +
|
||||
' case S_INACTIVE:\n' +
|
||||
on_off + '\n break;\n' +
|
||||
' }\n' +
|
||||
'}\n';
|
||||
|
||||
var code = ' ESPUI.switcher("' + ui_name + '", ' + switcher_state + ', &switcher_' + ui_name_clean + ', ' + ui_color + ');\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['espui_pad'] = {
|
||||
category: Facilino.locales.getKey('LANG_CATEGORY_BLOCKS'),
|
||||
helpUrl: Facilino.getHelpUrl('espui'),
|
||||
tags: ['webinterface'],
|
||||
examples: ['lol.bly'],
|
||||
init: function() {
|
||||
var colorOptions = [
|
||||
['none', 'COLOR_NONE'],
|
||||
['turquoise', 'COLOR_TURQUOISE'],
|
||||
['emerald', 'COLOR_EMERALD'],
|
||||
['peterriver', 'COLOR_PETERRIVER'],
|
||||
['wet asphalt', 'COLOR_WETASPHALT'],
|
||||
['sunflower', 'COLOR_SUNFLOWER'],
|
||||
['carrot', 'COLOR_CARROT'],
|
||||
['alizarin', 'COLOR_ALIZARIN'],
|
||||
];
|
||||
var centerOptions = [
|
||||
['Yes', 'false'],
|
||||
['No', 'true'],
|
||||
];
|
||||
this.appendDummyInput()
|
||||
.appendField('ESPUI ButtonPad')
|
||||
.appendField(new Blockly.FieldTextInput('name'), 'ui_name');
|
||||
this.appendDummyInput()
|
||||
.appendField('UI Color')
|
||||
.appendField(new Blockly.FieldDropdown(colorOptions), 'ui_color');
|
||||
this.appendDummyInput()
|
||||
.appendField('Center button')
|
||||
.appendField(new Blockly.FieldDropdown(centerOptions), 'pad_center');
|
||||
this.setColour("#3357c7");
|
||||
this.setPreviousStatement(true, 'ui_element');
|
||||
this.setNextStatement(true, 'ui_element');
|
||||
this.setTooltip('A web interface button');
|
||||
|
||||
this.appendStatementInput('on_down_for')
|
||||
.appendField('Forward press:')
|
||||
.setCheck(null);
|
||||
this.appendStatementInput('on_up_for')
|
||||
.appendField('Forward release:')
|
||||
.setCheck(null);
|
||||
|
||||
this.appendStatementInput('on_down_back')
|
||||
.appendField('Back press:')
|
||||
.setCheck(null);
|
||||
this.appendStatementInput('on_up_back')
|
||||
.appendField('Back release:')
|
||||
.setCheck(null);
|
||||
|
||||
this.appendStatementInput('on_down_left')
|
||||
.appendField('Right press:')
|
||||
.setCheck(null);
|
||||
this.appendStatementInput('on_up_left')
|
||||
.appendField('Right release:')
|
||||
.setCheck(null);
|
||||
|
||||
this.appendStatementInput('on_down_right')
|
||||
.appendField('Left press:')
|
||||
.setCheck(null);
|
||||
this.appendStatementInput('on_up_right')
|
||||
.appendField('Left release:')
|
||||
.setCheck(null);
|
||||
|
||||
this.appendStatementInput('on_down_center')
|
||||
.appendField('Center press:')
|
||||
.setCheck(null);
|
||||
this.appendStatementInput('on_up_center')
|
||||
.appendField('Center release:')
|
||||
.setCheck(null);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Arduino['espui_pad'] = function(block) {
|
||||
var ui_name = block.getFieldValue('ui_name');
|
||||
var ui_color = block.getFieldValue('ui_color');
|
||||
var pad_center = block.getFieldValue('pad_center');
|
||||
var ui_name_clean = ui_name.replace(' ', '_');
|
||||
|
||||
var on_down_for = Blockly.Arduino.statementToCode(block, 'on_down_for');
|
||||
var on_up_for = Blockly.Arduino.statementToCode(block, 'on_up_for');
|
||||
|
||||
var on_down_back = Blockly.Arduino.statementToCode(block, 'on_down_back');
|
||||
var on_up_back = Blockly.Arduino.statementToCode(block, 'on_up_back');
|
||||
|
||||
var on_down_left = Blockly.Arduino.statementToCode(block, 'on_down_left');
|
||||
var on_up_left = Blockly.Arduino.statementToCode(block, 'on_up_left');
|
||||
|
||||
var on_down_right = Blockly.Arduino.statementToCode(block, 'on_down_right');
|
||||
var on_up_right = Blockly.Arduino.statementToCode(block, 'on_up_right');
|
||||
|
||||
var on_down_center = Blockly.Arduino.statementToCode(block, 'on_down_center');
|
||||
var on_up_center = Blockly.Arduino.statementToCode(block, 'on_up_center');
|
||||
|
||||
|
||||
Blockly.Arduino.definitions_['define_ui_pad_' + ui_name_clean] =
|
||||
'void pad_' + ui_name_clean + '(Control c, int type) {\n' +
|
||||
' switch(type){\n' +
|
||||
|
||||
' case P_FOR_DOWN:\n' +
|
||||
on_down_for + '\n break;\n' +
|
||||
' case P_FOR_UP:\n' +
|
||||
on_up_for + '\n break;\n' +
|
||||
|
||||
' case P_BACK_DOWN:\n' +
|
||||
on_down_back + '\n break;\n' +
|
||||
' case P_BACK_UP:\n' +
|
||||
on_up_back + '\n break;\n' +
|
||||
|
||||
' case P_RIGHT_DOWN:\n' +
|
||||
on_down_left + '\n break;\n' +
|
||||
' case P_RIGHT_UP:\n' +
|
||||
on_up_left + '\n break;\n' +
|
||||
|
||||
' case P_LEFT_DOWN:\n' +
|
||||
on_down_right + '\n break;\n' +
|
||||
' case P_LEFT_UP:\n' +
|
||||
on_up_right + '\n break;\n' +
|
||||
|
||||
' case P_CENTER_DOWN:\n' +
|
||||
on_down_center + '\n break;\n' +
|
||||
' case P_CENTER_UP:\n' +
|
||||
on_up_center + '\n break;\n' +
|
||||
' }\n' +
|
||||
'}\n';
|
||||
|
||||
var code = ' ESPUI.pad("' + ui_name + '", ' + pad_center + ', &pad_' + ui_name_clean + ', ' + ui_color + ');\n';
|
||||
return code;
|
||||
};
|
1
data/css/normalize.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
1099
data/css/style.css
Normal file
1
data/css/style.min.css
vendored
Normal file
35
data/index.htm
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Control</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link
|
||||
rel="shortcut icon"
|
||||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAPFBMVEUAAACA1VWR21qQ2liR3FqR3FqS3VuR3VqR3VuR3VqO21mS21uS3FqS3FqS21uJ2GKQ21qR3FuR3FoAAAB/3Gu7AAAAEnRSTlMABoA3kPBwz8i5Kzioxg4NVcU3uEJHAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+EFEhcEM+HpYwQAAABYSURBVBjThY/JDsAgCESt4lpX/v9jLQZJ6qF9t3khAyj1xXUKbQ4BVowDwqOYgExkkW4iY6lPaF06RqM8YItOuRbMaz6xjbsusDAW/drplBg47jP696cXE8bPA1eUDeK2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA1LTE4VDIzOjA0OjUxKzAyOjAwxE59ewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNS0xOFQyMzowNDo1MSswMjowMLUTxccAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC"
|
||||
/>
|
||||
<link rel="stylesheet" href="/css/normalize.css" />
|
||||
<link rel="stylesheet" href="/css/style.css" />
|
||||
|
||||
<script src="/js/zepto.min.js"></script>
|
||||
<script src="/js/slider.js"></script>
|
||||
<script src="/js/graph.js"></script>
|
||||
<script src="/js/controls.js"></script>
|
||||
<script src="/js/tabbedcontent.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="javascript:start();">
|
||||
<div>
|
||||
<h4>
|
||||
<div id="mainHeader">Control</div>
|
||||
<span id="conStatus" class="label">Offline</span>
|
||||
</h4>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="container">
|
||||
<div id="row" class="row u-full-width"></div>
|
||||
<ul id="tabsnav" class="navigation navigation-tabs u-full-width"></ul>
|
||||
<div id="tabscontent" class="tabscontent u-full-width"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
1
data/index.min.htm
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html> <head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="shortcut icon" href=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAPFBMVEUAAACA1VWR21qQ2liR3FqR3FqS3VuR3VqR3VuR3VqO21mS21uS3FqS3FqS21uJ2GKQ21qR3FuR3FoAAAB/3Gu7AAAAEnRSTlMABoA3kPBwz8i5Kzioxg4NVcU3uEJHAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+EFEhcEM+HpYwQAAABYSURBVBjThY/JDsAgCESt4lpX/v9jLQZJ6qF9t3khAyj1xXUKbQ4BVowDwqOYgExkkW4iY6lPaF06RqM8YItOuRbMaz6xjbsusDAW/drplBg47jP696cXE8bPA1eUDeK2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA1LTE4VDIzOjA0OjUxKzAyOjAwxE59ewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNS0xOFQyMzowNDo1MSswMjowMLUTxccAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head> <body onload=javascript:start();> <div> <h4> <div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span> </h4> </div> <hr> <div class=container> <div id=row class="row u-full-width"></div> <ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul> <div id=tabscontent class="tabscontent u-full-width"></div> </div> </body> </html>
|
903
data/js/controls.js
vendored
Normal file
@ -0,0 +1,903 @@
|
||||
const UI_INITIAL_GUI = 200;
|
||||
const UI_RELOAD = 201;
|
||||
const UPDATE_OFFSET = 100;
|
||||
|
||||
const UI_TITEL = 0;
|
||||
|
||||
const UI_PAD = 1;
|
||||
const UPDATE_PAD = 101;
|
||||
|
||||
const UI_CPAD = 2;
|
||||
const UPDATE_CPAD = 102;
|
||||
|
||||
const UI_BUTTON = 3;
|
||||
const UPDATE_BUTTON = 103;
|
||||
|
||||
const UI_LABEL = 4;
|
||||
const UPDATE_LABEL = 104;
|
||||
|
||||
const UI_SWITCHER = 5;
|
||||
const UPDATE_SWITCHER = 105;
|
||||
|
||||
const UI_SLIDER = 6;
|
||||
const UPDATE_SLIDER = 106;
|
||||
|
||||
const UI_NUMBER = 7;
|
||||
const UPDATE_NUMBER = 107;
|
||||
|
||||
const UI_TEXT_INPUT = 8;
|
||||
const UPDATE_TEXT_INPUT = 108;
|
||||
|
||||
const UI_GRAPH = 9;
|
||||
const ADD_GRAPH_POINT = 10;
|
||||
const CLEAR_GRAPH = 109;
|
||||
|
||||
const UI_TAB = 11;
|
||||
const UPDATE_TAB = 111;
|
||||
|
||||
const UI_SELECT = 12;
|
||||
const UPDATE_SELECT = 112;
|
||||
|
||||
const UI_OPTION = 13;
|
||||
const UPDATE_OPTION = 113;
|
||||
const UI_MIN = 14;
|
||||
const UPDATE_MIN = 114;
|
||||
const UI_MAX = 15;
|
||||
const UPDATE_MAX = 115;
|
||||
const UI_STEP = 16;
|
||||
const UPDATE_STEP = 116;
|
||||
|
||||
const UI_GAUGE = 17;
|
||||
const UPDATE_GAUGE = 117;
|
||||
const UI_ACCEL = 18;
|
||||
const UPTDATE_ACCEL = 117;
|
||||
|
||||
const UP = 0;
|
||||
const DOWN = 1;
|
||||
const LEFT = 2;
|
||||
const RIGHT = 3;
|
||||
const CENTER = 4;
|
||||
|
||||
// Colors
|
||||
const C_TURQUOISE = 0;
|
||||
const C_EMERALD = 1;
|
||||
const C_PETERRIVER = 2;
|
||||
const C_WETASPHALT = 3;
|
||||
const C_SUNFLOWER = 4;
|
||||
const C_CARROT = 5;
|
||||
const C_ALIZARIN = 6;
|
||||
const C_DARK = 7;
|
||||
const C_NONE = 255;
|
||||
|
||||
var graphData = new Array();
|
||||
var hasAccel = false;
|
||||
var sliderContinuous = false;
|
||||
|
||||
function colorClass(colorId) {
|
||||
colorId = Number(colorId);
|
||||
switch (colorId) {
|
||||
case C_TURQUOISE:
|
||||
return "turquoise";
|
||||
|
||||
case C_EMERALD:
|
||||
return "emerald";
|
||||
|
||||
case C_PETERRIVER:
|
||||
return "peterriver";
|
||||
|
||||
case C_WETASPHALT:
|
||||
return "wetasphalt";
|
||||
|
||||
case C_SUNFLOWER:
|
||||
return "sunflower";
|
||||
|
||||
case C_CARROT:
|
||||
return "carrot";
|
||||
|
||||
case C_ALIZARIN:
|
||||
return "alizarin";
|
||||
|
||||
case C_NONE:
|
||||
return "dark";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
var websock;
|
||||
var websockConnected = false;
|
||||
|
||||
function requestOrientationPermission() {
|
||||
/*
|
||||
// Currently this fails, since it needs secure context on IOS safari
|
||||
if (typeof DeviceMotionEvent.requestPermission === "function") {
|
||||
DeviceOrientationEvent.requestPermission()
|
||||
.then(response => {
|
||||
if (response == "granted") {
|
||||
window.addEventListener("deviceorientation", handleOrientation);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
} else {
|
||||
// Non IOS 13
|
||||
window.addEventListener("deviceorientation", handleOrientation);
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
function handleOrientation(event) {
|
||||
var x = event.beta; // In degree in the range [-180,180]
|
||||
var y = event.gamma; // In degree in the range [-90,90]
|
||||
|
||||
var output = document.querySelector(".output");
|
||||
output.innerHTML = "beta : " + x + "\n";
|
||||
output.innerHTML += "gamma: " + y + "\n";
|
||||
|
||||
// Because we don't want to have the device upside down
|
||||
// We constrain the x value to the range [-90,90]
|
||||
if (x > 90) {
|
||||
x = 90;
|
||||
}
|
||||
if (x < -90) {
|
||||
x = -90;
|
||||
}
|
||||
|
||||
// To make computation easier we shift the range of
|
||||
// x and y to [0,180]
|
||||
x += 90;
|
||||
y += 90;
|
||||
|
||||
// 10 is half the size of the ball
|
||||
// It center the positioning point to the center of the ball
|
||||
var ball = document.querySelector(".ball");
|
||||
var garden = document.querySelector(".garden");
|
||||
var maxX = garden.clientWidth - ball.clientWidth;
|
||||
var maxY = garden.clientHeight - ball.clientHeight;
|
||||
ball.style.top = (maxY * y) / 180 - 10 + "px";
|
||||
ball.style.left = (maxX * x) / 180 - 10 + "px";
|
||||
}
|
||||
*/
|
||||
|
||||
function saveGraphData() {
|
||||
localStorage.setItem("espuigraphs", JSON.stringify(graphData));
|
||||
}
|
||||
|
||||
function restoreGraphData(id) {
|
||||
var savedData = localStorage.getItem("espuigraphs", graphData);
|
||||
if (savedData != null) {
|
||||
savedData = JSON.parse(savedData);
|
||||
return savedData[id];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function restart() {
|
||||
$(document).add("*").off();
|
||||
$("#row").html("");
|
||||
websock.close();
|
||||
start();
|
||||
}
|
||||
|
||||
function conStatusError() {
|
||||
websockConnected = false;
|
||||
$("#conStatus").removeClass("color-green");
|
||||
$("#conStatus").addClass("color-red");
|
||||
$("#conStatus").html("Error / No Connection ↻");
|
||||
$("#conStatus").off();
|
||||
$("#conStatus").on({
|
||||
click: restart,
|
||||
});
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
if (!websockConnected && !document.hidden) {
|
||||
restart();
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange, false);
|
||||
if (
|
||||
window.location.port != "" ||
|
||||
window.location.port != 80 ||
|
||||
window.location.port != 443
|
||||
) {
|
||||
websock = new WebSocket(
|
||||
"ws://" + window.location.hostname + ":" + window.location.port + "/ws"
|
||||
);
|
||||
} else {
|
||||
websock = new WebSocket("ws://" + window.location.hostname + "/ws");
|
||||
}
|
||||
websock.onopen = function (evt) {
|
||||
console.log("websock open");
|
||||
$("#conStatus").addClass("color-green");
|
||||
$("#conStatus").text("Connected");
|
||||
websockConnected = true;
|
||||
};
|
||||
|
||||
websock.onclose = function (evt) {
|
||||
console.log("websock close");
|
||||
conStatusError();
|
||||
};
|
||||
|
||||
websock.onerror = function (evt) {
|
||||
console.log(evt);
|
||||
conStatusError();
|
||||
};
|
||||
|
||||
var handleEvent = function (evt) {
|
||||
console.log(evt);
|
||||
var data = JSON.parse(evt.data);
|
||||
var e = document.body;
|
||||
var center = "";
|
||||
switch (data.type) {
|
||||
case UI_INITIAL_GUI:
|
||||
// Clear current elements
|
||||
$("#row").html("");
|
||||
$("#tabsnav").html("");
|
||||
$("#tabscontent").html("");
|
||||
|
||||
if (data.sliderContinuous) {
|
||||
sliderContinuous = data.sliderContinuous;
|
||||
}
|
||||
data.controls.forEach(element => {
|
||||
var fauxEvent = {
|
||||
data: JSON.stringify(element),
|
||||
};
|
||||
handleEvent(fauxEvent);
|
||||
});
|
||||
break;
|
||||
case UI_RELOAD:
|
||||
window.location.reload();
|
||||
break;
|
||||
|
||||
case UI_TITEL:
|
||||
document.title = data.label;
|
||||
$("#mainHeader").html(data.label);
|
||||
break;
|
||||
|
||||
case UI_LABEL:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<span id='l" +
|
||||
data.id +
|
||||
"' class='label label-wrap'>" +
|
||||
data.value +
|
||||
"</span>" +
|
||||
"</div>"
|
||||
);
|
||||
break;
|
||||
|
||||
case UI_BUTTON:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='one columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<button id='btn" +
|
||||
data.id +
|
||||
"' " +
|
||||
"onmousedown='buttonclick(" +
|
||||
data.id +
|
||||
", true)' " +
|
||||
"onmouseup='buttonclick(" +
|
||||
data.id +
|
||||
", false)'>" +
|
||||
data.value +
|
||||
"</button></div>"
|
||||
);
|
||||
$("#btn" + data.id).on({
|
||||
touchstart: function (e) {
|
||||
e.preventDefault();
|
||||
buttonclick(data.id, true);
|
||||
},
|
||||
touchend: function (e) {
|
||||
e.preventDefault();
|
||||
buttonclick(data.id, false);
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
||||
case UI_SWITCHER:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='one columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<label id='sl" +
|
||||
data.id +
|
||||
"' class='switch " +
|
||||
(data.value == "1" ? "checked" : "") +
|
||||
"'>" +
|
||||
"<div class='in'><input type='checkbox' id='s" +
|
||||
data.id +
|
||||
"' onClick='switcher(" +
|
||||
data.id +
|
||||
",null)' " +
|
||||
(data.value == "1" ? "checked" : "") +
|
||||
"/></div>" +
|
||||
"</label>" +
|
||||
"</div>"
|
||||
);
|
||||
switcher(data.id, data.value);
|
||||
break;
|
||||
|
||||
case UI_CPAD:
|
||||
case UI_PAD:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<nav class='control'>" +
|
||||
"<ul>" +
|
||||
"<li><a onmousedown='padclick(UP, " +
|
||||
data.id +
|
||||
", true)' onmouseup='padclick(UP, " +
|
||||
data.id +
|
||||
", false)' id='pf" +
|
||||
data.id +
|
||||
"'>▲</a></li>" +
|
||||
"<li><a onmousedown='padclick(RIGHT, " +
|
||||
data.id +
|
||||
", true)' onmouseup='padclick(RIGHT, " +
|
||||
data.id +
|
||||
", false)' id='pr" +
|
||||
data.id +
|
||||
"'>▲</a></li>" +
|
||||
"<li><a onmousedown='padclick(LEFT, " +
|
||||
data.id +
|
||||
", true)' onmouseup='padclick(LEFT, " +
|
||||
data.id +
|
||||
", false)' id='pl" +
|
||||
data.id +
|
||||
"'>▲</a></li>" +
|
||||
"<li><a onmousedown='padclick(DOWN, " +
|
||||
data.id +
|
||||
", true)' onmouseup='padclick(DOWN, " +
|
||||
data.id +
|
||||
", false)' id='pb" +
|
||||
data.id +
|
||||
"'>▲</a></li>" +
|
||||
"</ul>" +
|
||||
(data.type == UI_CPAD
|
||||
? "<a class='confirm' onmousedown='padclick(CENTER," +
|
||||
data.id +
|
||||
", true)' onmouseup='padclick(CENTER, " +
|
||||
data.id +
|
||||
", false)' id='pc" +
|
||||
data.id +
|
||||
"'>OK</a>"
|
||||
: "") +
|
||||
"</nav>" +
|
||||
"</div>"
|
||||
);
|
||||
|
||||
$("#pf" + data.id).on({
|
||||
touchstart: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(UP, data.id, true);
|
||||
},
|
||||
touchend: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(UP, data.id, false);
|
||||
},
|
||||
});
|
||||
$("#pl" + data.id).on({
|
||||
touchstart: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(LEFT, data.id, true);
|
||||
},
|
||||
touchend: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(LEFT, data.id, false);
|
||||
},
|
||||
});
|
||||
$("#pr" + data.id).on({
|
||||
touchstart: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(RIGHT, data.id, true);
|
||||
},
|
||||
touchend: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(RIGHT, data.id, false);
|
||||
},
|
||||
});
|
||||
$("#pb" + data.id).on({
|
||||
touchstart: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(DOWN, data.id, true);
|
||||
},
|
||||
touchend: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(DOWN, data.id, false);
|
||||
},
|
||||
});
|
||||
$("#pc" + data.id).on({
|
||||
touchstart: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(CENTER, data.id, true);
|
||||
},
|
||||
touchend: function (e) {
|
||||
e.preventDefault();
|
||||
padclick(CENTER, data.id, false);
|
||||
},
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
//https://codepen.io/seanstopnik/pen/CeLqA
|
||||
case UI_SLIDER:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter card-slider " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<div class='range-slider'>" +
|
||||
"<input id='sl" +
|
||||
data.id +
|
||||
"' type='range' min='0' max='100' value='" +
|
||||
data.value +
|
||||
"' class='range-slider__range'>" +
|
||||
"<span class='range-slider__value'>" +
|
||||
data.value +
|
||||
"</span>" +
|
||||
"</div>" +
|
||||
"</div>"
|
||||
);
|
||||
rangeSlider(!sliderContinuous);
|
||||
break;
|
||||
|
||||
case UI_NUMBER:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<input style='color:black;' id='num" +
|
||||
data.id +
|
||||
"' type='number' value='" +
|
||||
data.value +
|
||||
"' onchange='numberchange(" +
|
||||
data.id +
|
||||
")' />" +
|
||||
"</div>"
|
||||
);
|
||||
break;
|
||||
|
||||
case UI_TEXT_INPUT:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<input style='color:black;' id='text" +
|
||||
data.id +
|
||||
"' value='" +
|
||||
data.value +
|
||||
"' onchange='textchange(" +
|
||||
data.id +
|
||||
")' />" +
|
||||
"</div>"
|
||||
);
|
||||
break;
|
||||
|
||||
case UI_TAB:
|
||||
$("#tabsnav").append(
|
||||
"<li><a onmouseup='tabclick(" + data.id + ")' href='#tab" + data.id + "'>" + data.value + "</a></li>"
|
||||
);
|
||||
$("#tabscontent").append("<div id='tab" + data.id + "'></div>");
|
||||
|
||||
tabs = $(".tabscontent").tabbedContent({ loop: true }).data("api");
|
||||
// switch to tab...
|
||||
$("a")
|
||||
.filter(function () {
|
||||
return $(this).attr("href") === "#click-to-switch";
|
||||
})
|
||||
.on("click", function (e) {
|
||||
var tab = prompt("Tab to switch to (number or id)?");
|
||||
if (!tabs.switchTab(tab)) {
|
||||
alert("That tab does not exist :\\");
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
break;
|
||||
|
||||
case UI_SELECT:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<select style='color:black;' id='select" +
|
||||
data.id +
|
||||
"' onchange='selectchange(" +
|
||||
data.id +
|
||||
")' />" +
|
||||
"</div>"
|
||||
);
|
||||
break;
|
||||
|
||||
case UI_OPTION:
|
||||
if (data.parentControl) {
|
||||
var parent = $("#select" + data.parentControl);
|
||||
parent.append(
|
||||
"<option id='option" +
|
||||
data.id +
|
||||
"' value='" +
|
||||
data.value +
|
||||
"' " +
|
||||
data.selected +
|
||||
">" +
|
||||
data.label +
|
||||
"</option>"
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case UI_MIN:
|
||||
if (data.parentControl) {
|
||||
var parent = $("#id" + data.parentControl + " input");
|
||||
if (parent.size()) {
|
||||
parent.attr("min", data.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UI_MAX:
|
||||
if (data.parentControl) {
|
||||
var parent = $("#id" + data.parentControl + " input");
|
||||
if (parent.size()) {
|
||||
parent.attr("max", data.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UI_STEP:
|
||||
if (data.parentControl) {
|
||||
var parent = $("#id" + data.parentControl + " input");
|
||||
if (parent.size()) {
|
||||
parent.attr("step", data.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UI_GRAPH:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"<figure id='graph" +
|
||||
data.id +
|
||||
"'>" +
|
||||
"<figcaption>" +
|
||||
data.label +
|
||||
"</figcaption>" +
|
||||
"</figure>" +
|
||||
"</div>"
|
||||
);
|
||||
graphData[data.id] = restoreGraphData(data.id);
|
||||
renderGraphSvg(graphData[data.id], "graph" + data.id);
|
||||
break;
|
||||
case ADD_GRAPH_POINT:
|
||||
var ts = Math.round(new Date().getTime() / 1000);
|
||||
graphData[data.id].push({ x: ts, y: data.value });
|
||||
saveGraphData();
|
||||
renderGraphSvg(graphData[data.id], "graph" + data.id);
|
||||
break;
|
||||
case CLEAR_GRAPH:
|
||||
graphData[data.id] = [];
|
||||
saveGraphData();
|
||||
renderGraphSvg(graphData[data.id], "graph" + data.id);
|
||||
break;
|
||||
case UI_GAUGE:
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"WILL BE A GAUGE <input style='color:black;' id='gauge" +
|
||||
data.id +
|
||||
"' type='number' value='" +
|
||||
data.value +
|
||||
"' onchange='numberchange(" +
|
||||
data.id +
|
||||
")' />" +
|
||||
"</div>"
|
||||
);
|
||||
break;
|
||||
|
||||
case UI_ACCEL:
|
||||
if (hasAccel) break;
|
||||
var parent;
|
||||
if (data.parentControl) {
|
||||
parent = $("#tab" + data.parentControl);
|
||||
} else {
|
||||
parent = $("#row");
|
||||
}
|
||||
hasAccel = true;
|
||||
parent.append(
|
||||
"<div id='id" +
|
||||
data.id +
|
||||
"' class='two columns card tcenter " +
|
||||
colorClass(data.color) +
|
||||
"'>" +
|
||||
"<h5>" +
|
||||
data.label +
|
||||
"</h5><hr/>" +
|
||||
"ACCEL // Not implemented fully!<div class='accelerometer' id='accel" +
|
||||
data.id +
|
||||
"' ><div class='ball" +
|
||||
data.id +
|
||||
"'></div><pre class='accelerometeroutput" +
|
||||
data.id +
|
||||
"'></pre>" +
|
||||
"</div>"
|
||||
);
|
||||
|
||||
requestOrientationPermission();
|
||||
break;
|
||||
|
||||
case UPDATE_LABEL:
|
||||
$("#l" + data.id).html(data.value);
|
||||
break;
|
||||
|
||||
case UPDATE_SWITCHER:
|
||||
switcher(data.id, data.value == "0" ? 0 : 1);
|
||||
break;
|
||||
|
||||
case UPDATE_SLIDER:
|
||||
slider_move($("#id" + data.id), data.value, "100", false);
|
||||
break;
|
||||
|
||||
case UPDATE_NUMBER:
|
||||
$("#num" + data.id).val(data.value);
|
||||
break;
|
||||
|
||||
case UPDATE_TEXT_INPUT:
|
||||
$("#text" + data.id).val(data.value);
|
||||
break;
|
||||
|
||||
case UPDATE_SELECT:
|
||||
$("#select" + data.id).val(data.value);
|
||||
break;
|
||||
|
||||
case UPDATE_BUTTON:
|
||||
case UPDATE_PAD:
|
||||
case UPDATE_CPAD:
|
||||
break;
|
||||
case UPDATE_GAUGE:
|
||||
$("#gauge" + data.id).val(data.value);
|
||||
break;
|
||||
case UPDATE_ACCEL:
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error("Unknown type or event");
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.type >= UPDATE_OFFSET && data.type < UI_INITIAL_GUI) {
|
||||
var element = $("#id" + data.id);
|
||||
if (data.type == UPDATE_SLIDER) {
|
||||
element.removeClass(
|
||||
"slider-turquoise slider-emerald slider-peterriver slider-wetasphalt slider-sunflower slider-carrot slider-alizarin"
|
||||
);
|
||||
element.addClass("slider-" + colorClass(data.color));
|
||||
} else {
|
||||
element.removeClass(
|
||||
"turquoise emerald peterriver wetasphalt sunflower carrot alizarin"
|
||||
);
|
||||
element.addClass(colorClass(data.color));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
websock.onmessage = handleEvent;
|
||||
}
|
||||
|
||||
function sliderchange(number) {
|
||||
var val = $("#sl" + number).val();
|
||||
websock.send("slvalue:" + val + ":" + number);
|
||||
}
|
||||
|
||||
function numberchange(number) {
|
||||
var val = $("#num" + number).val();
|
||||
websock.send("nvalue:" + val + ":" + number);
|
||||
}
|
||||
|
||||
function textchange(number) {
|
||||
var val = $("#text" + number).val();
|
||||
websock.send("tvalue:" + val + ":" + number);
|
||||
}
|
||||
|
||||
function tabclick(number) {
|
||||
var val = $("#tab" + number).val();
|
||||
websock.send("tabvalue:" + val + ":" + number);
|
||||
}
|
||||
|
||||
function selectchange(number) {
|
||||
var val = $("#select" + number).val();
|
||||
websock.send("svalue:" + val + ":" + number);
|
||||
}
|
||||
|
||||
function buttonclick(number, isdown) {
|
||||
if (isdown) websock.send("bdown:" + number);
|
||||
else websock.send("bup:" + number);
|
||||
}
|
||||
|
||||
function padclick(type, number, isdown) {
|
||||
switch (type) {
|
||||
case CENTER:
|
||||
if (isdown) websock.send("pcdown:" + number);
|
||||
else websock.send("pcup:" + number);
|
||||
break;
|
||||
case UP:
|
||||
if (isdown) websock.send("pfdown:" + number);
|
||||
else websock.send("pfup:" + number);
|
||||
break;
|
||||
case DOWN:
|
||||
if (isdown) websock.send("pbdown:" + number);
|
||||
else websock.send("pbup:" + number);
|
||||
break;
|
||||
case LEFT:
|
||||
if (isdown) websock.send("pldown:" + number);
|
||||
else websock.send("plup:" + number);
|
||||
break;
|
||||
case RIGHT:
|
||||
if (isdown) websock.send("prdown:" + number);
|
||||
else websock.send("prup:" + number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function switcher(number, state) {
|
||||
if (state == null) {
|
||||
if ($("#s" + number).is(":checked")) {
|
||||
websock.send("sactive:" + number);
|
||||
$("#sl" + number).addClass("checked");
|
||||
} else {
|
||||
websock.send("sinactive:" + number);
|
||||
$("#sl" + number).removeClass("checked");
|
||||
}
|
||||
} else if (state == 1) {
|
||||
$("#sl" + number).addClass("checked");
|
||||
$("#sl" + number).prop("checked", true);
|
||||
} else if (state == 0) {
|
||||
$("#sl" + number).removeClass("checked");
|
||||
$("#sl" + number).prop("checked", false);
|
||||
}
|
||||
}
|
||||
|
||||
var rangeSlider = function (isDiscrete) {
|
||||
var slider = $(".range-slider"),
|
||||
range = $(".range-slider__range"),
|
||||
value = $(".range-slider__value");
|
||||
|
||||
slider.each(function () {
|
||||
value.each(function () {
|
||||
var value = $(this).prev().attr("value");
|
||||
$(this).html(value);
|
||||
});
|
||||
|
||||
if (!isDiscrete) {
|
||||
range.on({
|
||||
input: function () {
|
||||
sliderchange($(this).attr("id").replace(/^\D+/g, ""));
|
||||
},
|
||||
});
|
||||
} else {
|
||||
range.on({
|
||||
input: function () {
|
||||
$(this).next().html(this.value);
|
||||
},
|
||||
change: function () {
|
||||
sliderchange($(this).attr("id").replace(/^\D+/g, ""));
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
1
data/js/controls.min.js
vendored
Normal file
297
data/js/graph.js
Normal file
@ -0,0 +1,297 @@
|
||||
function lineGraph(parent, xAccessor, yAccessor) {
|
||||
// Constant size definitions TODO: this could well be improved and calculated...
|
||||
const width = 620;
|
||||
const height = 420;
|
||||
const gutter = 40;
|
||||
const pixelsPerTick = 30;
|
||||
|
||||
/**
|
||||
* Creates an object that contatins transform functions that:
|
||||
* transforms numeric data into coordinate space, linearly
|
||||
* transforms coordinates into numeric data, linearly
|
||||
*/
|
||||
function numericTransformer(dataMin, dataMax, pxMin, pxMax) {
|
||||
var dataDiff = dataMax - dataMin,
|
||||
pxDiff = pxMax - pxMin,
|
||||
dataRatio = pxDiff / dataDiff,
|
||||
coordRatio = dataDiff / pxDiff;
|
||||
|
||||
return {
|
||||
// transforms a data point to a coordinate point
|
||||
toCoord: function(data) {
|
||||
return (data - dataMin) * dataRatio + pxMin;
|
||||
},
|
||||
// transforms a coord point to a data point
|
||||
toData: function(coord) {
|
||||
return (coord - pxMin) * coordRatio + dataMin;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an axis.
|
||||
* orientation = 'x' or 'y'
|
||||
* transform = a function for transforming px into data for labeling/creating tick marks
|
||||
*/
|
||||
function axisRenderer(orientation, transform) {
|
||||
var axisGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
||||
var axisPath = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"path"
|
||||
);
|
||||
|
||||
axisGroup.setAttribute("class", orientation + "-axis");
|
||||
|
||||
var xMin = gutter;
|
||||
var xMax = width - gutter;
|
||||
var yMin = height - gutter;
|
||||
var yMax = gutter;
|
||||
|
||||
if (orientation === "x") {
|
||||
axisPath.setAttribute(
|
||||
"d",
|
||||
"M " + xMin + " " + yMin + " L " + xMax + " " + yMin
|
||||
);
|
||||
|
||||
// generate labels
|
||||
for (var i = xMin; i <= xMax; i++) {
|
||||
if ((i - xMin) % pixelsPerTick === 0 && i !== xMin) {
|
||||
var text = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"text"
|
||||
);
|
||||
// primitive formatting
|
||||
text.innerHTML = Math.floor(transform(i));
|
||||
text.setAttribute("x", i);
|
||||
text.setAttribute("y", yMin);
|
||||
// offset the text by 1 em
|
||||
text.setAttribute("dy", "1em");
|
||||
axisGroup.appendChild(text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
axisPath.setAttribute(
|
||||
"d",
|
||||
"M " + xMin + " " + yMin + " L " + xMin + " " + yMax
|
||||
);
|
||||
|
||||
// generate labels
|
||||
for (var i = yMax; i <= yMin; i++) {
|
||||
if ((i - yMin) % pixelsPerTick === 0 && i !== yMin) {
|
||||
var tickGroup = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"g"
|
||||
);
|
||||
var gridLine = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"path"
|
||||
);
|
||||
text = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
||||
// primitive formatting
|
||||
text.innerHTML = Math.floor(transform(i));
|
||||
text.setAttribute("x", xMin);
|
||||
text.setAttribute("y", i);
|
||||
// offset the text labels to align with grid line and keeping it to the left of the y-axis
|
||||
text.setAttribute("dx", "-.5em");
|
||||
text.setAttribute("dy", ".3em");
|
||||
|
||||
gridLine.setAttribute(
|
||||
"d",
|
||||
"M " + xMin + " " + i + " L " + xMax + " " + i
|
||||
);
|
||||
|
||||
tickGroup.appendChild(gridLine);
|
||||
tickGroup.appendChild(text);
|
||||
axisGroup.appendChild(tickGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
axisGroup.appendChild(axisPath);
|
||||
parent.appendChild(axisGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a line
|
||||
*/
|
||||
function lineRenderer(xAccessor, yAccessor, xTransform, yTransform) {
|
||||
var line = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||
|
||||
xAccessor.reset();
|
||||
yAccessor.reset();
|
||||
if (!xAccessor.hasNext() || !yAccessor.hasNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var pathString =
|
||||
"M " + xTransform(xAccessor.next()) + " " + yTransform(yAccessor.next());
|
||||
while (xAccessor.hasNext() && yAccessor.hasNext()) {
|
||||
pathString +=
|
||||
" L " +
|
||||
xTransform(xAccessor.next()) +
|
||||
" " +
|
||||
yTransform(yAccessor.next());
|
||||
}
|
||||
|
||||
line.setAttribute("class", "series");
|
||||
line.setAttribute("d", pathString);
|
||||
|
||||
parent.appendChild(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders data point circles + text labels
|
||||
*/
|
||||
function pointRenderer(xAccessor, yAccessor, xTransform, yTransform) {
|
||||
var pointGroup = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"g"
|
||||
);
|
||||
|
||||
pointGroup.setAttribute("class", "data-points");
|
||||
|
||||
xAccessor.reset();
|
||||
yAccessor.reset();
|
||||
if (!xAccessor.hasNext() || !yAccessor.hasNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (xAccessor.hasNext() && yAccessor.hasNext()) {
|
||||
var xDataValue = xAccessor.next();
|
||||
var x = xTransform(xDataValue);
|
||||
var yDataValue = yAccessor.next();
|
||||
var y = yTransform(yDataValue);
|
||||
|
||||
var circle = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"circle"
|
||||
);
|
||||
circle.setAttribute("cx", x);
|
||||
circle.setAttribute("cy", y);
|
||||
circle.setAttribute("r", "4");
|
||||
|
||||
var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
||||
// primitive formatting
|
||||
text.innerHTML = Math.floor(xDataValue) + " / " + Math.floor(yDataValue);
|
||||
text.setAttribute("x", x);
|
||||
text.setAttribute("y", y);
|
||||
|
||||
text.setAttribute("dx", "1em");
|
||||
text.setAttribute("dy", "-.7em");
|
||||
|
||||
pointGroup.appendChild(circle);
|
||||
pointGroup.appendChild(text);
|
||||
}
|
||||
|
||||
parent.appendChild(pointGroup);
|
||||
}
|
||||
|
||||
// perform the rendering
|
||||
xTransform = numericTransformer(
|
||||
xAccessor.min(),
|
||||
xAccessor.max(),
|
||||
0 + gutter,
|
||||
width - gutter
|
||||
);
|
||||
// NOTE: for y... have to reverse coordinate space
|
||||
yTransform = numericTransformer(
|
||||
yAccessor.min(),
|
||||
yAccessor.max(),
|
||||
height - gutter,
|
||||
0 + gutter
|
||||
);
|
||||
|
||||
axisRenderer("x", xTransform.toData);
|
||||
axisRenderer("y", yTransform.toData);
|
||||
|
||||
lineRenderer(xAccessor, yAccessor, xTransform.toCoord, yTransform.toCoord);
|
||||
pointRenderer(xAccessor, yAccessor, xTransform.toCoord, yTransform.toCoord);
|
||||
}
|
||||
|
||||
// Final render function
|
||||
function renderGraphSvg(dataArray, renderId) {
|
||||
var figure = document.getElementById(renderId);
|
||||
while (figure.hasChildNodes()) {
|
||||
figure.removeChild(figure.lastChild);
|
||||
}
|
||||
//console.log(dataArray);
|
||||
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
svg.setAttribute("viewBox", "0 0 640 440");
|
||||
svg.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
||||
|
||||
lineGraph(
|
||||
svg,
|
||||
// time accessor
|
||||
(function(data, min, max) {
|
||||
var i = 0;
|
||||
return {
|
||||
hasNext: function() {
|
||||
return i < data.length;
|
||||
},
|
||||
next: function() {
|
||||
return data[i++].x;
|
||||
},
|
||||
reset: function() {
|
||||
i = 0;
|
||||
},
|
||||
min: function() {
|
||||
return min;
|
||||
},
|
||||
max: function() {
|
||||
return max;
|
||||
}
|
||||
};
|
||||
})(
|
||||
dataArray,
|
||||
Math.min.apply(
|
||||
Math,
|
||||
dataArray.map(function(o) {
|
||||
return o.x;
|
||||
})
|
||||
),
|
||||
Math.max.apply(
|
||||
Math,
|
||||
dataArray.map(function(o) {
|
||||
return o.x;
|
||||
})
|
||||
)
|
||||
),
|
||||
// value accessor
|
||||
(function(data, min, max) {
|
||||
var i = 0;
|
||||
return {
|
||||
hasNext: function() {
|
||||
return i < data.length;
|
||||
},
|
||||
next: function() {
|
||||
return data[i++].y;
|
||||
},
|
||||
reset: function() {
|
||||
i = 0;
|
||||
},
|
||||
min: function() {
|
||||
return min;
|
||||
},
|
||||
max: function() {
|
||||
return max;
|
||||
}
|
||||
};
|
||||
})(
|
||||
dataArray,
|
||||
Math.min.apply(
|
||||
Math,
|
||||
dataArray.map(function(o) {
|
||||
return o.y;
|
||||
})
|
||||
),
|
||||
Math.max.apply(
|
||||
Math,
|
||||
dataArray.map(function(o) {
|
||||
return o.y;
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
figure.appendChild(svg);
|
||||
}
|
15
data/js/graph.min.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
function lineGraph(parent,xAccessor,yAccessor){const width=620;const height=420;const gutter=40;const pixelsPerTick=30;function numericTransformer(dataMin,dataMax,pxMin,pxMax){var dataDiff=dataMax-dataMin,pxDiff=pxMax-pxMin,dataRatio=pxDiff/dataDiff,coordRatio=dataDiff/pxDiff;return{toCoord:function(data){return(data-dataMin)*dataRatio+pxMin;},toData:function(coord){return(coord-pxMin)*coordRatio+dataMin;}};}
|
||||
function axisRenderer(orientation,transform){var axisGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var axisPath=document.createElementNS("http://www.w3.org/2000/svg","path");axisGroup.setAttribute("class",orientation+"-axis");var xMin=gutter;var xMax=width-gutter;var yMin=height-gutter;var yMax=gutter;if(orientation==="x"){axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMax+" "+yMin);for(var i=xMin;i<=xMax;i++){if((i-xMin)%pixelsPerTick===0&&i!==xMin){var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",i);text.setAttribute("y",yMin);text.setAttribute("dy","1em");axisGroup.appendChild(text);}}}else{axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMin+" "+yMax);for(var i=yMax;i<=yMin;i++){if((i-yMin)%pixelsPerTick===0&&i!==yMin){var tickGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var gridLine=document.createElementNS("http://www.w3.org/2000/svg","path");text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",xMin);text.setAttribute("y",i);text.setAttribute("dx","-.5em");text.setAttribute("dy",".3em");gridLine.setAttribute("d","M "+xMin+" "+i+" L "+xMax+" "+i);tickGroup.appendChild(gridLine);tickGroup.appendChild(text);axisGroup.appendChild(tickGroup);}}}
|
||||
axisGroup.appendChild(axisPath);parent.appendChild(axisGroup);}
|
||||
function lineRenderer(xAccessor,yAccessor,xTransform,yTransform){var line=document.createElementNS("http://www.w3.org/2000/svg","path");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
var pathString="M "+xTransform(xAccessor.next())+" "+yTransform(yAccessor.next());while(xAccessor.hasNext()&&yAccessor.hasNext()){pathString+=" L "+
|
||||
xTransform(xAccessor.next())+
|
||||
" "+
|
||||
yTransform(yAccessor.next());}
|
||||
line.setAttribute("class","series");line.setAttribute("d",pathString);parent.appendChild(line);}
|
||||
function pointRenderer(xAccessor,yAccessor,xTransform,yTransform){var pointGroup=document.createElementNS("http://www.w3.org/2000/svg","g");pointGroup.setAttribute("class","data-points");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
while(xAccessor.hasNext()&&yAccessor.hasNext()){var xDataValue=xAccessor.next();var x=xTransform(xDataValue);var yDataValue=yAccessor.next();var y=yTransform(yDataValue);var circle=document.createElementNS("http://www.w3.org/2000/svg","circle");circle.setAttribute("cx",x);circle.setAttribute("cy",y);circle.setAttribute("r","4");var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(xDataValue)+" / "+Math.floor(yDataValue);text.setAttribute("x",x);text.setAttribute("y",y);text.setAttribute("dx","1em");text.setAttribute("dy","-.7em");pointGroup.appendChild(circle);pointGroup.appendChild(text);}
|
||||
parent.appendChild(pointGroup);}
|
||||
xTransform=numericTransformer(xAccessor.min(),xAccessor.max(),0+gutter,width-gutter);yTransform=numericTransformer(yAccessor.min(),yAccessor.max(),height-gutter,0+gutter);axisRenderer("x",xTransform.toData);axisRenderer("y",yTransform.toData);lineRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);pointRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);}
|
||||
function renderGraphSvg(dataArray,renderId){var figure=document.getElementById(renderId);while(figure.hasChildNodes()){figure.removeChild(figure.lastChild);}
|
||||
var svg=document.createElementNS("http://www.w3.org/2000/svg","svg");svg.setAttribute("viewBox","0 0 640 440");svg.setAttribute("preserveAspectRatio","xMidYMid meet");lineGraph(svg,(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].x;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.x;})),Math.max.apply(Math,dataArray.map(function(o){return o.x;}))),(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].y;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.y;})),Math.max.apply(Math,dataArray.map(function(o){return o.y;}))));figure.appendChild(svg);}
|
123
data/js/slider.js
Normal file
@ -0,0 +1,123 @@
|
||||
/* -----------------------------------------------------
|
||||
Material Design Sliders
|
||||
CodePen URL: https://codepen.io/rkchauhan/pen/xVGGpR
|
||||
By: Ravikumar Chauhan
|
||||
-------------------------------------------------------- */
|
||||
function rkmd_rangeSlider(selector) {
|
||||
var self, slider_width, slider_offset, curnt, sliderDiscrete, range, slider;
|
||||
self = $(selector);
|
||||
slider_width = self.width();
|
||||
slider_offset = self.offset().left;
|
||||
sliderDiscrete = self;
|
||||
|
||||
sliderDiscrete.each(function (i, v) {
|
||||
curnt = $(this);
|
||||
curnt.append(sliderDiscrete_tmplt());
|
||||
range = curnt.find('input[type="range"]');
|
||||
slider = curnt.find(".slider");
|
||||
slider_fill = slider.find(".slider-fill");
|
||||
slider_handle = slider.find(".slider-handle");
|
||||
slider_label = slider.find(".slider-label");
|
||||
|
||||
var range_val = parseInt(range.val());
|
||||
slider_fill.css("width", range_val + "%");
|
||||
slider_handle.css("left", range_val + "%");
|
||||
slider_label.find("span").text(range_val);
|
||||
});
|
||||
|
||||
self.on("mousedown touchstart", ".slider-handle", function (e) {
|
||||
if (e.button === 2) {
|
||||
return false;
|
||||
}
|
||||
var parents = $(this).parents(".rkmd-slider");
|
||||
var slider_width = parents.width();
|
||||
var slider_offset = parents.offset().left;
|
||||
var check_range = parents.find('input[type="range"]').is(":disabled");
|
||||
if (check_range === true) {
|
||||
return false;
|
||||
}
|
||||
$(this).addClass("is-active");
|
||||
var moveFu = function (e) {
|
||||
var pageX = e.pageX || e.changedTouches[0].pageX;
|
||||
var slider_new_width = pageX - slider_offset;
|
||||
if (slider_new_width <= slider_width && !(slider_new_width < "0")) {
|
||||
slider_move(parents, slider_new_width, slider_width, true);
|
||||
}
|
||||
};
|
||||
var upFu = function (e) {
|
||||
$(this).off(handlers);
|
||||
parents.find(".is-active").removeClass("is-active");
|
||||
};
|
||||
|
||||
var handlers = {
|
||||
mousemove: moveFu,
|
||||
touchmove: moveFu,
|
||||
mouseup: upFu,
|
||||
touchend: upFu,
|
||||
};
|
||||
$(document).on(handlers);
|
||||
});
|
||||
|
||||
self.on("mousedown touchstart", ".slider", function (e) {
|
||||
if (e.button === 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var parents = $(this).parents(".rkmd-slider");
|
||||
var slider_width = parents.width();
|
||||
var slider_offset = parents.offset().left;
|
||||
var check_range = parents.find('input[type="range"]').is(":disabled");
|
||||
|
||||
if (check_range === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var slider_new_width = e.pageX - slider_offset;
|
||||
if (slider_new_width <= slider_width && !(slider_new_width < "0")) {
|
||||
slider_move(parents, slider_new_width, slider_width, true);
|
||||
}
|
||||
var upFu = function (e) {
|
||||
$(this).off(handlers);
|
||||
};
|
||||
|
||||
var handlers = {
|
||||
mouseup: upFu,
|
||||
touchend: upFu,
|
||||
};
|
||||
$(document).on(handlers);
|
||||
});
|
||||
}
|
||||
|
||||
function sliderDiscrete_tmplt() {
|
||||
var tmplt =
|
||||
'<div class="slider">' +
|
||||
'<div class="slider-fill"></div>' +
|
||||
'<div class="slider-handle"><div class="slider-label"><span>0</span></div></div>' +
|
||||
"</div>";
|
||||
|
||||
return tmplt;
|
||||
}
|
||||
|
||||
function slider_move(parents, newW, sliderW, send) {
|
||||
var slider_new_val = parseInt(Math.round((newW / sliderW) * 100));
|
||||
|
||||
var slider_fill = parents.find(".slider-fill");
|
||||
var slider_handle = parents.find(".slider-handle");
|
||||
var range = parents.find('input[type="range"]');
|
||||
range.next().html(newW); // update value
|
||||
|
||||
slider_fill.css("width", slider_new_val + "%");
|
||||
slider_handle.css({
|
||||
left: slider_new_val + "%",
|
||||
transition: "none",
|
||||
"-webkit-transition": "none",
|
||||
"-moz-transition": "none",
|
||||
});
|
||||
|
||||
range.val(slider_new_val);
|
||||
if (parents.find(".slider-handle span").text() != slider_new_val) {
|
||||
parents.find(".slider-handle span").text(slider_new_val);
|
||||
var number = parents.attr("id").substring(2);
|
||||
if (send) websock.send("slvalue:" + slider_new_val + ":" + number);
|
||||
}
|
||||
}
|
11
data/js/slider.min.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
function rkmd_rangeSlider(selector){var self,slider_width,slider_offset,curnt,sliderDiscrete,range,slider;self=$(selector);slider_width=self.width();slider_offset=self.offset().left;sliderDiscrete=self;sliderDiscrete.each(function(i,v){curnt=$(this);curnt.append(sliderDiscrete_tmplt());range=curnt.find('input[type="range"]');slider=curnt.find(".slider");slider_fill=slider.find(".slider-fill");slider_handle=slider.find(".slider-handle");slider_label=slider.find(".slider-label");var range_val=parseInt(range.val());slider_fill.css("width",range_val+"%");slider_handle.css("left",range_val+"%");slider_label.find("span").text(range_val);});self.on("mousedown touchstart",".slider-handle",function(e){if(e.button===2){return false;}
|
||||
var parents=$(this).parents(".rkmd-slider");var slider_width=parents.width();var slider_offset=parents.offset().left;var check_range=parents.find('input[type="range"]').is(":disabled");if(check_range===true){return false;}
|
||||
$(this).addClass("is-active");var moveFu=function(e){var pageX=e.pageX||e.changedTouches[0].pageX;var slider_new_width=pageX-slider_offset;if(slider_new_width<=slider_width&&!(slider_new_width<"0")){slider_move(parents,slider_new_width,slider_width,true);}};var upFu=function(e){$(this).off(handlers);parents.find(".is-active").removeClass("is-active");};var handlers={mousemove:moveFu,touchmove:moveFu,mouseup:upFu,touchend:upFu,};$(document).on(handlers);});self.on("mousedown touchstart",".slider",function(e){if(e.button===2){return false;}
|
||||
var parents=$(this).parents(".rkmd-slider");var slider_width=parents.width();var slider_offset=parents.offset().left;var check_range=parents.find('input[type="range"]').is(":disabled");if(check_range===true){return false;}
|
||||
var slider_new_width=e.pageX-slider_offset;if(slider_new_width<=slider_width&&!(slider_new_width<"0")){slider_move(parents,slider_new_width,slider_width,true);}
|
||||
var upFu=function(e){$(this).off(handlers);};var handlers={mouseup:upFu,touchend:upFu,};$(document).on(handlers);});}
|
||||
function sliderDiscrete_tmplt(){var tmplt='<div class="slider">'+
|
||||
'<div class="slider-fill"></div>'+
|
||||
'<div class="slider-handle"><div class="slider-label"><span>0</span></div></div>'+
|
||||
"</div>";return tmplt;}
|
||||
function slider_move(parents,newW,sliderW,send){var slider_new_val=parseInt(Math.round((newW/sliderW)*100));var slider_fill=parents.find(".slider-fill");var slider_handle=parents.find(".slider-handle");var range=parents.find('input[type="range"]');range.next().html(newW);slider_fill.css("width",slider_new_val+"%");slider_handle.css({left:slider_new_val+"%",transition:"none","-webkit-transition":"none","-moz-transition":"none",});range.val(slider_new_val);if(parents.find(".slider-handle span").text()!=slider_new_val){parents.find(".slider-handle span").text(slider_new_val);var number=parents.attr("id").substring(2);if(send)websock.send("slvalue:"+slider_new_val+":"+number);}}
|
351
data/js/tabbedcontent.js
Normal file
@ -0,0 +1,351 @@
|
||||
/**
|
||||
* Tabs plugin for jQuery created by Òscar Casajuana < elboletaire at underave dot net >
|
||||
*
|
||||
* @copyright Copyright 2013-2016 Òscar Casajuana
|
||||
* @license MIT
|
||||
* @author Òscar Casajuana Alonso <elboletaire at underave dot net>
|
||||
*/
|
||||
;(function($, document, window, undefined) {
|
||||
"use strict";
|
||||
|
||||
var Tabbedcontent = function(tabcontent, options) {
|
||||
var defaults = {
|
||||
links : tabcontent.prev().find('a').length ? tabcontent.prev().find('a') : '.tabs a', // the tabs itself. By default it selects the links contained in the previous wrapper or the links inside ".tabs a" if there's no previous item
|
||||
errorSelector : '.error-message', // false to disable
|
||||
speed : false, // speed of the show effect. Set to null or false to disable
|
||||
onSwitch : false, // onSwitch callback
|
||||
onInit : false, // onInit callback
|
||||
currentClass : 'active', // current selected tab class (is set to the <a> element)
|
||||
tabErrorClass : 'has-errors', // a class to be added to the tab where errorSelector is detected
|
||||
history : true, // set to false to disable HTML5 history
|
||||
historyOnInit : true, // allows to deactivate the history for the intial autmatically tab switch on load
|
||||
loop : false // if set to true will loop between tabs when using the next() and prev() api methods
|
||||
},
|
||||
firstTime = false,
|
||||
children = tabcontent.children(),
|
||||
history = window.history,
|
||||
loc = document.location,
|
||||
current = null
|
||||
;
|
||||
|
||||
options = $.extend(defaults, options);
|
||||
|
||||
if (!(options.links instanceof $)) {
|
||||
options.links = $(options.links);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified tab id exists.
|
||||
*
|
||||
* @param string tab Tab #id
|
||||
* @return bool
|
||||
*/
|
||||
function tabExists(tab) {
|
||||
return Boolean(children.filter(tab).length);
|
||||
}
|
||||
/**
|
||||
* Checks if the current tab is the
|
||||
* first one in the tabs set.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function isFirst() {
|
||||
return current === 0;
|
||||
}
|
||||
/**
|
||||
* Checks if the passed number is an integer.
|
||||
*
|
||||
* @param mixed num The value to be checked.
|
||||
* @return bool
|
||||
*/
|
||||
function isInt(num) {
|
||||
return num % 1 === 0;
|
||||
}
|
||||
/**
|
||||
* Checks if the current tab is the
|
||||
* last one in the tabs set.
|
||||
*
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
function isLast() {
|
||||
return current === children.length - 1;
|
||||
}
|
||||
/**
|
||||
* Filters a tab based on current links href.
|
||||
*
|
||||
* Method for compatibility with Zepto.js
|
||||
*
|
||||
* @param string tab Tab #href
|
||||
* @return bool
|
||||
*/
|
||||
function filterTab(tab) {
|
||||
return $(this).attr('href').match(new RegExp(tab + '$'));
|
||||
}
|
||||
/**
|
||||
* Returns an object containing two jQuery instances:
|
||||
* one for the tab content and the other for its link.
|
||||
*
|
||||
* @param mixed tab A tab id, #id or index.
|
||||
* @return object With thi
|
||||
*/
|
||||
function getTab(tab) {
|
||||
if (tab instanceof $) {
|
||||
return {
|
||||
tab : tab,
|
||||
link : options.links.eq(tab.index())
|
||||
};
|
||||
}
|
||||
if (isInt(tab)) {
|
||||
return {
|
||||
tab : children.eq(tab),
|
||||
link : options.links.eq(tab)
|
||||
};
|
||||
}
|
||||
if (children.filter(tab).length) {
|
||||
return {
|
||||
tab : children.filter(tab),
|
||||
link : options.links.filter(function() {
|
||||
return filterTab.apply(this, [tab]);
|
||||
})
|
||||
};
|
||||
}
|
||||
// assume it's an id without #
|
||||
return {
|
||||
tab : children.filter('#' + tab),
|
||||
link : options.links.filter(function() {
|
||||
return filterTab.apply(this, ['#' + tab]);
|
||||
})
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Returns the index of the current tab.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getCurrent() {
|
||||
return options.links.parent().filter('.' + options.currentClass).index();
|
||||
}
|
||||
/**
|
||||
* Go to the next tab in the tabs set.
|
||||
*
|
||||
* @param bool loop If defined will overwrite options.loop
|
||||
* @return mixed
|
||||
*/
|
||||
function next(loop) {
|
||||
++current;
|
||||
|
||||
if (loop === undefined) loop = options.loop;
|
||||
|
||||
if (current < children.length) {
|
||||
return switchTab(current, true);
|
||||
} else if (loop && current >= children.length) {
|
||||
return switchTab(0, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Go to the previous tab in the tabs set.
|
||||
*
|
||||
* @param bool loop If defined will overwrite options.loop
|
||||
* @return mixed
|
||||
*/
|
||||
function prev(loop) {
|
||||
--current;
|
||||
|
||||
if (loop === undefined) loop = options.loop;
|
||||
|
||||
if (current >= 0) {
|
||||
return switchTab(current, true);
|
||||
} else if (loop && current < 0) {
|
||||
return switchTab(children.length - 1, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* onSwitch callback for switchTab.
|
||||
*
|
||||
* @param string tab The tab #id
|
||||
* @return void
|
||||
*/
|
||||
function onSwitch(tab) {
|
||||
if (options.history && options.historyOnInit && firstTime && history !== undefined && ('pushState' in history)) {
|
||||
firstTime = false;
|
||||
window.setTimeout(function() {
|
||||
history.replaceState(null, '', tab);
|
||||
}, 100);
|
||||
}
|
||||
current = getCurrent();
|
||||
if (options.onSwitch && typeof options.onSwitch === 'function') {
|
||||
options.onSwitch(tab, api());
|
||||
}
|
||||
tabcontent.trigger('tabcontent.switch', [tab, api()]);
|
||||
}
|
||||
/**
|
||||
* Switch to specified tab.
|
||||
*
|
||||
* @param mixed tab The tab to switch to.
|
||||
* @param bool api Set to true to force history writing.
|
||||
* @return bool Returns false if tab does not exist; true otherwise.
|
||||
*/
|
||||
function switchTab(tab, api) {
|
||||
if (!tab.toString().match(/^#/)) {
|
||||
tab = '#' + getTab(tab).tab.attr('id');
|
||||
}
|
||||
|
||||
if (!tabExists(tab)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Toggle active class
|
||||
options.links.attr('aria-selected','false').parent().removeClass(options.currentClass);
|
||||
options.links.filter(function() {
|
||||
return filterTab.apply(this, [tab]);
|
||||
}).attr('aria-selected','true').parent().addClass(options.currentClass);
|
||||
// Hide tabs
|
||||
children.hide();
|
||||
|
||||
// We need to force the change of the hash if we're using the API
|
||||
if (options.history && api) {
|
||||
if (history !== undefined && ('pushState' in history)) {
|
||||
history.pushState(null, '', tab);
|
||||
} else {
|
||||
// force hash change to add it to the history
|
||||
window.location.hash = tab;
|
||||
}
|
||||
}
|
||||
|
||||
// Show tabs
|
||||
children.attr('aria-hidden','true').filter(tab).show(options.speed, function() {
|
||||
if (options.speed) {
|
||||
onSwitch(tab);
|
||||
}
|
||||
}).attr('aria-hidden','false');
|
||||
if (!options.speed) {
|
||||
onSwitch(tab);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Api method to switch tabs.
|
||||
*
|
||||
* @param mixed tab Tab to switch to.
|
||||
* @return bool Returns false if tab does not exist; true otherwise.
|
||||
*/
|
||||
function apiSwitch(tab) {
|
||||
return switchTab(tab, true);
|
||||
}
|
||||
/**
|
||||
* Method used to switch tabs using the
|
||||
* browser query hash.
|
||||
*
|
||||
* @param object e Event.
|
||||
* @return void
|
||||
*/
|
||||
function hashSwitch(e) {
|
||||
switchTab(loc.hash);
|
||||
}
|
||||
/**
|
||||
* Initialization method.
|
||||
*
|
||||
* The tab checking preference is:
|
||||
* - document.location.hash
|
||||
* - options.errorSelector
|
||||
* - first tab in the set of tabs
|
||||
*
|
||||
* The onInit method is called at the
|
||||
* end of this method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function init() {
|
||||
// Switch to tab using location.hash
|
||||
if (tabExists(loc.hash)) {
|
||||
// Switch to current hash tab
|
||||
switchTab(loc.hash);
|
||||
}
|
||||
// If there's a tab link with the options.currentClass set,
|
||||
// switch to that tab.
|
||||
else if (options.links.parent().filter('.' + options.currentClass).length) {
|
||||
switchTab(options.links.parent().filter('.' + options.currentClass).index());
|
||||
}
|
||||
// Switch to tab containing class options.errorSelector
|
||||
else if (options.errorSelector && children.find(options.errorSelector).length) {
|
||||
// Search for errors and show first tab containing one
|
||||
children.each(function() {
|
||||
if ($(this).find(options.errorSelector).length) {
|
||||
switchTab("#" + $(this).attr("id"));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Open first tab
|
||||
else {
|
||||
switchTab("#" + children.filter(":first-child").attr("id"));
|
||||
}
|
||||
// Add a class to every tab containing errors
|
||||
if (options.errorSelector) {
|
||||
children.find(options.errorSelector).each(function() {
|
||||
var tab = getTab($(this).parent());
|
||||
tab.link.parent().addClass(options.tabErrorClass);
|
||||
});
|
||||
}
|
||||
|
||||
// Binding
|
||||
if ('onhashchange' in window) {
|
||||
$(window).bind('hashchange', hashSwitch);
|
||||
} else { // old browsers
|
||||
var current_href = loc.href;
|
||||
window.setInterval(function() {
|
||||
if (current_href !== loc.href) {
|
||||
hashSwitch.call(window.event);
|
||||
current_href = loc.href;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
// Bind click event on links, to ensure we don't rewrite the URI in
|
||||
// case history is disabled
|
||||
$(options.links).on('click', function(e) {
|
||||
switchTab($(this).attr('href').replace(/^[^#]+/, ''), options.history);
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// onInit callback
|
||||
if (options.onInit && typeof options.onInit === 'function') {
|
||||
options.onInit(api());
|
||||
}
|
||||
tabcontent.trigger('tabcontent.init', [api()]);
|
||||
}
|
||||
/**
|
||||
* Returns the methods exposed in the api.
|
||||
*
|
||||
* @return object Containing each api method.
|
||||
*/
|
||||
function api() {
|
||||
return {
|
||||
'switch' : apiSwitch,
|
||||
'switchTab' : apiSwitch, // for old browsers
|
||||
'getCurrent' : getCurrent,
|
||||
'getTab' : getTab,
|
||||
'next' : next,
|
||||
'prev' : prev,
|
||||
'isFirst' : isFirst,
|
||||
'isLast' : isLast
|
||||
};
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
return api();
|
||||
};
|
||||
|
||||
$.fn.tabbedContent = function(options) {
|
||||
return this.each(function() {
|
||||
var tabs = new Tabbedcontent($(this), options);
|
||||
$(this).data('api', tabs);
|
||||
});
|
||||
};
|
||||
|
||||
})(window.jQuery || window.Zepto || window.$, document, window);
|
35
data/js/tabbedcontent.min.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
;(function($,document,window,undefined){"use strict";var Tabbedcontent=function(tabcontent,options){var defaults={links:tabcontent.prev().find('a').length?tabcontent.prev().find('a'):'.tabs a',errorSelector:'.error-message',speed:false,onSwitch:false,onInit:false,currentClass:'active',tabErrorClass:'has-errors',history:true,historyOnInit:true,loop:false},firstTime=false,children=tabcontent.children(),history=window.history,loc=document.location,current=null;options=$.extend(defaults,options);if(!(options.links instanceof $)){options.links=$(options.links);}
|
||||
function tabExists(tab){return Boolean(children.filter(tab).length);}
|
||||
function isFirst(){return current===0;}
|
||||
function isInt(num){return num%1===0;}
|
||||
function isLast(){return current===children.length-1;}
|
||||
function filterTab(tab){return $(this).attr('href').match(new RegExp(tab+'$'));}
|
||||
function getTab(tab){if(tab instanceof $){return{tab:tab,link:options.links.eq(tab.index())};}
|
||||
if(isInt(tab)){return{tab:children.eq(tab),link:options.links.eq(tab)};}
|
||||
if(children.filter(tab).length){return{tab:children.filter(tab),link:options.links.filter(function(){return filterTab.apply(this,[tab]);})};}
|
||||
return{tab:children.filter('#'+tab),link:options.links.filter(function(){return filterTab.apply(this,['#'+tab]);})};}
|
||||
function getCurrent(){return options.links.parent().filter('.'+options.currentClass).index();}
|
||||
function next(loop){++current;if(loop===undefined)loop=options.loop;if(current<children.length){return switchTab(current,true);}else if(loop&¤t>=children.length){return switchTab(0,true);}
|
||||
return false;}
|
||||
function prev(loop){--current;if(loop===undefined)loop=options.loop;if(current>=0){return switchTab(current,true);}else if(loop&¤t<0){return switchTab(children.length-1,true);}
|
||||
return false;}
|
||||
function onSwitch(tab){if(options.history&&options.historyOnInit&&firstTime&&history!==undefined&&('pushState'in history)){firstTime=false;window.setTimeout(function(){history.replaceState(null,'',tab);},100);}
|
||||
current=getCurrent();if(options.onSwitch&&typeof options.onSwitch==='function'){options.onSwitch(tab,api());}
|
||||
tabcontent.trigger('tabcontent.switch',[tab,api()]);}
|
||||
function switchTab(tab,api){if(!tab.toString().match(/^#/)){tab='#'+getTab(tab).tab.attr('id');}
|
||||
if(!tabExists(tab)){return false;}
|
||||
options.links.attr('aria-selected','false').parent().removeClass(options.currentClass);options.links.filter(function(){return filterTab.apply(this,[tab]);}).attr('aria-selected','true').parent().addClass(options.currentClass);children.hide();if(options.history&&api){if(history!==undefined&&('pushState'in history)){history.pushState(null,'',tab);}else{window.location.hash=tab;}}
|
||||
children.attr('aria-hidden','true').filter(tab).show(options.speed,function(){if(options.speed){onSwitch(tab);}}).attr('aria-hidden','false');if(!options.speed){onSwitch(tab);}
|
||||
return true;}
|
||||
function apiSwitch(tab){return switchTab(tab,true);}
|
||||
function hashSwitch(e){switchTab(loc.hash);}
|
||||
function init(){if(tabExists(loc.hash)){switchTab(loc.hash);}
|
||||
else if(options.links.parent().filter('.'+options.currentClass).length){switchTab(options.links.parent().filter('.'+options.currentClass).index());}
|
||||
else if(options.errorSelector&&children.find(options.errorSelector).length){children.each(function(){if($(this).find(options.errorSelector).length){switchTab("#"+$(this).attr("id"));return false;}});}
|
||||
else{switchTab("#"+children.filter(":first-child").attr("id"));}
|
||||
if(options.errorSelector){children.find(options.errorSelector).each(function(){var tab=getTab($(this).parent());tab.link.parent().addClass(options.tabErrorClass);});}
|
||||
if('onhashchange'in window){$(window).bind('hashchange',hashSwitch);}else{var current_href=loc.href;window.setInterval(function(){if(current_href!==loc.href){hashSwitch.call(window.event);current_href=loc.href;}},100);}
|
||||
$(options.links).on('click',function(e){switchTab($(this).attr('href').replace(/^[^#]+/,''),options.history);e.preventDefault();});if(options.onInit&&typeof options.onInit==='function'){options.onInit(api());}
|
||||
tabcontent.trigger('tabcontent.init',[api()]);}
|
||||
function api(){return{'switch':apiSwitch,'switchTab':apiSwitch,'getCurrent':getCurrent,'getTab':getTab,'next':next,'prev':prev,'isFirst':isFirst,'isLast':isLast};}
|
||||
init();return api();};$.fn.tabbedContent=function(options){return this.each(function(){var tabs=new Tabbedcontent($(this),options);$(this).data('api',tabs);});};})(window.jQuery||window.Zepto||window.$,document,window);
|
BIN
docs/Memory ESP32.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
docs/Memory ESP8266.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
docs/SPIFFS ESP32.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
docs/SPIFFS ESP8266.png
Normal file
After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 47 KiB |
BIN
docs/ui_graph.png
Normal file
After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 21 KiB |
BIN
docs/ui_number.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/ui_select1.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
docs/ui_select2.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
docs/ui_slider.png
Normal file
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 11 KiB |
BIN
docs/ui_tabs.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
docs/ui_text.png
Normal file
After Width: | Height: | Size: 21 KiB |
262
examples/gui-generic-api/gui-generic-api.ino
Normal file
@ -0,0 +1,262 @@
|
||||
#include <DNSServer.h>
|
||||
#include <ESPUI.h>
|
||||
|
||||
const byte DNS_PORT = 53;
|
||||
IPAddress apIP(192, 168, 1, 1);
|
||||
DNSServer dnsServer;
|
||||
|
||||
#if defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#endif
|
||||
|
||||
const char *ssid = "ESPUI";
|
||||
const char *password = "espui";
|
||||
const char *hostname = "espui";
|
||||
|
||||
uint16_t status;
|
||||
uint16_t button1;
|
||||
uint16_t millisLabelId;
|
||||
uint16_t switchOne;
|
||||
|
||||
void numberCall( Control* sender, int type ) {
|
||||
Serial.println( sender->value );
|
||||
}
|
||||
|
||||
void textCall(Control *sender, int type) {
|
||||
Serial.print("Text: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println(sender->value);
|
||||
}
|
||||
|
||||
void slider(Control *sender, int type) {
|
||||
Serial.print("Slider: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println(sender->value);
|
||||
}
|
||||
|
||||
void buttonCallback(Control *sender, int type) {
|
||||
switch (type) {
|
||||
case B_DOWN:
|
||||
Serial.println("Button DOWN");
|
||||
break;
|
||||
|
||||
case B_UP:
|
||||
Serial.println("Button UP");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void buttonExample(Control *sender, int type) {
|
||||
switch (type) {
|
||||
case B_DOWN:
|
||||
Serial.println("Status: Start");
|
||||
ESPUI.updateControlValue(status, "Start");
|
||||
|
||||
ESPUI.getControl(button1)->color = ControlColor::Carrot;
|
||||
ESPUI.updateControl(button1);
|
||||
break;
|
||||
|
||||
case B_UP:
|
||||
Serial.println("Status: Stop");
|
||||
ESPUI.updateControlValue(status, "Stop");
|
||||
|
||||
ESPUI.getControl(button1)->color = ControlColor::Peterriver;
|
||||
ESPUI.updateControl(button1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void padExample(Control *sender, int value) {
|
||||
switch (value) {
|
||||
case P_LEFT_DOWN:
|
||||
Serial.print("left down");
|
||||
break;
|
||||
|
||||
case P_LEFT_UP:
|
||||
Serial.print("left up");
|
||||
break;
|
||||
|
||||
case P_RIGHT_DOWN:
|
||||
Serial.print("right down");
|
||||
break;
|
||||
|
||||
case P_RIGHT_UP:
|
||||
Serial.print("right up");
|
||||
break;
|
||||
|
||||
case P_FOR_DOWN:
|
||||
Serial.print("for down");
|
||||
break;
|
||||
|
||||
case P_FOR_UP:
|
||||
Serial.print("for up");
|
||||
break;
|
||||
|
||||
case P_BACK_DOWN:
|
||||
Serial.print("back down");
|
||||
break;
|
||||
|
||||
case P_BACK_UP:
|
||||
Serial.print("back up");
|
||||
break;
|
||||
|
||||
case P_CENTER_DOWN:
|
||||
Serial.print("center down");
|
||||
break;
|
||||
|
||||
case P_CENTER_UP:
|
||||
Serial.print("center up");
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.println(sender->id);
|
||||
}
|
||||
|
||||
void switchExample(Control *sender, int value) {
|
||||
switch (value) {
|
||||
case S_ACTIVE:
|
||||
Serial.print("Active:");
|
||||
break;
|
||||
|
||||
case S_INACTIVE:
|
||||
Serial.print("Inactive");
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.println(sender->id);
|
||||
}
|
||||
|
||||
void selectExample(Control *sender, int value) {
|
||||
Serial.print("Select: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println(sender->value);
|
||||
}
|
||||
|
||||
void otherSwitchExample(Control *sender, int value) {
|
||||
switch (value) {
|
||||
case S_ACTIVE:
|
||||
Serial.print("Active:");
|
||||
break;
|
||||
|
||||
case S_INACTIVE:
|
||||
Serial.print("Inactive");
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.println(sender->id);
|
||||
}
|
||||
|
||||
void setup(void) {
|
||||
ESPUI.setVerbosity(Verbosity::VerboseJSON);
|
||||
Serial.begin(115200);
|
||||
|
||||
#if defined(ESP32)
|
||||
WiFi.setHostname(hostname);
|
||||
#else
|
||||
WiFi.hostname(hostname);
|
||||
#endif
|
||||
|
||||
// try to connect to existing network
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.print("\n\nTry to connect to existing network");
|
||||
|
||||
{
|
||||
uint8_t timeout = 10;
|
||||
|
||||
// Wait for connection, 5s timeout
|
||||
do {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
timeout--;
|
||||
} while (timeout && WiFi.status() != WL_CONNECTED);
|
||||
|
||||
// not connected -> create hotspot
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print("\n\nCreating hotspot");
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
|
||||
WiFi.softAP(ssid);
|
||||
|
||||
timeout = 5;
|
||||
|
||||
do {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
timeout--;
|
||||
} while (timeout);
|
||||
}
|
||||
}
|
||||
|
||||
dnsServer.start(DNS_PORT, "*", apIP);
|
||||
|
||||
Serial.println("\n\nWiFi parameters:");
|
||||
Serial.print("Mode: ");
|
||||
Serial.println(WiFi.getMode() == WIFI_AP ? "Station" : "Client");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.getMode() == WIFI_AP ? WiFi.softAPIP() : WiFi.localIP());
|
||||
|
||||
status = ESPUI.addControl(ControlType::Label, "Status:", "Stop", ControlColor::Turquoise);
|
||||
|
||||
uint16_t select1 = ESPUI.addControl(ControlType::Select, "Select:", "", ControlColor::Alizarin, Control::noParent, &selectExample);
|
||||
|
||||
ESPUI.addControl(ControlType::Option, "Option1", "Opt1", ControlColor::Alizarin, select1);
|
||||
ESPUI.addControl(ControlType::Option, "Option2", "Opt2", ControlColor::Alizarin, select1);
|
||||
ESPUI.addControl(ControlType::Option, "Option3", "Opt3", ControlColor::Alizarin, select1);
|
||||
|
||||
ESPUI.addControl(ControlType::Text, "Text Test:", "a Text Field", ControlColor::Alizarin, Control::noParent, &textCall);
|
||||
|
||||
millisLabelId = ESPUI.addControl(ControlType::Label, "Millis:", "0", ControlColor::Emerald, Control::noParent);
|
||||
button1 = ESPUI.addControl(ControlType::Button, "Push Button", "Press", ControlColor::Peterriver, Control::noParent, &buttonCallback);
|
||||
ESPUI.addControl(ControlType::Button, "Other Button", "Press", ControlColor::Wetasphalt, Control::noParent, &buttonExample);
|
||||
ESPUI.addControl(ControlType::PadWithCenter, "Pad with center", "", ControlColor::Sunflower, Control::noParent, &padExample);
|
||||
ESPUI.addControl(ControlType::Pad, "Pad without center", "", ControlColor::Carrot, Control::noParent, &padExample);
|
||||
switchOne = ESPUI.addControl(ControlType::Switcher, "Switch one", "", ControlColor::Alizarin, Control::noParent, &switchExample);
|
||||
ESPUI.addControl(ControlType::Switcher, "Switch two", "", ControlColor::None, Control::noParent, &otherSwitchExample);
|
||||
ESPUI.addControl(ControlType::Slider, "Slider one", "30", ControlColor::Alizarin, Control::noParent, &slider);
|
||||
ESPUI.addControl(ControlType::Slider, "Slider two", "100", ControlColor::Alizarin, Control::noParent, &slider);
|
||||
ESPUI.addControl(ControlType::Number, "Number:", "50", ControlColor::Alizarin, Control::noParent, &numberCall);
|
||||
|
||||
/*
|
||||
* .begin loads and serves all files from PROGMEM directly.
|
||||
* If you want to serve the files from SPIFFS use ESPUI.beginSPIFFS
|
||||
* (.prepareFileSystem has to be run in an empty sketch before)
|
||||
*/
|
||||
|
||||
// Enable this option if you want sliders to be continuous (update during move) and not discrete (update on stop)
|
||||
// ESPUI.sliderContinuous = true;
|
||||
|
||||
/*
|
||||
* Optionally you can use HTTP BasicAuth. Keep in mind that this is NOT a
|
||||
* SECURE way of limiting access.
|
||||
* Anyone who is able to sniff traffic will be able to intercept your password
|
||||
* since it is transmitted in cleartext. Just add a string as username and
|
||||
* password, for example begin("ESPUI Control", "username", "password")
|
||||
*/
|
||||
|
||||
|
||||
ESPUI.begin("ESPUI Control");
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
dnsServer.processNextRequest();
|
||||
|
||||
static long oldTime = 0;
|
||||
static bool testSwitchState = false;
|
||||
|
||||
if (millis() - oldTime > 5000) {
|
||||
ESPUI.updateControlValue(millisLabelId, String(millis()));
|
||||
testSwitchState = !testSwitchState;
|
||||
ESPUI.updateControlValue(switchOne, testSwitchState ? "1" : "0");
|
||||
|
||||
oldTime = millis();
|
||||
}
|
||||
}
|
1
examples/gui/data/css/normalize.min.css
vendored
@ -1 +0,0 @@
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
@ -1,765 +0,0 @@
|
||||
.container {
|
||||
position: relative;
|
||||
width: 79%;
|
||||
margin: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.column, .columns {
|
||||
width: 100%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-top: 2%;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 4px rgba(204, 197, 185, 0.5);
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
min-width: 150px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card-slider {
|
||||
padding-bottom: 10px
|
||||
}
|
||||
|
||||
.turquoise {
|
||||
background: #1abc9c;
|
||||
border-bottom: #16a085 3px solid;
|
||||
}
|
||||
|
||||
.emerald {
|
||||
background: #2ecc71;
|
||||
border-bottom: #27ae60 3px solid;
|
||||
}
|
||||
|
||||
.peterriver {
|
||||
background: #3498db;
|
||||
border-bottom: #2980b9 3px solid;
|
||||
}
|
||||
|
||||
.wetasphalt {
|
||||
background: #34495e;
|
||||
border-bottom: #2c3e50 3px solid;
|
||||
}
|
||||
|
||||
.sunflower {
|
||||
background: #f1c40f;
|
||||
border-bottom: #E6BB0F 3px solid;
|
||||
}
|
||||
|
||||
.carrot {
|
||||
background: #e67e22;
|
||||
border-bottom: #d35400 3px solid;
|
||||
}
|
||||
|
||||
.alizarin {
|
||||
background: #e74c3c;
|
||||
border-bottom: #c0392b 3px solid;
|
||||
}
|
||||
|
||||
.label {
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
border-radius: 0.2em;
|
||||
padding: 0.12em 0.4em 0.14em;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
margin-bottom: 5px;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
position: relative;
|
||||
top: -0.15em;
|
||||
background-color: #999999;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.label.color-blue {
|
||||
background-color: #6f9ad1;
|
||||
}
|
||||
|
||||
.label.color-red {
|
||||
background-color: #d37c7c;
|
||||
}
|
||||
|
||||
.label.color-green {
|
||||
background-color: #9bc268;
|
||||
}
|
||||
|
||||
.label.color-orange {
|
||||
background-color: #dea154;
|
||||
}
|
||||
|
||||
.label.color-yellow {
|
||||
background-color: #e9d641;
|
||||
}
|
||||
|
||||
.label.color-purple {
|
||||
background-color: #9f83d1;
|
||||
}
|
||||
|
||||
/* For devices larger than 400px */
|
||||
|
||||
@media (min-width: 400px) {
|
||||
.container {
|
||||
width: 84%;
|
||||
}
|
||||
}
|
||||
|
||||
/* For devices larger than 550px */
|
||||
|
||||
@media (min-width: 630px) {
|
||||
.container {
|
||||
width: 98%;
|
||||
}
|
||||
.column, .columns {
|
||||
margin-right: 2%;
|
||||
}
|
||||
.column:first-child, .columns:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
.one.column, .one.columns {
|
||||
width: 4.66666666667%;
|
||||
}
|
||||
.two.columns {
|
||||
width: 13.3333333333%;
|
||||
}
|
||||
.three.columns {
|
||||
width: 22%;
|
||||
}
|
||||
.four.columns {
|
||||
width: 30.6666666667%;
|
||||
}
|
||||
.five.columns {
|
||||
width: 39.3333333333%;
|
||||
}
|
||||
.six.columns {
|
||||
width: 48%;
|
||||
}
|
||||
.seven.columns {
|
||||
width: 56.6666666667%;
|
||||
}
|
||||
.eight.columns {
|
||||
width: 65.3333333333%;
|
||||
}
|
||||
.nine.columns {
|
||||
width: 74.0%;
|
||||
}
|
||||
.ten.columns {
|
||||
width: 82.6666666667%;
|
||||
}
|
||||
.eleven.columns {
|
||||
width: 91.3333333333%;
|
||||
}
|
||||
.twelve.columns {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
.one-third.column {
|
||||
width: 30.6666666667%;
|
||||
}
|
||||
.two-thirds.column {
|
||||
width: 65.3333333333%;
|
||||
}
|
||||
.one-half.column {
|
||||
width: 48%;
|
||||
}
|
||||
/* Offsets */
|
||||
.offset-by-one.column, .offset-by-one.columns {
|
||||
margin-left: 8.66666666667%;
|
||||
}
|
||||
.offset-by-two.column, .offset-by-two.columns {
|
||||
margin-left: 17.3333333333%;
|
||||
}
|
||||
.offset-by-three.column, .offset-by-three.columns {
|
||||
margin-left: 26%;
|
||||
}
|
||||
.offset-by-four.column, .offset-by-four.columns {
|
||||
margin-left: 34.6666666667%;
|
||||
}
|
||||
.offset-by-five.column, .offset-by-five.columns {
|
||||
margin-left: 43.3333333333%;
|
||||
}
|
||||
.offset-by-six.column, .offset-by-six.columns {
|
||||
margin-left: 52%;
|
||||
}
|
||||
.offset-by-seven.column, .offset-by-seven.columns {
|
||||
margin-left: 60.6666666667%;
|
||||
}
|
||||
.offset-by-eight.column, .offset-by-eight.columns {
|
||||
margin-left: 69.3333333333%;
|
||||
}
|
||||
.offset-by-nine.column, .offset-by-nine.columns {
|
||||
margin-left: 78.0%;
|
||||
}
|
||||
.offset-by-ten.column, .offset-by-ten.columns {
|
||||
margin-left: 86.6666666667%;
|
||||
}
|
||||
.offset-by-eleven.column, .offset-by-eleven.columns {
|
||||
margin-left: 95.3333333333%;
|
||||
}
|
||||
.offset-by-one-third.column, .offset-by-one-third.columns {
|
||||
margin-left: 34.6666666667%;
|
||||
}
|
||||
.offset-by-two-thirds.column, .offset-by-two-thirds.columns {
|
||||
margin-left: 69.3333333333%;
|
||||
}
|
||||
.offset-by-one-half.column, .offset-by-one-half.columns {
|
||||
margin-left: 52%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Base Styles
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-size: 1.5em;
|
||||
line-height: 1.0;
|
||||
font-weight: 400;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
color: #222;
|
||||
background-color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Typography
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4.0rem;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -.1rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 3.6rem;
|
||||
line-height: 1.25;
|
||||
letter-spacing: -.1rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 3.0rem;
|
||||
line-height: 1.3;
|
||||
letter-spacing: -.1rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 2.4rem;
|
||||
line-height: 1.35;
|
||||
letter-spacing: -.08rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.8rem;
|
||||
line-height: 1.5;
|
||||
letter-spacing: -.05rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.6;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
/* Larger than phablet */
|
||||
|
||||
@media (min-width: 630px) {
|
||||
h1 {
|
||||
font-size: 5.0rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 4.2rem;
|
||||
}
|
||||
h3 {
|
||||
font-size: 3.6rem;
|
||||
}
|
||||
h4 {
|
||||
font-size: 3.0rem;
|
||||
}
|
||||
h5 {
|
||||
font-size: 2.0rem;
|
||||
}
|
||||
h6 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Links
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
a {
|
||||
color: #1EAEDB;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0FA0CE;
|
||||
}
|
||||
|
||||
/* Buttons
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
button {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Main Head Part
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
#mainHeader {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#conStatus {
|
||||
position: inherit;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
/* Spacing
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
button, .button {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Utilities
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
.u-full-width {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.u-max-full-width {
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.u-pull-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.u-pull-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.tcenter {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Misc
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
hr {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 1.2rem;
|
||||
border-width: 0;
|
||||
border-top: 1px solid #E1E1E1;
|
||||
}
|
||||
|
||||
/* Clearing
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
/* Self Clearing Goodness */
|
||||
|
||||
.container:after, .row:after, .u-cf {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* ButtonPad
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
.control {
|
||||
background-color: #ddd;
|
||||
background-image: linear-gradient(hsla(0, 0%, 0%, .1), hsla(0, 0%, 100%, .1));
|
||||
border-radius: 50%;
|
||||
box-shadow: inset 0 1px 1px 1px hsla(0, 0%, 100%, .5), 0 0 1px 1px hsla(0, 0%, 100%, .75), 0 0 1px 2px hsla(0, 0%, 100%, .25), 0 0 1px 3px hsla(0, 0%, 100%, .25), 0 0 1px 4px hsla(0, 0%, 100%, .25), 0 0 1px 6px hsla(0, 0%, 0%, .75);
|
||||
height: 9em;
|
||||
margin: 3em auto;
|
||||
position: relative;
|
||||
width: 9em;
|
||||
}
|
||||
|
||||
.control ul {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.control li {
|
||||
border-radius: 100% 0 0 0;
|
||||
box-shadow: inset -1px -1px 1px hsla(0, 0%, 100%, .5), 0 0 1px hsla(0, 0%, 0%, .75);
|
||||
display: inline-block;
|
||||
height: 50%;
|
||||
overflow: hidden;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.control ul li:nth-child(2) {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.control ul li:nth-child(3) {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.control ul li:nth-child(4) {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.control ul a {
|
||||
height: 200%;
|
||||
position: relative;
|
||||
transform: rotate(-45deg);
|
||||
width: 200%;
|
||||
}
|
||||
|
||||
.control a:hover, .control a:focus {
|
||||
background-color: hsla(0, 0%, 100%, .25);
|
||||
}
|
||||
|
||||
.control a {
|
||||
border-radius: 50%;
|
||||
color: #333;
|
||||
display: block;
|
||||
font: bold 1em/3 sans-serif;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px 1px hsla(0, 0%, 100%, .4);
|
||||
transition: .15s;
|
||||
}
|
||||
|
||||
.control .confirm {
|
||||
background-color: #ddd;
|
||||
background-image: linear-gradient(hsla(0, 0%, 0%, .15), hsla(0, 0%, 100%, .25));
|
||||
box-shadow: inset 0 1px 1px 1px hsla(0, 0%, 100%, .5), 0 0 1px 1px hsla(0, 0%, 100%, .25), 0 0 1px 2px hsla(0, 0%, 100%, .25), 0 0 1px 3px hsla(0, 0%, 100%, .25), 0 0 1px 4px hsla(0, 0%, 100%, .25), 0 0 1px 6px hsla(0, 0%, 0%, .85);
|
||||
left: 50%;
|
||||
line-height: 3;
|
||||
margin: -1.5em;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 3em;
|
||||
}
|
||||
|
||||
.control .confirm:hover, .control .confirm:focus {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
/* Switch
|
||||
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||
|
||||
.switch {
|
||||
display: inline-block !important;
|
||||
background-color: #bebebe;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
height: 26px;
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
width: 60px;
|
||||
-webkit-transition: background-color 0.2s ease-in-out;
|
||||
-moz-transition: background-color 0.2s ease-in-out;
|
||||
-o-transition: background-color 0.2s ease-in-out;
|
||||
-ms-transition: background-color 0.2s ease-in-out;
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.switch.checked {
|
||||
background-color: #76d21d;
|
||||
}
|
||||
|
||||
.switch input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
height: 10px;
|
||||
left: 12px;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
-webkit-transition: left 0.05s ease-in-out;
|
||||
-moz-transition: left 0.05s ease-in-out;
|
||||
-o-transition: left 0.05s ease-in-out;
|
||||
-ms-transition: left 0.05s ease-in-out;
|
||||
transition: left 0.05s ease-in-out;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.switch.checked input[type="checkbox"] {
|
||||
left: 38px;
|
||||
}
|
||||
|
||||
.switch input:before {
|
||||
background: #fff;
|
||||
background: -moz-linear-gradient(top, #fff 0%, #f0f0f0 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #f0f0f0));
|
||||
background: -webkit-linear-gradient(top, #fff 0%, #f0f0f0 100%);
|
||||
background: -o-linear-gradient(top, #fff 0%, #f0f0f0 100%);
|
||||
background: -ms-linear-gradient(top, #fff 0%, #f0f0f0 100%);
|
||||
background: linear-gradient(to bottom, #fff 0%, #f0f0f0 100%);
|
||||
border: 1px solid #fff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
|
||||
content: '';
|
||||
height: 18px;
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
left: -9px;
|
||||
width: 26px;
|
||||
}
|
||||
|
||||
.switch input:after {
|
||||
background: #f0f0f0;
|
||||
background: -moz-linear-gradient(top, #f0f0f0 0%, #fff 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f0f0f0), color-stop(100%, #fff));
|
||||
background: -webkit-linear-gradient(top, #f0f0f0 0%, #fff 100%);
|
||||
background: -o-linear-gradient(top, #f0f0f0 0%, #fff 100%);
|
||||
background: -ms-linear-gradient(top, #f0f0f0 0%, #fff 100%);
|
||||
background: linear-gradient(to bottom, #f0f0f0 0%, #fff 100%);
|
||||
border-radius: 10px;
|
||||
content: '';
|
||||
height: 12px;
|
||||
margin: -1px 0 0 -1px;
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.switch .icon-ok, .switch .icon-remove {
|
||||
line-height: 28px;
|
||||
text-shadow: 0 -2px 0 rgba(0, 0, 0, 0.2);
|
||||
margin: 0 9px;
|
||||
}
|
||||
|
||||
.switch .icon-ok {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.switch .icon-remove {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Material Design Range Slider - by Ravikumar Chauhan
|
||||
------------------------------------------------------------------------- */
|
||||
.rkmd-slider {
|
||||
display: block;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
.rkmd-slider input[type="range"] {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
opacity: 0;
|
||||
}
|
||||
.rkmd-slider input[type="range"] + .slider {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background-color: #bebebe;
|
||||
}
|
||||
.rkmd-slider input[type="range"] + .slider .slider-fill {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
z-index: 1;
|
||||
}
|
||||
.rkmd-slider input[type="range"] + .slider .slider-handle {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: -5.5px;
|
||||
left: 0%;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-left: -8px;
|
||||
border-radius: 50%;
|
||||
transition: all .2s ease;
|
||||
user-select: none;
|
||||
z-index: 2;
|
||||
}
|
||||
.rkmd-slider input[type="range"]:disabled + .slider {
|
||||
background-color: #b0b0b0 !important;
|
||||
}
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-fill,
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-handle {
|
||||
cursor: default !important;
|
||||
background-color: #b0b0b0 !important;
|
||||
}
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-fill .slider-label,
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-handle .slider-label {
|
||||
display: none;
|
||||
background-color: #b0b0b0 !important;
|
||||
}
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-fill.is-active,
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-handle.is-active {
|
||||
top: -5.5px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-left: -8px;
|
||||
}
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-fill.is-active .slider-label,
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-handle.is-active .slider-label {
|
||||
display: none;
|
||||
border-radius: 50%;
|
||||
transform: none;
|
||||
}
|
||||
.rkmd-slider input[type="range"]:disabled + .slider .slider-handle:active {
|
||||
box-shadow: none !important;
|
||||
transform: scale(1) !important;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Discrete Range Slider - by Ravikumar Chauhan
|
||||
------------------------------------------------------------------------- */
|
||||
.rkmd-slider.slider-discrete .slider .slider-handle {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete .slider .slider-handle .slider-label {
|
||||
position: absolute;
|
||||
top: -17.5px;
|
||||
left: -2px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
-webkit-transform-origin: 50% 100%;
|
||||
transform-origin: 50% 100%;
|
||||
border-radius: 50%;
|
||||
-webkit-transform: scale(0.5) rotate(-45deg);
|
||||
transform: scale(0.5) rotate(-45deg);
|
||||
-webkit-transition: all .2s ease;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete .slider .slider-handle .slider-label span {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
opacity: 0;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete .slider .slider-handle.is-active {
|
||||
top: 0px;
|
||||
margin-left: -2px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
.rkmd-slider.slider-discrete .slider .slider-handle.is-active .slider-label {
|
||||
top: -15px;
|
||||
left: -2px;
|
||||
border-radius: 15px 15px 15px 0;
|
||||
-webkit-transform: rotate(-45deg) translate(23px, -25px);
|
||||
transform: rotate(-45deg) translate(23px, -25px);
|
||||
}
|
||||
.rkmd-slider.slider-discrete .slider .slider-handle.is-active .slider-label span {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.rkmd-slider.slider-discrete.slider-turquoise .slider-label {
|
||||
background-color: #16a085;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete.slider-emerald .slider-label {
|
||||
background-color: #27ae60;
|
||||
}
|
||||
|
||||
.peterriver {
|
||||
background: #3498db;
|
||||
border-bottom: #2980b9 3px solid;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete.slider-peterriver .slider-label {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
.wetasphalt {
|
||||
background: #34495e;
|
||||
border-bottom: #2c3e50 3px solid;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete.slider-wetasphalt .slider-label {
|
||||
background-color: #2c3e50;
|
||||
}
|
||||
|
||||
.sunflower {
|
||||
background: #f1c40f;
|
||||
border-bottom: #E6BB0F 3px solid;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete.slider-sunflower .slider-label {
|
||||
background-color: #E6BB0F;
|
||||
}
|
||||
|
||||
.carrot {
|
||||
background: #e67e22;
|
||||
border-bottom: #d35400 3px solid;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete.slider-carrot .slider-label {
|
||||
background-color: #d35400;
|
||||
}
|
||||
|
||||
.alizarin {
|
||||
background: #e74c3c;
|
||||
border-bottom: #c0392b 3px solid;
|
||||
}
|
||||
|
||||
.rkmd-slider.slider-discrete.slider-alizarin .slider-label {
|
||||
background-color: #c0392b;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
.rkmd-slider.slider-light input[type="range"] + .slider {
|
||||
background-color: #5c5c5c;
|
||||
}
|
||||
.rkmd-slider.slider-light input[type="range"]:disabled + .slider {
|
||||
background-color: #5c5c5c !important;
|
||||
}
|
||||
.rkmd-slider.slider-light input[type="range"]:disabled + .slider .slider-fill,
|
||||
.rkmd-slider.slider-light input[type="range"]:disabled + .slider .slider-handle {
|
||||
background-color: #5c5c5c !important;
|
||||
}
|
||||
|
||||
*/
|
1
examples/gui/data/css/style.min.css
vendored
@ -1,28 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Control</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAPFBMVEUAAACA1VWR21qQ2liR3FqR3FqS3VuR3VqR3VuR3VqO21mS21uS3FqS3FqS21uJ2GKQ21qR3FuR3FoAAAB/3Gu7AAAAEnRSTlMABoA3kPBwz8i5Kzioxg4NVcU3uEJHAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+EFEhcEM+HpYwQAAABYSURBVBjThY/JDsAgCESt4lpX/v9jLQZJ6qF9t3khAyj1xXUKbQ4BVowDwqOYgExkkW4iY6lPaF06RqM8YItOuRbMaz6xjbsusDAW/drplBg47jP696cXE8bPA1eUDeK2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA1LTE4VDIzOjA0OjUxKzAyOjAwxE59ewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNS0xOFQyMzowNDo1MSswMjowMLUTxccAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC"
|
||||
/>
|
||||
<link rel="stylesheet" href="/css/normalize.css">
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
|
||||
<script src="/js/zepto.js"></script>
|
||||
<script src="/js/slider.js"></script>
|
||||
<script src="/js/controls.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="javascript:start();">
|
||||
<div>
|
||||
<h4><div id="mainHeader">Control</div> <span id="conStatus" class="label">Offline</span></h4></div>
|
||||
<hr />
|
||||
<div class="container">
|
||||
<div id="row" class="row u-full-width">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
293
examples/gui/data/js/controls.js
vendored
@ -1,293 +0,0 @@
|
||||
const UI_TITEL = 0;
|
||||
const UI_LABEL = 1;
|
||||
const UI_BUTTON = 2;
|
||||
const UI_SWITCHER = 3;
|
||||
const UI_PAD = 4;
|
||||
const UI_CPAD = 5;
|
||||
const UPDATE_LABEL = 6;
|
||||
const UPDATE_SWITCHER = 7;
|
||||
const UI_SLIDER = 8;
|
||||
const UPDATE_SLIDER = 9;
|
||||
|
||||
const FOR = 0;
|
||||
const BACK = 1;
|
||||
const LEFT = 2;
|
||||
const RIGHT = 3;
|
||||
const CENTER = 4;
|
||||
|
||||
// Colors
|
||||
const C_TURQUOISE = 0;
|
||||
const C_EMERALD = 1;
|
||||
const C_PETERRIVER = 2;
|
||||
const C_WETASPHALT = 3;
|
||||
const C_SUNFLOWER = 4;
|
||||
const C_CARROT = 5;
|
||||
const C_ALIZARIN = 6;
|
||||
const C_NONE = 7;
|
||||
|
||||
function colorClass(colorId) {
|
||||
colorId = Number(colorId);
|
||||
switch (colorId) {
|
||||
case C_TURQUOISE:
|
||||
return "turquoise";
|
||||
break;
|
||||
|
||||
case C_EMERALD:
|
||||
return "emerald";
|
||||
break;
|
||||
|
||||
case C_PETERRIVER:
|
||||
return "peterriver";
|
||||
break;
|
||||
|
||||
case C_WETASPHALT:
|
||||
return "wetasphalt";
|
||||
break;
|
||||
|
||||
case C_SUNFLOWER:
|
||||
return "sunflower";
|
||||
break;
|
||||
|
||||
case C_CARROT:
|
||||
return "carrot"
|
||||
break;
|
||||
|
||||
case C_ALIZARIN:
|
||||
return "alizarin"
|
||||
break;
|
||||
|
||||
case C_NONE:
|
||||
return ""
|
||||
break;
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
var websock;
|
||||
|
||||
function start() {
|
||||
websock = new WebSocket('ws://' + window.location.hostname + '/ws');
|
||||
websock.onopen = function(evt) {
|
||||
console.log('websock open');
|
||||
$("#conStatus").addClass("color-green");
|
||||
$("#conStatus").text("Connected");
|
||||
};
|
||||
websock.onclose = function(evt) {
|
||||
console.log('websock close');
|
||||
$("#conStatus").removeClass("color-green");
|
||||
$("#conStatus").addClass("color-red");
|
||||
$("#conStatus").text("Error / No Connection");
|
||||
};
|
||||
websock.onerror = function(evt) {
|
||||
console.log(evt);
|
||||
$("#conStatus").removeClass("color-green");
|
||||
$("#conStatus").addClass("color-red");
|
||||
$("#conStatus").text("Error / No Connection");
|
||||
};
|
||||
websock.onmessage = function(evt) {
|
||||
console.log(evt);
|
||||
var data = JSON.parse(evt.data);
|
||||
var e = document.body;
|
||||
var center = "";
|
||||
switch (data.type) {
|
||||
case UI_TITEL:
|
||||
document.title = data.label;
|
||||
$('#mainHeader').html(data.label);
|
||||
break;
|
||||
case UI_LABEL:
|
||||
$('#row').append("<div class='two columns card tcenter " + colorClass(data.color) + "'><h5 id='" + data.id + "'>" + data.label + "</h5><hr /><span id='l" + data.id + "' class='label'>" + data.value + "</span></div>");
|
||||
break;
|
||||
case UI_BUTTON:
|
||||
$('#row').append("<div class='one columns card tcenter " + colorClass(data.color) + "'><h5>" + data.label + "</h5><hr/><button onmousedown='buttonclick(" + data.id + ", true)' onmouseup='buttonclick(" + data.id + ", false)' id='" + data.id + "'>" + data.value + "</button></div>");
|
||||
$('#' + data.id).on({
|
||||
'touchstart': function(e) {
|
||||
e.preventDefault();
|
||||
buttonclick(data.id, true)
|
||||
}
|
||||
});
|
||||
$('#' + data.id).on({
|
||||
'touchend': function(e) {
|
||||
e.preventDefault();
|
||||
buttonclick(data.id, false)
|
||||
}
|
||||
});
|
||||
break;
|
||||
case UI_SWITCHER:
|
||||
var label = "<label id='sl" + data.id + "' class='switch checked'>";
|
||||
var input = "<input type='checkbox' id='s" + data.id + "' onClick='switcher(" + data.id + ",null)' checked>";
|
||||
if (data.value == "0") {
|
||||
label = "<label id='sl" + data.id + "' class='switch'>";
|
||||
input = "<input type='checkbox' id='s" + data.id + "' onClick='switcher(" + data.id + ",null)' >";
|
||||
}
|
||||
$('#row').append(
|
||||
"<div id='" + data.id + "' class='one columns card tcenter " + colorClass(data.color) + "'><h5>" + data.label + "</h5><hr/>" +
|
||||
label + "<i class='icon-ok'></i>" +
|
||||
"<i class='icon-remove'></i>" + input +
|
||||
"</label>" +
|
||||
"</div>");
|
||||
break;
|
||||
case UI_CPAD:
|
||||
center = "<a class='confirm' onmousedown='padclick(CENTER, " + data.id + ", true)' onmouseup='padclick(CENTER, " + data.id + ", false)' href='#' id='pc" + data.id + "'>OK</a>";
|
||||
//NO BREAK
|
||||
case UI_PAD:
|
||||
$('#row').append(
|
||||
"<div class='two columns card tcenter " + colorClass(data.color) + "'><h5>" + data.label + "</h5><hr/>" +
|
||||
"<nav class='control'>" +
|
||||
"<ul>" +
|
||||
"<li><a onmousedown='padclick(FOR, " + data.id + ", true)' onmouseup='padclick(FOR, " + data.id + ", false)' href='#' id='pf" + data.id + "'>▲</a></li>" +
|
||||
"<li><a onmousedown='padclick(RIGHT, " + data.id + ", true)' onmouseup='padclick(RIGHT, " + data.id + ", false)' href='#' id='pr" + data.id + "'>▲</a></li>" +
|
||||
"<li><a onmousedown='padclick(LEFT, " + data.id + ", true)' onmouseup='padclick(LEFT, " + data.id + ", false)' href='#' id='pl" + data.id + "'>▲</a></li>" +
|
||||
"<li><a onmousedown='padclick(BACK, " + data.id + ", true)' onmouseup='padclick(BACK, " + data.id + ", false)' href='#' id='pb" + data.id + "'>▲</a></li>" +
|
||||
"</ul>" +
|
||||
center +
|
||||
"</nav>" +
|
||||
"</div>");
|
||||
|
||||
$('#pf' + data.id).on({
|
||||
'touchstart': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(FOR, data.id, true)
|
||||
}
|
||||
});
|
||||
$('#pf' + data.id).on({
|
||||
'touchend': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(FOR, data.id, false)
|
||||
}
|
||||
});
|
||||
$('#pl' + data.id).on({
|
||||
'touchstart': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(LEFT, data.id, true)
|
||||
}
|
||||
});
|
||||
$('#pl' + data.id).on({
|
||||
'touchend': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(LEFT, data.id, false)
|
||||
}
|
||||
});
|
||||
$('#pr' + data.id).on({
|
||||
'touchstart': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(RIGHT, data.id, true)
|
||||
}
|
||||
});
|
||||
$('#pr' + data.id).on({
|
||||
'touchend': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(RIGHT, data.id, false)
|
||||
}
|
||||
});
|
||||
$('#pb' + data.id).on({
|
||||
'touchstart': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(BACK, data.id, true)
|
||||
}
|
||||
});
|
||||
$('#pb' + data.id).on({
|
||||
'touchend': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(BACK, data.id, false)
|
||||
}
|
||||
});
|
||||
$('#pc' + data.id).on({
|
||||
'touchstart': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(CENTER, data.id, true)
|
||||
}
|
||||
});
|
||||
$('#pc' + data.id).on({
|
||||
'touchend': function(e) {
|
||||
e.preventDefault();
|
||||
padclick(CENTER, data.id, false)
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
case UPDATE_LABEL:
|
||||
$('#l' + data.id).html(data.value);
|
||||
break;
|
||||
case UPDATE_SWITCHER:
|
||||
if (data.value == "0")
|
||||
switcher(data.id, 0);
|
||||
else
|
||||
switcher(data.id, 1);
|
||||
break;
|
||||
case UI_SLIDER:
|
||||
$('#row').append(
|
||||
"<div class='two columns card tcenter card-slider " + colorClass(data.color) + "'>" +
|
||||
"<h5 id='" + data.id + "'>" + data.label + "</h5><hr />" +
|
||||
"<div id='sl" + data.id + "' class='rkmd-slider slider-discrete slider-" + colorClass(data.color) + "'>" +
|
||||
"<input type='range' min='0' max='100' value='" + data.value + "'>" +
|
||||
"</div>" +
|
||||
"</div>"
|
||||
);
|
||||
$('#row').append(
|
||||
"<script>" +
|
||||
"rkmd_rangeSlider('#sl" + data.id + "');" +
|
||||
"</script>"
|
||||
);
|
||||
break;
|
||||
|
||||
case UPDATE_SLIDER:
|
||||
slider_move($('#sl'+data.id), data.value ,'100', false);
|
||||
break;
|
||||
default:
|
||||
console.error('Unknown type or event');
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function buttonclick(number, isdown) {
|
||||
if (isdown) websock.send("bdown:" + number);
|
||||
else websock.send("bup:" + number);
|
||||
}
|
||||
|
||||
function padclick(type, number, isdown) {
|
||||
switch (type) {
|
||||
case CENTER:
|
||||
if (isdown) websock.send("pcdown:" + number);
|
||||
else websock.send("pcup:" + number);
|
||||
break;
|
||||
case FOR:
|
||||
if (isdown) websock.send("pfdown:" + number);
|
||||
else websock.send("pfup:" + number);
|
||||
break;
|
||||
case BACK:
|
||||
if (isdown) websock.send("pbdown:" + number);
|
||||
else websock.send("pbup:" + number);
|
||||
break;
|
||||
case LEFT:
|
||||
if (isdown) websock.send("pldown:" + number);
|
||||
else websock.send("plup:" + number);
|
||||
break;
|
||||
case RIGHT:
|
||||
if (isdown) websock.send("prdown:" + number);
|
||||
else websock.send("prup:" + number);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function switcher(number, state) {
|
||||
if (state == null) {
|
||||
if ($('#s' + number).is(':checked')) {
|
||||
websock.send("sactive:" + number);
|
||||
$('#sl' + number).addClass('checked');
|
||||
} else {
|
||||
websock.send("sinactive:" + number);
|
||||
$('#sl' + number).removeClass('checked');
|
||||
}
|
||||
} else if (state == 1) {
|
||||
$('#sl' + number).addClass('checked');
|
||||
$('#sl' + number).prop("checked", true);
|
||||
} else if (state == 0) {
|
||||
$('#sl' + number).removeClass('checked');
|
||||
$('#sl' + number).prop("checked", false);
|
||||
}
|
||||
}
|
1
examples/gui/data/js/controls.min.js
vendored
@ -1,125 +0,0 @@
|
||||
/* -----------------------------------------------------
|
||||
Material Design Sliders
|
||||
CodePen URL: https://codepen.io/rkchauhan/pen/xVGGpR
|
||||
By: Ravikumar Chauhan
|
||||
-------------------------------------------------------- */
|
||||
function rkmd_rangeSlider(selector) {
|
||||
var self, slider_width, slider_offset, curnt, sliderDiscrete, range, slider;
|
||||
self = $(selector);
|
||||
slider_width = self.width();
|
||||
slider_offset = self.offset().left;
|
||||
sliderDiscrete = self;
|
||||
|
||||
sliderDiscrete.each(function(i, v) {
|
||||
curnt = $(this);
|
||||
curnt.append(sliderDiscrete_tmplt());
|
||||
range = curnt.find('input[type="range"]');
|
||||
slider = curnt.find('.slider');
|
||||
slider_fill = slider.find('.slider-fill');
|
||||
slider_handle = slider.find('.slider-handle');
|
||||
slider_label = slider.find('.slider-label');
|
||||
|
||||
var range_val = parseInt(range.val());
|
||||
slider_fill.css('width', range_val + '%');
|
||||
slider_handle.css('left', range_val + '%');
|
||||
slider_label.find('span').text(range_val);
|
||||
});
|
||||
|
||||
self.on('mousedown touchstart', '.slider-handle', function(e) {
|
||||
if (e.button === 2) {
|
||||
return false;
|
||||
}
|
||||
var parents = $(this).parents('.rkmd-slider');
|
||||
var slider_width = parents.width();
|
||||
var slider_offset = parents.offset().left;
|
||||
var check_range = parents.find('input[type="range"]').is(':disabled');
|
||||
if (check_range === true) {
|
||||
return false;
|
||||
}
|
||||
$(this).addClass('is-active');
|
||||
var moveFu =
|
||||
function(e) {
|
||||
var slider_new_width = e.pageX - slider_offset;
|
||||
|
||||
if (slider_new_width <= slider_width && !(slider_new_width < '0')) {
|
||||
slider_move(parents, slider_new_width, slider_width, true);
|
||||
}
|
||||
};
|
||||
var upFu =
|
||||
function(e) {
|
||||
$(this).off(handlers);
|
||||
parents.find('.is-active').removeClass('is-active');
|
||||
};
|
||||
|
||||
var handlers = {
|
||||
mousemove: moveFu,
|
||||
touchmove: moveFu,
|
||||
mouseup: upFu,
|
||||
touchend: upFu
|
||||
};
|
||||
$(document).on(handlers);
|
||||
});
|
||||
|
||||
self.on('mousedown touchstart', '.slider', function(e) {
|
||||
if (e.button === 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var parents = $(this).parents('.rkmd-slider');
|
||||
var slider_width = parents.width();
|
||||
var slider_offset = parents.offset().left;
|
||||
var check_range = parents.find('input[type="range"]').is(':disabled');
|
||||
|
||||
if (check_range === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var slider_new_width = e.pageX - slider_offset;
|
||||
if (slider_new_width <= slider_width && !(slider_new_width < '0')) {
|
||||
slider_move(parents, slider_new_width, slider_width, true);
|
||||
}
|
||||
var upFu =
|
||||
function(e) {
|
||||
$(this).off(handlers);
|
||||
};
|
||||
|
||||
var handlers = {
|
||||
mouseup: upFu,
|
||||
touchend: upFu
|
||||
};
|
||||
$(document).on(handlers);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
function sliderDiscrete_tmplt() {
|
||||
var tmplt = '<div class="slider">' +
|
||||
'<div class="slider-fill"></div>' +
|
||||
'<div class="slider-handle"><div class="slider-label"><span>0</span></div></div>' +
|
||||
'</div>';
|
||||
|
||||
return tmplt;
|
||||
}
|
||||
|
||||
function slider_move(parents, newW, sliderW, send) {
|
||||
var slider_new_val = parseInt(Math.round(newW / sliderW * 100));
|
||||
|
||||
var slider_fill = parents.find('.slider-fill');
|
||||
var slider_handle = parents.find('.slider-handle');
|
||||
var range = parents.find('input[type="range"]');
|
||||
|
||||
slider_fill.css('width', slider_new_val + '%');
|
||||
slider_handle.css({
|
||||
'left': slider_new_val + '%',
|
||||
'transition': 'none',
|
||||
'-webkit-transition': 'none',
|
||||
'-moz-transition': 'none'
|
||||
});
|
||||
|
||||
range.val(slider_new_val);
|
||||
if (parents.find('.slider-handle span').text() != slider_new_val) {
|
||||
parents.find('.slider-handle span').text(slider_new_val);
|
||||
var number = parents.attr('id').substring(2);
|
||||
if (send) websock.send('slvalue:' + slider_new_val + ':' + number);
|
||||
}
|
||||
}
|
1
examples/gui/data/js/slider.min.js
vendored
@ -1 +0,0 @@
|
||||
function rkmd_rangeSlider(b){var f,e,c,a,g,d,h;f=$(b);e=f.width();c=f.offset().left;g=f;g.each(function(k,j){a=$(this);a.append(sliderDiscrete_tmplt());d=a.find('input[type="range"]');h=a.find(".slider");slider_fill=h.find(".slider-fill");slider_handle=h.find(".slider-handle");slider_label=h.find(".slider-label");var l=parseInt(d.val());slider_fill.css("width",l+"%");slider_handle.css("left",l+"%");slider_label.find("span").text(l)});f.on("mousedown touchstart",".slider-handle",function(o){if(o.button===2){return false}var m=$(this).parents(".rkmd-slider");var l=m.width();var i=m.offset().left;var k=m.find('input[type="range"]').is(":disabled");if(k===true){return false}$(this).addClass("is-active");var p=function(r){var q=r.pageX-i;if(q<=l&&!(q<"0")){slider_move(m,q,l,true)}};var n=function(q){$(this).off(j);m.find(".is-active").removeClass("is-active")};var j={mousemove:p,touchmove:p,mouseup:n,touchend:n};$(document).on(j)});f.on("mousedown touchstart",".slider",function(p){if(p.button===2){return false}var m=$(this).parents(".rkmd-slider");var l=m.width();var i=m.offset().left;var k=m.find('input[type="range"]').is(":disabled");if(k===true){return false}var o=p.pageX-i;if(o<=l&&!(o<"0")){slider_move(m,o,l,true)}var n=function(q){$(this).off(j)};var j={mouseup:n,touchend:n};$(document).on(j)})}function sliderDiscrete_tmplt(){var a='<div class="slider"><div class="slider-fill"></div><div class="slider-handle"><div class="slider-label"><span>0</span></div></div></div>';return a}function slider_move(g,a,h,e){var i=parseInt(Math.round(a/h*100));var b=g.find(".slider-fill");var c=g.find(".slider-handle");var f=g.find('input[type="range"]');b.css("width",i+"%");c.css({left:i+"%",transition:"none","-webkit-transition":"none","-moz-transition":"none"});f.val(i);if(g.find(".slider-handle span").text()!=i){g.find(".slider-handle span").text(i);var d=g.attr("id").substring(2);if(e){websock.send("slvalue:"+i+":"+d)}}};
|
@ -1,157 +1,248 @@
|
||||
#include <DNSServer.h>
|
||||
#include <ESPUI.h>
|
||||
|
||||
const byte DNS_PORT = 53;
|
||||
IPAddress apIP(192, 168, 1, 1);
|
||||
DNSServer dnsServer;
|
||||
|
||||
#if defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#endif
|
||||
|
||||
const char *ssid = "ESPUI";
|
||||
const char *password = "";
|
||||
const char *password = "espui";
|
||||
|
||||
long oldTime = 0;
|
||||
bool switchi = false;
|
||||
const char *hostname = "espui";
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(115200);
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
#if defined(ESP32)
|
||||
WiFi.setHostname(ssid);
|
||||
#else
|
||||
WiFi.hostname(ssid);
|
||||
#endif
|
||||
int statusLabelId;
|
||||
int graphId;
|
||||
int millisLabelId;
|
||||
int testSwitchId;
|
||||
|
||||
WiFi.softAP(ssid);
|
||||
// WiFi.softAP(ssid, password);
|
||||
Serial.println("");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.softAPIP());
|
||||
void numberCall(Control *sender, int type) { Serial.println(sender->value); }
|
||||
|
||||
// change the beginning to this if you want to join an existing network
|
||||
/*
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.println("");
|
||||
// Wait for connection
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
*/
|
||||
|
||||
ESPUI.label("Status:", COLOR_TURQUOISE, "Stop");
|
||||
ESPUI.label("Millis:", COLOR_EMERALD, "0");
|
||||
ESPUI.button("Push Button", &buttonCallback, COLOR_PETERRIVER);
|
||||
ESPUI.button("Other Button", &buttonExample, COLOR_WETASPHALT, "Press");
|
||||
ESPUI.pad("Pad with center", true, &padExample, COLOR_SUNFLOWER);
|
||||
ESPUI.pad("Pad without center", false, &padExample, COLOR_CARROT);
|
||||
ESPUI.switcher("Switch one", false, &switchExample, COLOR_ALIZARIN);
|
||||
ESPUI.switcher("Switch two", true, &otherSwitchExample, COLOR_NONE);
|
||||
ESPUI.slider("Slider one", &slider, COLOR_ALIZARIN, "30");
|
||||
ESPUI.slider("Slider two", &slider, COLOR_NONE, "100");
|
||||
|
||||
ESPUI.begin("ESP32 Control");
|
||||
void textCall(Control *sender, int type) {
|
||||
Serial.print("Text: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println(sender->value);
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
if (millis() - oldTime > 5000) {
|
||||
ESPUI.print("Millis:", String(millis()));
|
||||
switchi = !switchi;
|
||||
ESPUI.updateSwitcher("Switch one", switchi);
|
||||
oldTime = millis();
|
||||
}
|
||||
void slider(Control *sender, int type) {
|
||||
Serial.print("Slider: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println(sender->value);
|
||||
// Like all Control Values in ESPUI slider values are Strings. To use them as int simply do this:
|
||||
int sliderValueWithOffset = sender->value.toInt() + 100;
|
||||
Serial.print("SliderValue with offset");
|
||||
Serial.println(sliderValueWithOffset);
|
||||
}
|
||||
|
||||
void slider(Control sender, int type) {
|
||||
Serial.println(sender.value);
|
||||
}
|
||||
|
||||
void buttonCallback(Control sender, int type) {
|
||||
void buttonCallback(Control *sender, int type) {
|
||||
switch (type) {
|
||||
case B_DOWN:
|
||||
Serial.println("Button DOWN");
|
||||
break;
|
||||
|
||||
case B_UP:
|
||||
Serial.println("Button UP");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void buttonExample(Control sender, int type) {
|
||||
void buttonExample(Control *sender, int type) {
|
||||
switch (type) {
|
||||
case B_DOWN:
|
||||
Serial.println("Status: Start");
|
||||
ESPUI.print(0, "Status: Start");
|
||||
ESPUI.print(statusLabelId, "Start");
|
||||
break;
|
||||
|
||||
case B_UP:
|
||||
Serial.println("Status: Stop");
|
||||
ESPUI.print(0, "Status: Stop");
|
||||
ESPUI.print(statusLabelId, "Stop");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void padExample(Control sender, int value) {
|
||||
void padExample(Control *sender, int value) {
|
||||
switch (value) {
|
||||
case P_LEFT_DOWN:
|
||||
Serial.print("left down");
|
||||
break;
|
||||
|
||||
case P_LEFT_UP:
|
||||
Serial.print("left up");
|
||||
break;
|
||||
|
||||
case P_RIGHT_DOWN:
|
||||
Serial.print("right down");
|
||||
break;
|
||||
|
||||
case P_RIGHT_UP:
|
||||
Serial.print("right up");
|
||||
break;
|
||||
|
||||
case P_FOR_DOWN:
|
||||
Serial.print("for down");
|
||||
break;
|
||||
|
||||
case P_FOR_UP:
|
||||
Serial.print("for up");
|
||||
break;
|
||||
|
||||
case P_BACK_DOWN:
|
||||
Serial.print("back down");
|
||||
break;
|
||||
|
||||
case P_BACK_UP:
|
||||
Serial.print("back up");
|
||||
break;
|
||||
|
||||
case P_CENTER_DOWN:
|
||||
Serial.print("center down");
|
||||
break;
|
||||
|
||||
case P_CENTER_UP:
|
||||
Serial.print("center up");
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.println(sender.id);
|
||||
Serial.println(sender->id);
|
||||
}
|
||||
|
||||
void switchExample(Control sender, int value) {
|
||||
void switchExample(Control *sender, int value) {
|
||||
switch (value) {
|
||||
case S_ACTIVE:
|
||||
Serial.print("Active:");
|
||||
break;
|
||||
|
||||
case S_INACTIVE:
|
||||
Serial.print("Inactive");
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.println(sender.id);
|
||||
Serial.println(sender->id);
|
||||
}
|
||||
|
||||
void otherSwitchExample(Control sender, int value) {
|
||||
void otherSwitchExample(Control *sender, int value) {
|
||||
switch (value) {
|
||||
case S_ACTIVE:
|
||||
Serial.print("Active:");
|
||||
break;
|
||||
|
||||
case S_INACTIVE:
|
||||
Serial.print("Inactive");
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.println(sender.id);
|
||||
Serial.println(sender->id);
|
||||
}
|
||||
|
||||
void setup(void) {
|
||||
ESPUI.setVerbosity(Verbosity::VerboseJSON);
|
||||
Serial.begin(115200);
|
||||
|
||||
#if defined(ESP32)
|
||||
WiFi.setHostname(hostname);
|
||||
#else
|
||||
WiFi.hostname(hostname);
|
||||
#endif
|
||||
|
||||
// try to connect to existing network
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.print("\n\nTry to connect to existing network");
|
||||
|
||||
{
|
||||
uint8_t timeout = 10;
|
||||
|
||||
// Wait for connection, 5s timeout
|
||||
do {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
timeout--;
|
||||
} while (timeout && WiFi.status() != WL_CONNECTED);
|
||||
|
||||
// not connected -> create hotspot
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print("\n\nCreating hotspot");
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
|
||||
WiFi.softAP(ssid);
|
||||
|
||||
timeout = 5;
|
||||
|
||||
do {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
timeout--;
|
||||
} while (timeout);
|
||||
}
|
||||
}
|
||||
|
||||
dnsServer.start(DNS_PORT, "*", apIP);
|
||||
|
||||
Serial.println("\n\nWiFi parameters:");
|
||||
Serial.print("Mode: ");
|
||||
Serial.println(WiFi.getMode() == WIFI_AP ? "Station" : "Client");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.getMode() == WIFI_AP ? WiFi.softAPIP() : WiFi.localIP());
|
||||
|
||||
statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop");
|
||||
millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0");
|
||||
ESPUI.button("Push Button", &buttonCallback, ControlColor::Peterriver, "Press");
|
||||
ESPUI.button("Other Button", &buttonExample, ControlColor::Wetasphalt, "Press");
|
||||
ESPUI.padWithCenter("Pad with center", &padExample, ControlColor::Sunflower);
|
||||
ESPUI.pad("Pad without center", &padExample, ControlColor::Carrot);
|
||||
testSwitchId = ESPUI.switcher("Switch one", &switchExample, ControlColor::Alizarin, false);
|
||||
ESPUI.switcher("Switch two", &otherSwitchExample, ControlColor::None, true);
|
||||
ESPUI.slider("Slider one", &slider, ControlColor::Alizarin, 30);
|
||||
ESPUI.slider("Slider two", &slider, ControlColor::None, 100);
|
||||
ESPUI.text("Text Test:", &textCall, ControlColor::Alizarin, "a Text Field");
|
||||
ESPUI.number("Numbertest", &numberCall, ControlColor::Alizarin, 5, 0, 10);
|
||||
|
||||
graphId = ESPUI.graph("Graph Test", ControlColor::Wetasphalt);
|
||||
|
||||
/*
|
||||
* .begin loads and serves all files from PROGMEM directly.
|
||||
* If you want to serve the files from SPIFFS use ESPUI.beginSPIFFS
|
||||
* (.prepareFileSystem has to be run in an empty sketch before)
|
||||
*/
|
||||
|
||||
// Enable this option if you want sliders to be continuous (update during move) and not discrete (update on stop)
|
||||
// ESPUI.sliderContinuous = true;
|
||||
|
||||
/*
|
||||
* Optionally you can use HTTP BasicAuth. Keep in mind that this is NOT a
|
||||
* SECURE way of limiting access.
|
||||
* Anyone who is able to sniff traffic will be able to intercept your password
|
||||
* since it is transmitted in cleartext. Just add a string as username and
|
||||
* password, for example begin("ESPUI Control", "username", "password")
|
||||
*/
|
||||
|
||||
|
||||
ESPUI.begin("ESPUI Control");
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
dnsServer.processNextRequest();
|
||||
|
||||
static long oldTime = 0;
|
||||
static bool testSwitchState = false;
|
||||
|
||||
if (millis() - oldTime > 5000) {
|
||||
ESPUI.print(millisLabelId, String(millis()));
|
||||
|
||||
ESPUI.addGraphPoint(graphId, random(1, 50));
|
||||
|
||||
testSwitchState = !testSwitchState;
|
||||
ESPUI.updateSwitcher(testSwitchId, testSwitchState);
|
||||
|
||||
oldTime = millis();
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
#include <ESPUI.h>
|
||||
|
||||
void setup(void) {
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
ESPUI.prepareFileSystem();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
262
examples/tabbedGui/tabbedGui.ino
Normal file
@ -0,0 +1,262 @@
|
||||
#include <DNSServer.h>
|
||||
#include <ESPUI.h>
|
||||
|
||||
const byte DNS_PORT = 53;
|
||||
IPAddress apIP( 192, 168, 1, 1 );
|
||||
DNSServer dnsServer;
|
||||
|
||||
#if defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#endif
|
||||
|
||||
const char* ssid = "ESPUI";
|
||||
const char* password = "espui";
|
||||
const char* hostname = "espui";
|
||||
|
||||
uint16_t button1;
|
||||
uint16_t switchOne;
|
||||
uint16_t status;
|
||||
|
||||
void numberCall( Control* sender, int type ) {
|
||||
Serial.println( sender->value );
|
||||
}
|
||||
|
||||
void textCall( Control* sender, int type ) {
|
||||
Serial.print("Text: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println( sender->value );}
|
||||
|
||||
void slider( Control* sender, int type ) {
|
||||
Serial.print("Slider: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println( sender->value );}
|
||||
|
||||
void buttonCallback( Control* sender, int type ) {
|
||||
switch ( type ) {
|
||||
case B_DOWN:
|
||||
Serial.println( "Button DOWN" );
|
||||
break;
|
||||
|
||||
case B_UP:
|
||||
Serial.println( "Button UP" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void buttonExample( Control* sender, int type ) {
|
||||
switch ( type ) {
|
||||
case B_DOWN:
|
||||
Serial.println( "Status: Start" );
|
||||
ESPUI.updateControlValue( status, "Start" );
|
||||
|
||||
ESPUI.getControl( button1 )->color = ControlColor::Carrot;
|
||||
ESPUI.updateControl( button1 );
|
||||
break;
|
||||
|
||||
case B_UP:
|
||||
Serial.println( "Status: Stop" );
|
||||
ESPUI.updateControlValue( status, "Stop" );
|
||||
|
||||
ESPUI.getControl( button1 )->color = ControlColor::Peterriver;
|
||||
ESPUI.updateControl( button1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void padExample( Control* sender, int value ) {
|
||||
switch ( value ) {
|
||||
case P_LEFT_DOWN:
|
||||
Serial.print( "left down" );
|
||||
break;
|
||||
|
||||
case P_LEFT_UP:
|
||||
Serial.print( "left up" );
|
||||
break;
|
||||
|
||||
case P_RIGHT_DOWN:
|
||||
Serial.print( "right down" );
|
||||
break;
|
||||
|
||||
case P_RIGHT_UP:
|
||||
Serial.print( "right up" );
|
||||
break;
|
||||
|
||||
case P_FOR_DOWN:
|
||||
Serial.print( "for down" );
|
||||
break;
|
||||
|
||||
case P_FOR_UP:
|
||||
Serial.print( "for up" );
|
||||
break;
|
||||
|
||||
case P_BACK_DOWN:
|
||||
Serial.print( "back down" );
|
||||
break;
|
||||
|
||||
case P_BACK_UP:
|
||||
Serial.print( "back up" );
|
||||
break;
|
||||
|
||||
case P_CENTER_DOWN:
|
||||
Serial.print( "center down" );
|
||||
break;
|
||||
|
||||
case P_CENTER_UP:
|
||||
Serial.print( "center up" );
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print( " " );
|
||||
Serial.println( sender->id );
|
||||
}
|
||||
|
||||
void switchExample( Control* sender, int value ) {
|
||||
switch ( value ) {
|
||||
case S_ACTIVE:
|
||||
Serial.print( "Active:" );
|
||||
break;
|
||||
|
||||
case S_INACTIVE:
|
||||
Serial.print( "Inactive" );
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print( " " );
|
||||
Serial.println( sender->id );
|
||||
}
|
||||
|
||||
void selectExample( Control* sender, int value ) {
|
||||
Serial.print("Select: ID: ");
|
||||
Serial.print(sender->id);
|
||||
Serial.print(", Value: ");
|
||||
Serial.println( sender->value );
|
||||
}
|
||||
|
||||
void otherSwitchExample( Control* sender, int value ) {
|
||||
switch ( value ) {
|
||||
case S_ACTIVE:
|
||||
Serial.print( "Active:" );
|
||||
break;
|
||||
|
||||
case S_INACTIVE:
|
||||
Serial.print( "Inactive" );
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print( " " );
|
||||
Serial.println( sender->id );
|
||||
}
|
||||
|
||||
void setup( void ) {
|
||||
Serial.begin( 115200 );
|
||||
|
||||
#if defined(ESP32)
|
||||
WiFi.setHostname( hostname );
|
||||
#else
|
||||
WiFi.hostname( hostname );
|
||||
#endif
|
||||
|
||||
// try to connect to existing network
|
||||
WiFi.begin( ssid, password );
|
||||
Serial.print( "\n\nTry to connect to existing network" );
|
||||
|
||||
{
|
||||
uint8_t timeout = 10;
|
||||
|
||||
// Wait for connection, 5s timeout
|
||||
do {
|
||||
delay( 500 );
|
||||
Serial.print( "." );
|
||||
timeout--;
|
||||
} while ( timeout && WiFi.status() != WL_CONNECTED );
|
||||
|
||||
// not connected -> create hotspot
|
||||
if ( WiFi.status() != WL_CONNECTED ) {
|
||||
Serial.print( "\n\nCreating hotspot" );
|
||||
|
||||
WiFi.mode( WIFI_AP );
|
||||
WiFi.softAPConfig( apIP, apIP, IPAddress( 255, 255, 255, 0 ) );
|
||||
WiFi.softAP( ssid );
|
||||
|
||||
timeout = 5;
|
||||
|
||||
do {
|
||||
delay( 500 );
|
||||
Serial.print( "." );
|
||||
timeout--;
|
||||
} while ( timeout );
|
||||
}
|
||||
}
|
||||
|
||||
dnsServer.start( DNS_PORT, "*", apIP );
|
||||
|
||||
Serial.println( "\n\nWiFi parameters:" );
|
||||
Serial.print( "Mode: " );
|
||||
Serial.println( WiFi.getMode() == WIFI_AP ? "Station" : "Client" );
|
||||
Serial.print( "IP address: " );
|
||||
Serial.println( WiFi.getMode() == WIFI_AP ? WiFi.softAPIP() : WiFi.localIP() );
|
||||
|
||||
uint16_t tab1 = ESPUI.addControl( ControlType::Tab, "Settings 1", "Settings 1" );
|
||||
uint16_t tab2 = ESPUI.addControl( ControlType::Tab, "Settings 2", "Settings 2" );
|
||||
uint16_t tab3 = ESPUI.addControl( ControlType::Tab, "Settings 3", "Settings 3" );
|
||||
|
||||
// shown above all tabs
|
||||
status = ESPUI.addControl( ControlType::Label, "Status:", "Stop", ControlColor::Turquoise );
|
||||
|
||||
uint16_t select1 = ESPUI.addControl( ControlType::Select, "Select:", "", ControlColor::Alizarin, tab1, &selectExample );
|
||||
ESPUI.addControl( ControlType::Option, "Option1", "Opt1", ControlColor::Alizarin, select1 );
|
||||
ESPUI.addControl( ControlType::Option, "Option2", "Opt2", ControlColor::Alizarin, select1 );
|
||||
ESPUI.addControl( ControlType::Option, "Option3", "Opt3", ControlColor::Alizarin, select1 );
|
||||
|
||||
ESPUI.addControl( ControlType::Text, "Text Test:", "a Text Field", ControlColor::Alizarin, tab1, &textCall );
|
||||
|
||||
// tabbed controls
|
||||
ESPUI.addControl( ControlType::Label, "Millis:", "0", ControlColor::Emerald, tab1 );
|
||||
button1 = ESPUI.addControl( ControlType::Button, "Push Button", "Press", ControlColor::Peterriver, tab1, &buttonCallback );
|
||||
ESPUI.addControl( ControlType::Button, "Other Button", "Press", ControlColor::Wetasphalt, tab1, &buttonExample );
|
||||
ESPUI.addControl( ControlType::PadWithCenter, "Pad with center", "", ControlColor::Sunflower, tab2, &padExample );
|
||||
ESPUI.addControl( ControlType::Pad, "Pad without center", "", ControlColor::Carrot, tab3, &padExample );
|
||||
switchOne = ESPUI.addControl( ControlType::Switcher, "Switch one", "", ControlColor::Alizarin, tab3, &switchExample );
|
||||
ESPUI.addControl( ControlType::Switcher, "Switch two", "", ControlColor::None, tab3, &otherSwitchExample );
|
||||
ESPUI.addControl( ControlType::Slider, "Slider one", "30", ControlColor::Alizarin, tab1, &slider );
|
||||
ESPUI.addControl( ControlType::Slider, "Slider two", "100", ControlColor::Alizarin, tab3, &slider );
|
||||
ESPUI.addControl( ControlType::Number, "Number:", "50", ControlColor::Alizarin, tab3, &numberCall );
|
||||
|
||||
/*
|
||||
* .begin loads and serves all files from PROGMEM directly.
|
||||
* If you want to serve the files from SPIFFS use ESPUI.beginSPIFFS
|
||||
* (.prepareFileSystem has to be run in an empty sketch before)
|
||||
*/
|
||||
|
||||
// Enable this option if you want sliders to be continuous (update during move) and not discrete (update on stop)
|
||||
// ESPUI.sliderContinuous = true;
|
||||
|
||||
/*
|
||||
* Optionally you can use HTTP BasicAuth. Keep in mind that this is NOT a
|
||||
* SECURE way of limiting access.
|
||||
* Anyone who is able to sniff traffic will be able to intercept your password
|
||||
* since it is transmitted in cleartext. Just add a string as username and
|
||||
* password, for example begin("ESPUI Control", "username", "password")
|
||||
*/
|
||||
|
||||
|
||||
ESPUI.begin("ESPUI Control");
|
||||
}
|
||||
|
||||
void loop( void ) {
|
||||
dnsServer.processNextRequest();
|
||||
|
||||
static long oldTime = 0;
|
||||
static bool switchi = false;
|
||||
|
||||
if ( millis() - oldTime > 5000 ) {
|
||||
switchi = !switchi;
|
||||
ESPUI.updateControlValue( switchOne, switchi ? "1" : "0" );
|
||||
|
||||
oldTime = millis();
|
||||
}
|
||||
}
|
2
img/blocks/acknowledgements.html
Normal file
@ -0,0 +1,2 @@
|
||||
<div>Icons made by <a href="https://www.flaticon.com/authors/smashicons" title="Smashicons">Smashicons</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
|
||||
<div>Icons made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
|
54
img/blocks/button_pressed.svg
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 297 297" style="enable-background:new 0 0 297 297;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M252.07,167.87c-4.949-29.482-26.585-35.193-35.98-36.267c-6.673-8.979-16.33-13.892-27.432-13.892
|
||||
c-2.664,0-5.165,0.28-7.412,0.697c-6.587-7.587-15.832-11.686-26.139-11.686c-0.209,0-0.906,0.002-0.906,0.005v-9.013
|
||||
c15-9.416,24.883-25.934,24.883-44.716c0-29.225-23.635-53-52.859-53S73.066,23.775,73.066,53c0,18.65,10.135,35.069,24.135,44.518
|
||||
v43.873l-0.429-1.012c-5.388-8.765-13.937-13.786-23.688-13.787c-10.507-0.001-20.581,5.932-25.753,15.112
|
||||
c-4.941,8.77-4.662,18.985,0.701,28.089l62.342,119.392c2.486,4.759,7.382,7.815,12.751,7.815h87.757
|
||||
c7.578,0,13.879-6.025,14.343-13.59l2.04-33.263C249.032,216.644,256.227,192.64,252.07,167.87z M85.136,53
|
||||
c0-22.607,18.508-41,41.115-41s40.776,18.393,40.776,41c0,11.592-4.826,22.066-12.826,29.531V69.753
|
||||
c0-3.05-0.842-8.673-0.842-8.673c0.761-2.562,1.259-5.271,1.259-8.08c0-15.649-12.643-28.335-28.293-28.335
|
||||
c-15.648,0-28.313,12.686-28.313,28.335c0,2.568,0.364,5.053,1.005,7.419c-0.017,0.052-0.199,0.101-0.216,0.152
|
||||
c-0.909,2.859-1.599,5.939-1.599,9.182v12.484C90.201,74.793,85.136,64.438,85.136,53z M215.832,245.648
|
||||
c-0.228,0.345-0.364,0.747-0.39,1.16l-2.196,35.866c-0.076,1.25-1.112,2.325-2.365,2.325h-87.757c-0.883,0-1.692-0.591-2.1-1.373
|
||||
L58.539,163.986c-7.93-13.086,3.246-25.37,14.658-25.369c5.049,0,10.146,2.388,13.653,8.176l7.994,12.275
|
||||
c1.653,2.54,3.943,3.674,6.438,3.674c4.107,0,7.918-3.088,7.918-8.077V69.753c0-11.035,8.224-16.552,16.5-16.552
|
||||
c8.276,0,16.5,5.517,16.5,16.552v48.273c0,1.346,1.381,2.376,2.637,2.376c0.236,0,0.618-0.037,0.86-0.114
|
||||
c2.311-0.744,5.794-1.564,9.619-1.564c6.569,0,14.385,2.422,19.857,11.809c0.462,0.792,1.311,1.262,2.181,1.262
|
||||
c0.278,0,0.57-0.049,0.845-0.15c2.201-0.81,6.048-1.932,10.454-1.932c6.133,0,13.357,2.176,18.744,10.4
|
||||
c1.285,1.962,3.461,3.149,5.801,3.282c7.438,0.422,23.267,4.01,27.036,26.462C243.853,191.414,237.617,212.653,215.832,245.648z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
53
img/blocks/button_released.svg
Normal file
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 285.328 285.328" style="enable-background:new 0 0 285.328 285.328;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M230.71,155.764c-2.799-16.547-11.149-25.21-17.662-29.563c-6.352-4.246-12.953-5.882-18.102-6.433
|
||||
c-6.64-8.881-16.195-13.73-27.209-13.73c-2.417-0.001-4.878,0.231-7.351,0.69c-5.867-6.705-13.708-10.661-22.569-11.403
|
||||
c12.83-9.682,21.14-25.049,21.14-42.324c0-29.225-23.775-53-53-53s-53,23.775-53,53c0,18.704,9.748,35.163,24.421,44.599
|
||||
l0.017,13.992l0.041,33.745c-7.59,4.057-12.837,10.48-15.269,18.749c-3.746,12.739-0.76,29.147,9.13,50.16
|
||||
c6.509,13.827,14.322,25.924,18.062,31.44l1.658,22.07c0.74,9.854,9.061,17.572,18.942,17.572l78.646-0.097
|
||||
c9.489-0.012,17.576-7.115,18.812-16.523l3.054-23.263C229.043,216.331,235.851,186.165,230.71,155.764z M77.33,58.413L77.36,82.34
|
||||
C69.716,74.889,64.957,64.492,64.957,53c0-22.607,18.393-41,41-41c22.607,0,41,18.393,41,41c0,11.683-4.919,22.23-12.785,29.706
|
||||
l-0.029-24.361c-0.011-8.464-3.266-16.01-9.166-21.25c-5.172-4.593-12.005-7.123-19.238-7.123c-7.751,0-15.192,2.999-20.414,8.228
|
||||
C80.085,43.445,77.321,50.436,77.33,58.413z M199.797,239.861c-0.565,0.873-0.939,1.863-1.075,2.895l-3.202,24.389
|
||||
c-0.456,3.479-3.419,6.249-6.928,6.254l-78.623,0.265c-0.003,0-0.006,0-0.009,0c-3.66,0-6.702-2.989-6.976-6.64l-1.76-23.493
|
||||
c-0.093-1.235-0.509-2.46-1.211-3.48c-7.197-10.457-47.38-71.494-14.839-85.098c2.59-1.082,4.268-3.631,4.265-6.438
|
||||
c-0.021-16.613-0.086-71.755-0.109-90.112c-0.014-10.948,8.197-16.429,16.408-16.429c8.195,0,16.391,5.458,16.404,16.385
|
||||
l0.05,42.287c0.005,3.916,3.194,6.986,6.974,6.986c0.362,0,0.729-0.028,1.1-0.087c1.39-0.219,2.9-0.36,4.48-0.36
|
||||
c5.907,0,12.798,1.978,18.078,9.293c1.312,1.816,3.41,2.811,5.589,2.811c0.611,0,1.23-0.079,1.839-0.239
|
||||
c2.07-0.548,4.661-1.014,7.484-1.013c6.169,0,13.447,2.225,18.814,10.681c1.076,1.695,2.904,2.752,4.911,2.824
|
||||
c7.09,0.256,23.55,3.362,27.416,26.223C222.461,178.954,220.811,207.381,199.797,239.861z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
97
img/blocks/controller_center_pressed.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_center_pressed.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_center_released.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_center_released.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_down_pressed.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_down_pressed.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_down_released.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_down_released.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_left_pressed.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_left_pressed.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_left_released.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_left_released.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_right_pressed.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_right_pressed.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_right_released.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_right_released.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_up_pressed.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_up_pressed.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
97
img/blocks/controller_up_released.svg
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 480.00001 480.00001"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="controller_up_released.svg"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
width="480"
|
||||
height="480"><metadata
|
||||
id="metadata47"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs45" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview43"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.54742791"
|
||||
inkscape:cx="-10.370455"
|
||||
inkscape:cy="215.5535"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
units="px" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="m 232.419,191.328 c 2.418,2.548 5.663,3.951 9.134,3.951 3.471,0 6.716,-1.403 9.134,-3.951 l 52.122,-54.912 c 3.923,-4.133 6.881,-11.547 6.881,-17.245 V 17.893 c 0,-7.168 -5.832,-12.9999996 -13,-12.9999996 H 186.417 c -7.168,0 -13,5.8319996 -13,12.9999996 V 119.17 c 0,5.698 2.958,13.112 6.881,17.245 z m 9.135,-165.276 c 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.282,-36.369 36.369,-36.369 z"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 250.687,289.565 c -2.418,-2.548 -5.662,-3.95 -9.133,-3.95 -3.471,0 -6.715,1.402 -9.134,3.95 l -52.122,54.913 c -3.923,4.133 -6.881,11.547 -6.881,17.245 V 463 c 0,7.168 5.832,13 13,13 H 296.69 c 7.168,0 13,-5.832 13,-13 V 361.723 c 0,-5.698 -2.958,-13.112 -6.881,-17.245 z m -9.133,165.276 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 464.107,172.31001 H 362.83 c -5.699,0 -13.112,2.958 -17.244,6.881 l -54.914,52.122 c -2.548,2.418 -3.951,5.662 -3.951,9.134 0,3.472 1.403,6.716 3.951,9.135 l 54.913,52.12 c 4.132,3.924 11.546,6.882 17.245,6.882 h 101.277 c 7.168,0 13,-5.832 13,-13 v -110.274 c 0,-7.168 -5.832,-13 -13,-13 z m -44.528,104.506 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 0,20.086 -16.283,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8"
|
||||
d="m 196.386,240.44701 c 0,-3.472 -1.403,-6.716 -3.951,-9.135 l -54.913,-52.12 c -4.132,-3.924 -11.546,-6.882 -17.245,-6.882 H 19 c -7.168,0 -13,5.832 -13,13 v 110.273 c 0,7.168 5.832,13 13,13 h 101.277 c 5.699,0 13.112,-2.958 17.244,-6.881 l 54.914,-52.122 c 2.548,-2.417 3.951,-5.662 3.951,-9.133 z m -132.858,36.369 c -20.086,0 -36.369,-16.283 -36.369,-36.369 0,-20.086 16.283,-36.369 36.369,-36.369 20.086,0 36.369,16.283 36.369,36.369 10e-4,20.086 -16.282,36.369 -36.369,36.369 z"
|
||||
style="fill:none;stroke:#808080;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /><g
|
||||
id="g12"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g14"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g16"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g18"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g20"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g22"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g24"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g26"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g28"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g30"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g32"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g34"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g36"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g38"
|
||||
transform="translate(0,48.893005)" /><g
|
||||
id="g40"
|
||||
transform="translate(0,48.893005)" /><ellipse
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="path4599-2"
|
||||
cx="242.02635"
|
||||
cy="240.7314"
|
||||
rx="38.337769"
|
||||
ry="37.802738" /></svg>
|
After Width: | Height: | Size: 5.4 KiB |
64
img/blocks/switch_off.svg
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 60 60"
|
||||
style="enable-background:new 0 0 60 60;"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="switch_off.svg"
|
||||
inkscape:version="0.92.1 r15371"><metadata
|
||||
id="metadata45"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs43" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview41"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.9333333"
|
||||
inkscape:cx="30"
|
||||
inkscape:cy="30"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2"
|
||||
d="M 14,20 C 8.486,20 4,24.486 4,30 4,35.514 8.486,40 14,40 19.514,40 24,35.514 24,30 24,24.486 19.514,20 14,20 Z m 0,18 c -4.411,0 -8,-3.589 -8,-8 0,-4.411 3.589,-8 8,-8 4.411,0 8,3.589 8,8 0,4.411 -3.589,8 -8,8 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="M 46,16 H 14 C 6.28,16 0,22.28 0,30 0,37.72 6.28,44 14,44 H 46 C 53.72,44 60,37.72 60,30 60,22.28 53.72,16 46,16 Z m 0,26 H 14 C 7.383,42 2,36.617 2,30 2,23.383 7.383,18 14,18 h 32 c 6.617,0 12,5.383 12,12 0,6.617 -5.383,12 -12,12 z" /><g
|
||||
id="g10" /><g
|
||||
id="g12" /><g
|
||||
id="g14" /><g
|
||||
id="g16" /><g
|
||||
id="g18" /><g
|
||||
id="g20" /><g
|
||||
id="g22" /><g
|
||||
id="g24" /><g
|
||||
id="g26" /><g
|
||||
id="g28" /><g
|
||||
id="g30" /><g
|
||||
id="g32" /><g
|
||||
id="g34" /><g
|
||||
id="g36" /><g
|
||||
id="g38" /></svg>
|
After Width: | Height: | Size: 2.4 KiB |
61
img/blocks/switch_on.svg
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 60 60"
|
||||
style="enable-background:new 0 0 60 60;"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="switch_on.svg"
|
||||
inkscape:version="0.92.1 r15371"><metadata
|
||||
id="metadata45"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs43" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
id="namedview41"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.9333333"
|
||||
inkscape:cx="30"
|
||||
inkscape:cy="30"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6"
|
||||
d="M 14,44 H 46 C 53.72,44 60,37.72 60,30 60,22.28 53.72,16 46,16 H 14 C 6.28,16 0,22.28 0,30 0,37.72 6.28,44 14,44 Z M 46,20 c 5.514,0 10,4.486 10,10 0,5.514 -4.486,10 -10,10 -5.514,0 -10,-4.486 -10,-10 0,-5.514 4.486,-10 10,-10 z" /><g
|
||||
id="g10" /><g
|
||||
id="g12" /><g
|
||||
id="g14" /><g
|
||||
id="g16" /><g
|
||||
id="g18" /><g
|
||||
id="g20" /><g
|
||||
id="g22" /><g
|
||||
id="g24" /><g
|
||||
id="g26" /><g
|
||||
id="g28" /><g
|
||||
id="g30" /><g
|
||||
id="g32" /><g
|
||||
id="g34" /><g
|
||||
id="g36" /><g
|
||||
id="g38" /></svg>
|
After Width: | Height: | Size: 2.1 KiB |
34
keywords.txt
@ -15,13 +15,15 @@ ESPUI KEYWORD1
|
||||
|
||||
label KEYWORD2
|
||||
button KEYWORD2
|
||||
switcher KEYWORD2
|
||||
switcher KEYWORD2
|
||||
pad KEYWORD2
|
||||
slider KEYWORD2
|
||||
|
||||
begin KEYWORD2
|
||||
beginSPIFFS KEYWORD2
|
||||
print KEYWORD2
|
||||
updateSwitcher KEYWORD2
|
||||
updateSlider KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
@ -31,18 +33,18 @@ updateSwitcher KEYWORD2
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
B_DOWN LITERAL1
|
||||
B_UP LITERAL1
|
||||
P_LEFT_DOWN LITERAL1
|
||||
P_LEFT_UP LITERAL1
|
||||
P_RIGHT_DOWN LITERAL1
|
||||
P_RIGHT_UP LITERAL1
|
||||
P_FOR_DOWN LITERAL1
|
||||
P_FOR_UP LITERAL1
|
||||
P_BACK_DOWN LITERAL1
|
||||
P_BACK_UP LITERAL1
|
||||
P_CENTER_DOWN LITERAL1
|
||||
P_CENTER_UP LITERAL1
|
||||
S_ACTIVE LITERAL1
|
||||
S_INACTIVE LITERAL1
|
||||
SL_VALUE LITERAL1
|
||||
B_DOWN LITERAL1
|
||||
B_UP LITERAL1
|
||||
P_LEFT_DOWN LITERAL1
|
||||
P_LEFT_UP LITERAL1
|
||||
P_RIGHT_DOWN LITERAL1
|
||||
P_RIGHT_UP LITERAL1
|
||||
P_FOR_DOWN LITERAL1
|
||||
P_FOR_UP LITERAL1
|
||||
P_BACK_DOWN LITERAL1
|
||||
P_BACK_UP LITERAL1
|
||||
P_CENTER_DOWN LITERAL1
|
||||
P_CENTER_UP LITERAL1
|
||||
S_ACTIVE LITERAL1
|
||||
S_INACTIVE LITERAL1
|
||||
SL_VALUE LITERAL1
|
||||
|
44
lang/ESPUI.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"langs": {
|
||||
"en-GB": {
|
||||
"keys": {
|
||||
"LANG_SUBCATERGORY_ESPUI": "User Interface",
|
||||
"LANG_ESPUI_ESPUI_TITLE": "Title",
|
||||
"LANG_ESPUI_ESPUI_HOTSPOT": "Enable Wifi Hotspot Code",
|
||||
"LANG_ESPUI_ESPUI_TOOLTIP": "Creates a webinterface on the ESP32/ESP8266",
|
||||
"LANG_ESPUI_BUTTON_BUTTON": "UI Button",
|
||||
"LANG_ESPUI_NAME": "name",
|
||||
"LANG_ESPUI_COLOR": "Color",
|
||||
"LANG_ESPUI_TEXT": "Text",
|
||||
"LANG_ESPUI_BUTTON_TOOLTIP": "A web interface button",
|
||||
"LANG_ESPUI_LABEL_LABEL": "UI Label",
|
||||
"LANG_ESPUI_LABEL": "Label",
|
||||
"LANG_ESPUI_LABEL_TOOLTIP": "A web interface label you can update from your code",
|
||||
"LANG_ESPUI_STATE": "State",
|
||||
"LANG_ESPUI_SWITCH_SWITCH": "UI Switch",
|
||||
"LANG_ESPUI_PAD_PAD": "UI Pad",
|
||||
"LANG_ESPUI_PAD_CENTER": "Center button?"
|
||||
}
|
||||
},
|
||||
"zh-CN": {
|
||||
"keys": {
|
||||
"LANG_SUBCATERGORY_ESPUI": "用户接口",
|
||||
"LANG_ESPUI_ESPUI_TITLE": "标题",
|
||||
"LANG_ESPUI_ESPUI_HOTSPOT": "启用无线热点代码",
|
||||
"LANG_ESPUI_ESPUI_TOOLTIP": "在ESP32/ESP8266创建一网络接口",
|
||||
"LANG_ESPUI_BUTTON_BUTTON": "UI 按钮",
|
||||
"LANG_ESPUI_NAME": "名称",
|
||||
"LANG_ESPUI_COLOR": "颜色",
|
||||
"LANG_ESPUI_TEXT": "文本",
|
||||
"LANG_ESPUI_BUTTON_TOOLTIP": "一个网页接口的按钮",
|
||||
"LANG_ESPUI_LABEL_LABEL": "UI 标签",
|
||||
"LANG_ESPUI_LABEL": "标签",
|
||||
"LANG_ESPUI_LABEL_TOOLTIP": "一个网页接口的标签,你可通过修改代码去更新它",
|
||||
"LANG_ESPUI_STATE": "状态",
|
||||
"LANG_ESPUI_SWITCH_SWITCH": "UI 开关",
|
||||
"LANG_ESPUI_PAD_PAD": "UI 面板",
|
||||
"LANG_ESPUI_PAD_CENTER": "中间按钮?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
library.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "ESPUI",
|
||||
"keywords": "espressif web interface iot control simple easy ui userinterface",
|
||||
"description": "ESP32 and ESP8266 Web Interface Library",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/s00500/ESPUI.git"
|
||||
},
|
||||
"authors": [{
|
||||
"name": "Lukas Bachschwell",
|
||||
"email": "lukas@lbsfilm.at",
|
||||
"url": "https://lbsfilm.at",
|
||||
"maintainer": true
|
||||
}],
|
||||
"dependencies": [{
|
||||
"name": "ESP Async WebServer",
|
||||
"authors": "Hristo Gochkov",
|
||||
"frameworks": "arduino"
|
||||
},
|
||||
{
|
||||
"name": "ArduinoJson",
|
||||
"authors": "Benoit Blanchon",
|
||||
"frameworks": "arduino"
|
||||
}
|
||||
],
|
||||
"version": "2.0.2",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
name=ESPUI
|
||||
version=1.4.0
|
||||
version=2.0.2
|
||||
author=Lukas Bachschwell
|
||||
maintainer=Lukas Bachschwell <lukas@lbsfilm.at>
|
||||
sentence=ESP32 and ESP8266 Web Interface Library
|
||||
@ -7,3 +7,4 @@ paragraph=A simple library that implements a web graphical user interface for ES
|
||||
category=Communication
|
||||
url=https://github.com/s00500/ESPUI
|
||||
architectures=*
|
||||
depends=ArduinoJson
|
||||
|
1574
src/ESPUI.cpp
305
src/ESPUI.h
@ -1,55 +1,171 @@
|
||||
#ifndef ESPUI_h
|
||||
#define ESPUI_h
|
||||
|
||||
#define debug true
|
||||
#define DEBUG_ESPUI true
|
||||
#define WS_AUTHENTICATION false
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "ArduinoJson.h"
|
||||
#include "FS.h"
|
||||
#include "stdlib_noniso.h"
|
||||
|
||||
#if defined(ESP32)
|
||||
|
||||
#include "SPIFFS.h"
|
||||
#include "WiFi.h"
|
||||
#include <AsyncTCP.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
#include "SPIFFS.h"
|
||||
#include "WiFi.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <ArduinoOTA.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <FS.h>
|
||||
#include <Hash.h>
|
||||
#include <ESPAsyncTCP.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Hash.h>
|
||||
#include <LittleFS.h>
|
||||
#include <SPIFFSEditor.h>
|
||||
|
||||
#define FILE_WRITE "w"
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct Control {
|
||||
unsigned int type;
|
||||
unsigned int id; // just mirroring the id here for practical reasons
|
||||
const char *label;
|
||||
void (*callback)(Control, int);
|
||||
String value;
|
||||
unsigned int color;
|
||||
} Control;
|
||||
// Message Types (and control types)
|
||||
|
||||
// Types
|
||||
#define UI_TITEL 0
|
||||
#define UI_LABEL 1
|
||||
#define UI_BUTTON 2
|
||||
#define UI_SWITCHER 3
|
||||
#define UI_PAD 4
|
||||
#define UI_CPAD 5
|
||||
#define UPDATE_LABEL 6
|
||||
#define UPDATE_SWITCHER 7
|
||||
#define UI_SLIDER 8
|
||||
#define UPDATE_SLIDER 9
|
||||
enum ControlType : uint8_t
|
||||
{
|
||||
// fixed controls
|
||||
Title = 0,
|
||||
|
||||
// updatable controls
|
||||
Pad,
|
||||
PadWithCenter,
|
||||
Button,
|
||||
Label,
|
||||
Switcher,
|
||||
Slider,
|
||||
Number,
|
||||
Text,
|
||||
Graph,
|
||||
GraphPoint,
|
||||
Tab,
|
||||
Select,
|
||||
Option,
|
||||
Min,
|
||||
Max,
|
||||
Step,
|
||||
Gauge,
|
||||
Accel,
|
||||
|
||||
UpdateOffset = 100,
|
||||
UpdatePad = 101,
|
||||
UpdatePadWithCenter,
|
||||
ButtonButton,
|
||||
UpdateLabel,
|
||||
UpdateSwitcher,
|
||||
UpdateSlider,
|
||||
UpdateNumber,
|
||||
UpdateText,
|
||||
ClearGraph,
|
||||
UpdateTab,
|
||||
UpdateSelection,
|
||||
UpdateOption,
|
||||
UpdateMin,
|
||||
UpdateMax,
|
||||
UpdateStep,
|
||||
UpdateGauge,
|
||||
UpdateAccel,
|
||||
|
||||
InitialGui = 200,
|
||||
Reload = 201
|
||||
};
|
||||
|
||||
#define UI_INITIAL_GUI ControlType::InitialGui
|
||||
#define UI_RELOAD ControlType::Reload
|
||||
|
||||
#define UI_TITLE ControlType::Title
|
||||
#define UI_LABEL ControlType::Label
|
||||
#define UI_BUTTON ControlType::Button
|
||||
#define UI_SWITCHER ControlType::Switcher
|
||||
#define UI_PAD ControlType::Pad
|
||||
#define UI_CPAD ControlType::Cpad
|
||||
#define UI_SLIDER ControlType::Slider
|
||||
#define UI_NUMBER ControlType::Number
|
||||
#define UI_TEXT_INPUT ControlType::Text
|
||||
#define UI_GRAPH ControlType::Graph
|
||||
#define UI_ADD_GRAPH_POINT ControlType::GraphPoint
|
||||
|
||||
#define UPDATE_LABEL ControlType::UpdateLabel
|
||||
#define UPDATE_SWITCHER ControlType::UpdateSwitcher
|
||||
#define UPDATE_SLIDER ControlType::UpdateSlider
|
||||
#define UPDATE_NUMBER ControlType::UpdateNumber
|
||||
#define UPDATE_TEXT_INPUT ControlType::UpdateText
|
||||
#define CLEAR_GRAPH ControlType::ClearGraph
|
||||
|
||||
// Colors
|
||||
enum ControlColor : uint8_t
|
||||
{
|
||||
Turquoise,
|
||||
Emerald,
|
||||
Peterriver,
|
||||
Wetasphalt,
|
||||
Sunflower,
|
||||
Carrot,
|
||||
Alizarin,
|
||||
Dark,
|
||||
None = 0xFF
|
||||
};
|
||||
#define COLOR_TURQUOISE ControlColor::Turquoise
|
||||
#define COLOR_EMERALD ControlColor::Emerald
|
||||
#define COLOR_PETERRIVER ControlColor::Peterriver
|
||||
#define COLOR_WETASPHALT ControlColor::Wetasphalt
|
||||
#define COLOR_SUNFLOWER ControlColor::Sunflower
|
||||
#define COLOR_CARROT ControlColor::Carrot
|
||||
#define COLOR_ALIZARIN ControlColor::Alizarin
|
||||
#define COLOR_DARK ControlColor::Dark
|
||||
#define COLOR_NONE ControlColor::None
|
||||
|
||||
class Control
|
||||
{
|
||||
public:
|
||||
ControlType type;
|
||||
uint16_t id; // just mirroring the id here for practical reasons
|
||||
const char* label;
|
||||
void (*callback)(Control*, int);
|
||||
String value;
|
||||
ControlColor color;
|
||||
uint16_t parentControl;
|
||||
Control* next;
|
||||
|
||||
static constexpr uint16_t noParent = 0xffff;
|
||||
|
||||
Control(ControlType type, const char* label, void (*callback)(Control*, int), const String& value,
|
||||
ControlColor color, uint16_t parentControl = Control::noParent)
|
||||
: type(type),
|
||||
label(label),
|
||||
callback(callback),
|
||||
value(value),
|
||||
color(color),
|
||||
parentControl(parentControl),
|
||||
next(nullptr)
|
||||
{
|
||||
id = idCounter++;
|
||||
}
|
||||
|
||||
Control(const Control& control)
|
||||
: type(control.type),
|
||||
id(control.id),
|
||||
label(control.label),
|
||||
callback(control.callback),
|
||||
value(control.value),
|
||||
color(control.color),
|
||||
parentControl(control.parentControl),
|
||||
next(control.next)
|
||||
{ }
|
||||
|
||||
private:
|
||||
static uint16_t idCounter;
|
||||
};
|
||||
|
||||
// Values
|
||||
#define B_DOWN -1
|
||||
@ -70,60 +186,111 @@ typedef struct Control {
|
||||
#define S_INACTIVE 7
|
||||
|
||||
#define SL_VALUE 8
|
||||
#define N_VALUE 9
|
||||
#define T_VALUE 10
|
||||
#define S_VALUE 11
|
||||
|
||||
enum Verbosity : uint8_t
|
||||
{
|
||||
Quiet = 0,
|
||||
Verbose,
|
||||
VerboseJSON
|
||||
};
|
||||
|
||||
// Colors
|
||||
#define COLOR_TURQUOISE 0
|
||||
#define COLOR_EMERALD 1
|
||||
#define COLOR_PETERRIVER 2
|
||||
#define COLOR_WETASPHALT 3
|
||||
#define COLOR_SUNFLOWER 4
|
||||
#define COLOR_CARROT 5
|
||||
#define COLOR_ALIZARIN 6
|
||||
#define COLOR_NONE 6
|
||||
|
||||
|
||||
class ESPUIClass {
|
||||
|
||||
class ESPUIClass
|
||||
{
|
||||
public:
|
||||
void begin(const char *_title); // Setup servers and page
|
||||
ESPUIClass()
|
||||
{
|
||||
verbosity = Verbosity::Quiet;
|
||||
jsonUpdateDocumentSize = 2000;
|
||||
jsonInitialDocumentSize = 8000;
|
||||
sliderContinuous = false;
|
||||
}
|
||||
unsigned int jsonUpdateDocumentSize;
|
||||
unsigned int jsonInitialDocumentSize;
|
||||
bool sliderContinuous;
|
||||
|
||||
void prepareFileSystem(); // Initially preps the filesystem and loads a lot of stuff into SPIFFS
|
||||
void setVerbosity(Verbosity verbosity);
|
||||
void begin(const char* _title, const char* username = nullptr,
|
||||
const char* password = nullptr); // Setup server and page in Memorymode
|
||||
void beginSPIFFS(const char* _title, const char* username = nullptr,
|
||||
const char* password = nullptr); // Setup server and page in SPIFFSmode
|
||||
|
||||
// Creating Elements
|
||||
void label(const char *label, int color, String value = ""); // Create Label
|
||||
void button(const char *label, void (*callBack)(Control, int), int color,
|
||||
String value = ""); // Create Event Button
|
||||
void switcher(const char *label, bool startState,
|
||||
void (*callBack)(Control, int),
|
||||
int color); // Create Toggle Button
|
||||
void pad(const char *label, bool centerButton, void (*callBack)(Control, int),
|
||||
int color); // Create Pad Control
|
||||
void slider(const char *label, void (*callBack)(Control, int), int color, String value); // Create Slider Control
|
||||
void prepareFileSystem(); // Initially preps the filesystem and loads a lot of
|
||||
// stuff into SPIFFS
|
||||
void list(); // Lists SPIFFS directory
|
||||
|
||||
// Update Elements
|
||||
void print(int id, String value);
|
||||
void print(String label, String value);
|
||||
uint16_t addControl(ControlType type, const char* label, const String& value = String(""),
|
||||
ControlColor color = ControlColor::Turquoise, uint16_t parentControl = Control::noParent,
|
||||
void (*callback)(Control*, int) = nullptr);
|
||||
bool removeControl(uint16_t id, bool force_reload_ui = false);
|
||||
|
||||
void updateSwitcher(int id, bool nValue, int clientId = -1);
|
||||
void updateSwitcher(String label, bool nValue, int clientId = -1);
|
||||
// create Elements
|
||||
uint16_t button(const char* label, void (*callback)(Control*, int), ControlColor color,
|
||||
const String& value = ""); // Create Event Button
|
||||
uint16_t switcher(const char* label, void (*callback)(Control*, int), ControlColor color,
|
||||
bool startState = false); // Create Toggle Button
|
||||
uint16_t pad(const char* label, void (*callback)(Control*, int),
|
||||
ControlColor color); // Create Pad Control
|
||||
uint16_t padWithCenter(const char* label, void (*callback)(Control*, int),
|
||||
ControlColor color); // Create Pad Control with Centerbutton
|
||||
|
||||
void updateSlider(int id, int nValue, int clientId = -1);
|
||||
void updateSlider(String label, int nValue, int clientId = -1);
|
||||
uint16_t slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
|
||||
int max = 100); // Create Slider Control
|
||||
uint16_t number(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
|
||||
int max = 100); // Create a Number Input Control
|
||||
uint16_t text(const char* label, void (*callback)(Control*, int), ControlColor color,
|
||||
const String& value = ""); // Create a Text Input Control
|
||||
|
||||
void textThem(String text, int clientId);
|
||||
// Output only
|
||||
uint16_t label(const char* label, ControlColor color,
|
||||
const String& value = ""); // Create Label
|
||||
uint16_t graph(const char* label, ControlColor color); // Create Graph display
|
||||
uint16_t gauge(const char* label, ControlColor color, int value, int min = 0,
|
||||
int max = 100); // Create Gauge display
|
||||
|
||||
// Variables ---
|
||||
const char *ui_title = "ESPUI"; // Store UI Title and Header Name
|
||||
int cIndex = 0; // Control index
|
||||
Control *controls[25];
|
||||
void jsonDom(AsyncWebSocketClient *client);
|
||||
int getIdByLabel(String label);
|
||||
bool labelExists(String label);
|
||||
// Input only
|
||||
uint16_t accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color);
|
||||
|
||||
// Update Elements
|
||||
|
||||
Control* getControl(uint16_t id);
|
||||
|
||||
// Update Elements
|
||||
void updateControlValue(uint16_t id, const String& value, int clientId = -1);
|
||||
void updateControlValue(Control* control, const String& value, int clientId = -1);
|
||||
|
||||
void updateControl(uint16_t id, int clientId = -1);
|
||||
void updateControl(Control* control, int clientId = -1);
|
||||
|
||||
void print(uint16_t id, const String& value);
|
||||
void updateLabel(uint16_t id, const String& value);
|
||||
void updateSwitcher(uint16_t id, bool nValue, int clientId = -1);
|
||||
void updateSlider(uint16_t id, int nValue, int clientId = -1);
|
||||
void updateNumber(uint16_t id, int nValue, int clientId = -1);
|
||||
void updateText(uint16_t id, const String& nValue, int clientId = -1);
|
||||
void updateSelect(uint16_t id, const String& nValue, int clientId = -1);
|
||||
void updateGauge(uint16_t id, int number, int clientId);
|
||||
|
||||
void clearGraph(uint16_t id, int clientId = -1);
|
||||
void addGraphPoint(uint16_t id, int nValue, int clientId = -1);
|
||||
|
||||
// Variables
|
||||
const char* ui_title = "ESPUI"; // Store UI Title and Header Name
|
||||
Control* controls = nullptr;
|
||||
void jsonReload();
|
||||
void jsonDom(AsyncWebSocketClient* client = nullptr);
|
||||
|
||||
Verbosity verbosity;
|
||||
|
||||
AsyncWebServer* server;
|
||||
AsyncWebSocket* ws;
|
||||
|
||||
private:
|
||||
AsyncWebServer *server;
|
||||
AsyncWebSocket *ws;
|
||||
const char* basicAuthUsername = nullptr;
|
||||
const char* basicAuthPassword = nullptr;
|
||||
bool basicAuth = true;
|
||||
};
|
||||
|
||||
extern ESPUIClass ESPUI;
|
||||
|
5
src/dataControlsJS.h
Normal file
19
src/dataGraphJS.h
Normal file
@ -0,0 +1,19 @@
|
||||
const char JS_GRAPH[] PROGMEM = R"=====(
|
||||
function lineGraph(parent,xAccessor,yAccessor){const width=620;const height=420;const gutter=40;const pixelsPerTick=30;function numericTransformer(dataMin,dataMax,pxMin,pxMax){var dataDiff=dataMax-dataMin,pxDiff=pxMax-pxMin,dataRatio=pxDiff/dataDiff,coordRatio=dataDiff/pxDiff;return{toCoord:function(data){return(data-dataMin)*dataRatio+pxMin;},toData:function(coord){return(coord-pxMin)*coordRatio+dataMin;}};}
|
||||
function axisRenderer(orientation,transform){var axisGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var axisPath=document.createElementNS("http://www.w3.org/2000/svg","path");axisGroup.setAttribute("class",orientation+"-axis");var xMin=gutter;var xMax=width-gutter;var yMin=height-gutter;var yMax=gutter;if(orientation==="x"){axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMax+" "+yMin);for(var i=xMin;i<=xMax;i++){if((i-xMin)%pixelsPerTick===0&&i!==xMin){var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",i);text.setAttribute("y",yMin);text.setAttribute("dy","1em");axisGroup.appendChild(text);}}}else{axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMin+" "+yMax);for(var i=yMax;i<=yMin;i++){if((i-yMin)%pixelsPerTick===0&&i!==yMin){var tickGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var gridLine=document.createElementNS("http://www.w3.org/2000/svg","path");text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",xMin);text.setAttribute("y",i);text.setAttribute("dx","-.5em");text.setAttribute("dy",".3em");gridLine.setAttribute("d","M "+xMin+" "+i+" L "+xMax+" "+i);tickGroup.appendChild(gridLine);tickGroup.appendChild(text);axisGroup.appendChild(tickGroup);}}}
|
||||
axisGroup.appendChild(axisPath);parent.appendChild(axisGroup);}
|
||||
function lineRenderer(xAccessor,yAccessor,xTransform,yTransform){var line=document.createElementNS("http://www.w3.org/2000/svg","path");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
var pathString="M "+xTransform(xAccessor.next())+" "+yTransform(yAccessor.next());while(xAccessor.hasNext()&&yAccessor.hasNext()){pathString+=" L "+
|
||||
xTransform(xAccessor.next())+
|
||||
" "+
|
||||
yTransform(yAccessor.next());}
|
||||
line.setAttribute("class","series");line.setAttribute("d",pathString);parent.appendChild(line);}
|
||||
function pointRenderer(xAccessor,yAccessor,xTransform,yTransform){var pointGroup=document.createElementNS("http://www.w3.org/2000/svg","g");pointGroup.setAttribute("class","data-points");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
while(xAccessor.hasNext()&&yAccessor.hasNext()){var xDataValue=xAccessor.next();var x=xTransform(xDataValue);var yDataValue=yAccessor.next();var y=yTransform(yDataValue);var circle=document.createElementNS("http://www.w3.org/2000/svg","circle");circle.setAttribute("cx",x);circle.setAttribute("cy",y);circle.setAttribute("r","4");var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(xDataValue)+" / "+Math.floor(yDataValue);text.setAttribute("x",x);text.setAttribute("y",y);text.setAttribute("dx","1em");text.setAttribute("dy","-.7em");pointGroup.appendChild(circle);pointGroup.appendChild(text);}
|
||||
parent.appendChild(pointGroup);}
|
||||
xTransform=numericTransformer(xAccessor.min(),xAccessor.max(),0+gutter,width-gutter);yTransform=numericTransformer(yAccessor.min(),yAccessor.max(),height-gutter,0+gutter);axisRenderer("x",xTransform.toData);axisRenderer("y",yTransform.toData);lineRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);pointRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);}
|
||||
function renderGraphSvg(dataArray,renderId){var figure=document.getElementById(renderId);while(figure.hasChildNodes()){figure.removeChild(figure.lastChild);}
|
||||
var svg=document.createElementNS("http://www.w3.org/2000/svg","svg");svg.setAttribute("viewBox","0 0 640 440");svg.setAttribute("preserveAspectRatio","xMidYMid meet");lineGraph(svg,(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].x;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.x;})),Math.max.apply(Math,dataArray.map(function(o){return o.x;}))),(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].y;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.y;})),Math.max.apply(Math,dataArray.map(function(o){return o.y;}))));figure.appendChild(svg);}
|
||||
)=====";
|
||||
|
||||
const uint8_t JS_GRAPH_GZIP[1245] PROGMEM = { 31,139,8,0,19,56,231,94,2,255,205,87,95,111,219,54,16,127,247,167,112,4,44,16,107,89,86,27,175,3,170,240,33,109,135,174,64,18,20,77,48,96,24,246,192,73,180,76,76,150,4,138,182,69,184,254,238,59,146,162,36,219,82,134,58,45,186,135,56,226,253,231,241,119,119,228,98,157,69,130,229,217,56,101,25,253,192,73,177,116,11,194,105,38,188,234,38,138,104,89,230,220,147,246,11,237,162,60,43,197,120,203,98,177,196,175,95,5,161,89,47,41,75,150,2,207,27,66,178,22,130,114,60,183,235,130,85,52,45,63,81,254,200,162,127,240,85,16,46,172,219,108,189,162,156,69,143,156,100,229,34,231,176,112,99,34,200,29,203,60,253,159,84,94,81,169,21,252,146,10,237,54,132,143,21,227,61,91,44,112,45,49,181,26,69,165,201,90,116,106,212,20,235,51,1,87,216,48,103,86,217,139,242,156,199,134,101,105,51,35,19,114,42,214,60,219,137,252,157,146,121,99,131,213,145,161,157,225,234,133,245,140,94,52,126,38,218,111,184,247,68,254,30,104,173,178,246,215,104,235,149,137,17,189,104,67,153,212,6,195,253,62,220,143,154,44,145,138,149,159,105,22,83,14,249,201,57,131,243,81,210,153,39,108,222,76,102,148,220,7,158,175,11,28,231,17,100,54,19,126,196,41,17,244,215,148,170,213,253,131,235,44,133,40,222,204,102,219,237,214,223,94,249,57,79,102,175,130,32,152,149,155,196,241,156,196,65,161,53,244,137,192,33,159,105,167,0,93,48,213,196,227,151,84,220,8,193,217,223,107,65,93,39,74,73,89,58,94,103,39,19,103,170,132,107,247,42,45,216,128,168,94,147,10,107,212,77,59,84,169,164,12,246,14,201,32,92,175,217,162,155,46,140,177,83,57,104,103,119,119,20,85,12,129,223,141,157,137,242,62,113,224,67,154,143,91,77,35,85,67,67,33,164,220,85,190,24,214,167,205,174,177,18,8,217,100,130,118,224,211,101,83,125,178,63,29,2,31,227,224,242,146,93,96,173,100,78,76,208,74,156,155,100,165,11,9,83,255,124,150,101,148,255,246,120,119,139,239,212,198,22,41,64,202,109,208,225,50,84,203,29,238,184,114,60,214,203,144,142,103,54,218,195,139,129,233,188,164,171,131,243,37,69,1,248,124,183,100,105,236,42,29,4,8,222,195,214,233,121,201,110,104,80,243,157,100,75,157,228,107,44,117,210,219,100,203,167,146,45,219,100,3,253,155,148,71,194,89,124,11,13,243,153,229,241,195,15,191,26,58,99,57,4,140,24,180,156,169,255,179,62,254,33,112,248,87,154,109,179,244,95,39,207,142,107,76,185,182,71,117,128,44,107,113,136,111,144,55,128,74,171,161,161,57,234,23,178,96,69,161,153,130,39,76,107,161,237,205,106,112,54,189,185,103,104,122,85,51,220,60,249,120,216,175,211,231,99,168,241,232,115,10,121,118,81,40,79,40,80,36,23,173,220,146,148,247,144,39,23,125,249,114,33,79,169,118,68,193,30,85,136,202,205,3,156,93,150,96,115,106,205,22,218,205,250,153,209,52,53,219,10,200,99,129,112,11,137,164,110,79,44,151,151,189,161,180,222,39,216,128,100,244,100,0,35,21,193,232,201,16,246,163,244,20,147,245,64,114,74,184,140,80,53,133,210,94,220,182,225,244,2,36,213,208,236,96,163,200,89,38,206,5,135,86,126,118,187,106,173,12,108,89,223,99,180,84,249,157,225,244,181,135,175,39,191,186,68,253,78,210,53,197,199,167,109,110,6,184,139,135,70,216,48,101,171,44,251,148,37,238,34,229,72,57,98,60,74,207,174,78,163,13,9,53,31,199,185,87,189,119,136,167,102,239,0,143,131,229,121,61,131,190,235,240,232,100,18,138,122,6,69,213,97,118,51,53,48,87,6,47,21,195,67,229,229,147,35,101,234,255,162,249,29,56,119,43,207,100,107,144,93,223,72,70,61,53,219,106,40,129,22,76,184,231,101,210,34,112,197,50,23,121,157,53,169,96,29,76,204,181,211,235,94,85,161,130,158,52,42,143,140,202,35,163,7,23,220,198,133,153,114,77,107,209,73,111,172,250,230,237,113,44,163,242,127,42,243,21,243,203,175,95,68,135,102,52,169,78,253,183,48,212,233,159,92,155,211,207,210,135,77,162,159,92,55,156,19,233,25,198,199,216,52,137,5,75,214,188,83,170,9,21,117,37,188,149,31,99,183,17,174,199,143,17,87,157,70,67,224,62,143,105,169,250,77,77,231,116,149,111,168,65,71,77,130,86,41,52,1,213,83,17,202,232,220,218,83,191,40,132,223,35,152,111,24,221,190,205,85,37,4,227,96,252,122,30,140,231,243,160,87,178,80,141,152,111,232,77,89,208,72,232,119,35,104,193,117,42,254,3,254,198,43,74,69,61,193,204,131,30,44,120,238,193,35,214,3,168,121,43,251,158,102,56,176,79,222,186,251,182,175,86,219,190,199,236,90,41,250,41,205,18,177,132,231,109,214,47,166,132,254,132,155,249,95,126,5,66,122,98,116,165,148,171,189,242,222,163,186,210,207,102,136,170,143,7,247,126,245,36,70,29,12,232,142,4,74,170,156,83,233,170,165,215,112,161,120,138,118,207,121,99,40,87,113,33,84,43,147,234,28,101,244,3,178,41,255,167,217,148,207,201,166,86,134,43,89,93,101,221,182,12,152,133,90,251,23,198,24,146,161,158,18,0,0 };
|
5
src/dataIndexHTML.h
Normal file
@ -0,0 +1,5 @@
|
||||
const char HTML_INDEX[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html><html> <head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="shortcut icon" href=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAPFBMVEUAAACA1VWR21qQ2liR3FqR3FqS3VuR3VqR3VuR3VqO21mS21uS3FqS3FqS21uJ2GKQ21qR3FuR3FoAAAB/3Gu7AAAAEnRSTlMABoA3kPBwz8i5Kzioxg4NVcU3uEJHAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+EFEhcEM+HpYwQAAABYSURBVBjThY/JDsAgCESt4lpX/v9jLQZJ6qF9t3khAyj1xXUKbQ4BVowDwqOYgExkkW4iY6lPaF06RqM8YItOuRbMaz6xjbsusDAW/drplBg47jP696cXE8bPA1eUDeK2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA1LTE4VDIzOjA0OjUxKzAyOjAwxE59ewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNS0xOFQyMzowNDo1MSswMjowMLUTxccAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head> <body onload=javascript:start();> <div> <h4> <div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span> </h4> </div> <hr> <div class=container> <div id=row class="row u-full-width"></div> <ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul> <div id=tabscontent class="tabscontent u-full-width"></div> </div> </body> </html>
|
||||
)=====";
|
||||
|
||||
const uint8_t HTML_INDEX_GZIP[916] PROGMEM = { 31,139,8,0,19,56,231,94,2,255,133,148,235,115,162,58,20,192,255,21,174,159,238,157,221,22,95,181,237,174,56,19,20,108,85,68,64,240,241,45,64,42,193,240,40,9,162,254,245,155,128,157,238,157,189,211,235,12,201,201,57,191,243,200,17,206,240,175,137,57,94,239,86,154,20,177,132,140,134,245,42,13,35,4,195,209,48,65,12,74,65,4,11,138,152,82,178,183,187,167,209,144,97,70,208,104,156,165,172,200,200,80,110,142,13,153,194,4,41,39,140,170,60,43,152,20,112,4,165,76,105,85,56,100,145,18,162,19,14,208,93,125,248,46,225,20,51,12,201,29,13,32,65,74,167,53,26,18,156,30,165,2,17,165,69,35,238,30,148,76,194,60,68,75,138,10,244,166,132,144,193,31,56,129,7,36,231,233,225,167,15,41,26,244,191,99,79,53,237,170,61,159,30,50,192,127,75,199,141,52,247,192,37,85,28,129,53,6,134,216,179,133,245,188,22,130,58,13,213,181,171,1,176,152,174,198,242,57,82,45,174,28,171,177,163,207,150,220,58,152,113,223,195,43,87,174,68,188,49,24,240,53,20,158,102,46,162,14,18,190,232,189,113,80,18,237,73,196,91,233,170,225,105,110,205,118,188,141,221,237,188,91,93,130,237,158,254,46,30,167,231,149,118,207,227,114,179,155,221,78,226,116,59,165,83,219,248,195,229,89,119,58,183,184,31,231,57,163,139,188,170,220,155,150,143,34,190,150,218,206,154,24,64,205,64,239,184,82,171,235,19,126,152,95,113,118,62,244,151,94,224,246,74,109,246,82,223,116,51,91,216,109,11,96,224,134,78,173,32,149,163,147,171,232,73,167,2,96,18,6,170,133,177,143,106,91,216,118,220,142,174,126,211,116,45,10,52,227,219,75,190,171,68,35,212,157,227,218,170,167,198,235,104,39,207,38,20,28,198,154,195,250,36,223,202,167,231,120,97,237,103,131,119,253,153,245,142,17,184,196,157,243,214,157,251,86,95,245,178,106,82,189,155,187,131,118,62,30,55,125,188,27,144,21,212,219,3,251,221,120,218,189,50,179,180,125,3,94,7,231,216,167,37,157,128,141,28,22,57,81,15,253,199,120,53,120,30,4,91,237,201,95,129,14,114,39,104,222,21,213,205,182,182,190,121,177,143,187,173,77,204,100,121,217,111,244,246,222,2,23,99,162,245,22,107,208,89,172,181,190,55,121,189,154,49,104,155,177,123,158,95,193,133,203,213,89,123,120,70,149,248,43,188,182,237,69,237,253,148,251,173,115,230,119,237,124,159,30,129,17,131,243,242,210,174,150,78,251,108,234,214,197,184,102,213,114,146,117,12,135,86,70,156,85,198,194,93,159,131,64,148,176,15,53,111,23,234,203,211,62,181,123,187,237,140,128,151,176,23,94,30,114,63,97,215,93,87,175,246,206,195,41,72,144,255,24,87,176,110,169,70,244,245,209,41,173,100,60,254,237,77,166,236,66,16,141,16,98,205,75,44,7,148,202,105,86,36,144,224,43,186,231,167,255,131,107,101,3,210,160,192,57,147,104,17,40,114,76,229,43,202,89,118,159,224,244,62,230,70,185,177,254,65,81,130,67,84,124,137,28,10,152,71,95,18,65,243,173,211,47,33,6,125,31,133,183,111,254,223,164,92,15,19,105,232,103,225,69,202,82,146,193,80,137,225,9,54,246,31,148,193,130,253,253,207,79,78,132,248,36,102,79,191,17,37,28,42,9,196,233,11,119,71,197,231,200,105,40,154,195,84,16,60,165,195,32,43,169,20,16,72,169,66,160,143,200,200,124,123,227,157,69,188,8,142,113,90,174,131,222,92,163,226,150,160,241,16,69,243,52,168,248,76,91,100,213,205,216,18,98,121,247,86,18,210,204,46,62,170,110,97,74,34,80,126,113,154,194,143,88,45,46,226,3,100,56,75,165,79,241,78,64,127,68,41,201,103,66,1,220,154,247,17,233,119,213,127,23,240,177,137,198,214,119,172,103,247,47,103,53,186,226,210,5,0,0 };
|
5
src/dataNormalizeCSS.h
Normal file
@ -0,0 +1,5 @@
|
||||
const char CSS_NORMALIZE[] PROGMEM = R"=====(
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
||||
)=====";
|
||||
|
||||
const uint8_t CSS_NORMALIZE_GZIP[861] PROGMEM = { 31,139,8,0,19,56,231,94,2,255,149,84,237,142,155,58,16,125,149,104,171,74,183,146,137,216,237,199,94,25,221,39,137,242,99,176,7,112,227,47,217,38,155,20,241,238,119,12,132,36,219,108,165,254,2,6,123,230,204,57,103,166,75,70,15,141,179,169,104,192,40,125,230,17,108,44,34,6,213,84,133,137,69,194,83,42,162,250,133,5,200,159,125,76,252,185,44,63,87,197,27,214,7,149,30,255,29,107,39,207,131,129,208,42,203,203,17,66,82,66,35,131,168,36,50,137,9,148,142,172,81,173,0,159,148,179,249,181,15,200,26,231,18,6,214,33,200,252,104,131,235,61,51,160,44,51,104,123,102,225,200,34,138,233,70,236,13,165,63,15,82,69,175,225,204,107,237,196,97,132,94,42,199,4,216,35,68,230,131,107,3,198,200,142,84,213,173,39,149,213,202,98,49,93,168,142,152,161,129,46,64,171,214,242,26,34,230,191,115,34,110,93,250,103,39,136,153,224,116,220,127,89,83,88,103,177,234,80,181,93,162,238,118,157,146,18,237,158,37,52,244,59,225,221,185,17,134,26,196,33,247,98,101,33,156,118,129,167,64,12,123,8,104,211,8,28,168,163,35,145,195,59,71,112,6,215,167,12,33,211,86,215,97,151,84,210,184,31,106,23,136,147,162,118,41,57,195,159,253,105,35,233,21,229,88,179,72,240,108,59,43,248,54,131,170,157,150,163,108,236,28,140,233,172,145,171,68,61,138,177,123,94,130,36,25,127,65,83,45,42,109,127,188,162,217,148,35,125,30,110,16,243,79,77,83,86,51,236,79,101,89,142,209,128,214,55,41,254,37,181,99,79,40,122,127,19,125,253,254,185,154,104,190,176,84,121,23,85,86,142,7,36,142,168,225,15,185,207,153,146,243,188,216,126,71,147,115,15,75,215,197,246,37,71,148,105,23,58,136,163,120,108,39,153,120,32,239,124,25,50,131,141,118,111,124,214,100,156,141,117,113,226,51,117,248,173,244,167,177,11,67,97,220,47,162,243,148,241,42,219,242,44,51,233,145,67,213,7,225,85,113,79,41,215,74,208,39,55,10,71,198,62,212,146,76,135,44,130,241,119,3,101,156,117,164,183,64,182,190,85,87,174,8,213,88,247,212,161,101,202,250,62,49,231,211,108,125,34,132,236,206,242,136,145,89,96,152,101,80,182,163,217,76,83,134,245,99,157,181,57,211,21,222,81,69,85,107,188,84,152,83,14,211,212,78,54,108,92,48,179,81,151,19,29,173,131,205,4,100,151,206,30,255,123,154,227,79,123,118,27,164,193,194,244,46,70,82,25,69,193,225,178,27,192,123,4,42,34,144,207,73,42,209,135,72,45,120,167,136,214,176,148,220,209,188,0,97,148,251,219,226,107,112,88,46,73,108,160,215,105,185,196,249,164,96,227,68,31,11,101,45,45,140,233,222,239,241,213,44,149,7,41,179,168,229,56,29,29,110,29,106,137,7,208,227,109,63,162,67,113,32,225,223,183,14,180,27,158,242,72,174,46,89,167,243,244,190,198,114,199,246,166,198,240,180,39,116,11,55,19,180,34,122,101,139,91,241,63,60,79,107,225,254,252,176,0,159,252,119,39,3,113,46,186,199,50,100,221,27,133,90,86,127,242,255,229,226,95,141,199,67,12,87,252,115,164,16,25,134,126,212,242,135,87,36,10,23,32,239,142,71,29,77,214,157,90,34,67,94,164,206,251,49,58,173,228,38,42,77,147,176,142,199,230,197,95,37,218,126,165,117,178,217,254,120,153,30,175,121,183,104,108,209,202,71,142,89,135,240,126,240,47,179,250,251,250,77,217,189,151,189,77,147,171,193,71,228,151,151,106,249,145,151,193,82,64,178,212,13,215,130,255,3,4,241,118,208,151,7,0,0 };
|
15
src/dataSliderJS.h
Normal file
@ -0,0 +1,15 @@
|
||||
const char JS_SLIDER[] PROGMEM = R"=====(
|
||||
function rkmd_rangeSlider(selector){var self,slider_width,slider_offset,curnt,sliderDiscrete,range,slider;self=$(selector);slider_width=self.width();slider_offset=self.offset().left;sliderDiscrete=self;sliderDiscrete.each(function(i,v){curnt=$(this);curnt.append(sliderDiscrete_tmplt());range=curnt.find('input[type="range"]');slider=curnt.find(".slider");slider_fill=slider.find(".slider-fill");slider_handle=slider.find(".slider-handle");slider_label=slider.find(".slider-label");var range_val=parseInt(range.val());slider_fill.css("width",range_val+"%");slider_handle.css("left",range_val+"%");slider_label.find("span").text(range_val);});self.on("mousedown touchstart",".slider-handle",function(e){if(e.button===2){return false;}
|
||||
var parents=$(this).parents(".rkmd-slider");var slider_width=parents.width();var slider_offset=parents.offset().left;var check_range=parents.find('input[type="range"]').is(":disabled");if(check_range===true){return false;}
|
||||
$(this).addClass("is-active");var moveFu=function(e){var pageX=e.pageX||e.changedTouches[0].pageX;var slider_new_width=pageX-slider_offset;if(slider_new_width<=slider_width&&!(slider_new_width<"0")){slider_move(parents,slider_new_width,slider_width,true);}};var upFu=function(e){$(this).off(handlers);parents.find(".is-active").removeClass("is-active");};var handlers={mousemove:moveFu,touchmove:moveFu,mouseup:upFu,touchend:upFu,};$(document).on(handlers);});self.on("mousedown touchstart",".slider",function(e){if(e.button===2){return false;}
|
||||
var parents=$(this).parents(".rkmd-slider");var slider_width=parents.width();var slider_offset=parents.offset().left;var check_range=parents.find('input[type="range"]').is(":disabled");if(check_range===true){return false;}
|
||||
var slider_new_width=e.pageX-slider_offset;if(slider_new_width<=slider_width&&!(slider_new_width<"0")){slider_move(parents,slider_new_width,slider_width,true);}
|
||||
var upFu=function(e){$(this).off(handlers);};var handlers={mouseup:upFu,touchend:upFu,};$(document).on(handlers);});}
|
||||
function sliderDiscrete_tmplt(){var tmplt='<div class="slider">'+
|
||||
'<div class="slider-fill"></div>'+
|
||||
'<div class="slider-handle"><div class="slider-label"><span>0</span></div></div>'+
|
||||
"</div>";return tmplt;}
|
||||
function slider_move(parents,newW,sliderW,send){var slider_new_val=parseInt(Math.round((newW/sliderW)*100));var slider_fill=parents.find(".slider-fill");var slider_handle=parents.find(".slider-handle");var range=parents.find('input[type="range"]');range.next().html(newW);slider_fill.css("width",slider_new_val+"%");slider_handle.css({left:slider_new_val+"%",transition:"none","-webkit-transition":"none","-moz-transition":"none",});range.val(slider_new_val);if(parents.find(".slider-handle span").text()!=slider_new_val){parents.find(".slider-handle span").text(slider_new_val);var number=parents.attr("id").substring(2);if(send)websock.send("slvalue:"+slider_new_val+":"+number);}}
|
||||
)=====";
|
||||
|
||||
const uint8_t JS_SLIDER_GZIP[881] PROGMEM = { 31,139,8,0,150,187,70,95,2,255,237,86,77,143,218,48,16,189,243,43,88,107,187,196,93,240,210,61,18,204,165,85,165,30,122,106,165,86,90,173,144,73,156,141,69,112,162,216,129,182,44,255,189,227,143,132,36,192,106,219,83,15,61,37,246,60,143,223,204,60,123,156,84,50,210,34,151,195,114,189,137,151,37,147,79,252,75,38,98,94,6,138,103,60,210,121,137,247,91,86,14,97,148,140,149,181,44,119,34,214,105,61,200,147,68,113,61,142,170,82,106,63,247,65,168,168,228,154,143,173,59,63,25,26,15,244,250,232,54,108,123,163,198,74,236,111,208,88,156,107,103,114,255,1,38,25,79,116,216,221,199,34,122,115,132,179,40,13,18,31,93,32,198,91,188,183,28,129,130,78,133,194,161,29,17,86,20,92,198,65,119,241,82,111,138,12,54,195,161,141,128,58,104,34,0,56,18,178,168,244,131,254,89,112,138,172,21,61,142,106,198,109,32,34,110,14,53,225,36,34,203,168,251,239,66,38,198,114,196,165,76,198,25,63,143,116,182,35,54,99,43,126,193,169,53,1,210,84,207,18,93,110,89,70,11,86,42,254,73,234,192,78,17,152,50,97,182,24,146,72,169,0,217,74,160,113,179,238,22,189,233,19,116,64,83,142,75,56,203,192,179,82,5,147,8,19,205,127,248,173,13,26,135,7,28,186,242,202,0,109,242,74,241,56,223,201,161,206,171,40,85,154,149,224,186,31,250,184,169,41,199,123,145,4,156,172,42,173,115,73,41,189,199,123,168,30,148,96,152,176,76,241,240,48,48,177,67,196,92,106,85,215,157,248,49,36,202,72,126,210,84,201,170,188,45,73,15,108,84,217,2,120,101,214,136,174,56,13,46,74,121,180,118,199,169,65,189,160,31,34,128,207,44,22,138,173,50,30,3,25,8,172,237,130,82,93,86,252,36,188,58,36,22,199,239,51,102,202,33,212,132,65,118,182,220,7,180,201,183,252,99,69,219,57,115,57,121,226,223,41,39,246,251,252,12,181,76,205,62,241,87,147,120,174,30,166,143,206,212,142,89,242,93,147,24,48,77,58,169,48,132,251,184,57,109,167,243,230,230,234,20,129,166,8,227,189,159,54,92,3,159,172,113,31,218,189,123,108,54,194,195,193,242,171,138,94,132,117,90,128,90,224,84,83,194,121,239,148,1,145,86,166,72,201,205,222,103,82,232,54,168,125,208,189,149,168,193,206,92,98,199,86,169,237,9,139,168,138,153,33,229,172,112,189,184,209,33,188,14,226,60,170,54,64,3,27,197,31,185,189,254,24,252,215,127,47,188,19,117,122,85,255,11,250,28,252,129,60,207,74,237,111,132,116,24,212,155,13,207,119,53,123,3,216,127,58,154,199,98,59,140,140,240,41,242,74,88,140,110,7,103,230,93,147,90,204,239,192,114,9,226,175,232,197,25,147,235,70,139,185,233,3,139,233,252,206,126,157,179,198,37,114,127,40,244,101,182,28,79,227,233,22,2,42,240,205,39,31,190,144,35,255,94,57,214,167,211,246,62,51,157,146,50,175,64,138,129,89,122,231,151,226,183,239,166,83,220,17,185,237,215,189,91,163,219,176,91,96,223,180,207,195,155,174,221,244,226,215,28,10,247,248,32,210,180,76,76,82,189,201,44,227,203,221,186,27,243,165,150,189,55,135,116,118,138,5,209,50,169,132,73,244,12,201,92,66,171,69,147,29,95,173,133,158,28,77,232,104,219,228,191,206,25,14,53,113,243,182,232,110,99,207,245,75,41,26,182,159,9,248,138,246,150,239,95,189,182,191,175,73,188,172,54,43,120,163,213,62,152,214,37,220,246,112,219,16,85,173,148,46,133,124,10,238,45,69,43,35,8,93,229,209,154,152,1,188,95,50,240,83,241,25,186,237,103,14,166,156,103,211,144,126,3,128,124,107,46,79,11,0,0 };
|
5
src/dataStyleCSS.h
Normal file
39
src/dataTabbedcontentJS.h
Normal file
5
src/dataZeptoJS.h
Normal file
@ -1,27 +0,0 @@
|
||||
const char HTML_INDEX[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Control</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAPFBMVEUAAACA1VWR21qQ2liR3FqR3FqS3VuR3VqR3VuR3VqO21mS21uS3FqS3FqS21uJ2GKQ21qR3FuR3FoAAAB/3Gu7AAAAEnRSTlMABoA3kPBwz8i5Kzioxg4NVcU3uEJHAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+EFEhcEM+HpYwQAAABYSURBVBjThY/JDsAgCESt4lpX/v9jLQZJ6qF9t3khAyj1xXUKbQ4BVowDwqOYgExkkW4iY6lPaF06RqM8YItOuRbMaz6xjbsusDAW/drplBg47jP696cXE8bPA1eUDeK2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA1LTE4VDIzOjA0OjUxKzAyOjAwxE59ewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNS0xOFQyMzowNDo1MSswMjowMLUTxccAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC"
|
||||
/>
|
||||
<link rel="stylesheet" href="/css/normalize.css">
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
|
||||
<script src="/js/zepto.js"></script>
|
||||
<script src="/js/slider.js"></script>
|
||||
<script src="/js/controls.js"></script>
|
||||
</head>
|
||||
<body onload="javascript:start();">
|
||||
<div>
|
||||
<h4><div id="mainHeader">Control</div> <span id="conStatus" class="label">Offline</span></h4></div>
|
||||
<hr />
|
||||
<div class="container">
|
||||
<div id="row" class="row u-full-width">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
@ -1,3 +0,0 @@
|
||||
const char CSS_NORMALIZE[] PROGMEM = R"=====(
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
||||
)=====";
|
@ -1,3 +0,0 @@
|
||||
const char JS_SLIDER[] PROGMEM = R"=====(
|
||||
function rkmd_rangeSlider(b){var f,e,c,a,g,d,h;f=$(b);e=f.width();c=f.offset().left;g=f;g.each(function(k,j){a=$(this);a.append(sliderDiscrete_tmplt());d=a.find('input[type="range"]');h=a.find(".slider");slider_fill=h.find(".slider-fill");slider_handle=h.find(".slider-handle");slider_label=h.find(".slider-label");var l=parseInt(d.val());slider_fill.css("width",l+"%");slider_handle.css("left",l+"%");slider_label.find("span").text(l)});f.on("mousedown touchstart",".slider-handle",function(o){if(o.button===2){return false}var m=$(this).parents(".rkmd-slider");var l=m.width();var i=m.offset().left;var k=m.find('input[type="range"]').is(":disabled");if(k===true){return false}$(this).addClass("is-active");var p=function(r){var q=r.pageX-i;if(q<=l&&!(q<"0")){slider_move(m,q,l,true)}};var n=function(q){$(this).off(j);m.find(".is-active").removeClass("is-active")};var j={mousemove:p,touchmove:p,mouseup:n,touchend:n};$(document).on(j)});f.on("mousedown touchstart",".slider",function(p){if(p.button===2){return false}var m=$(this).parents(".rkmd-slider");var l=m.width();var i=m.offset().left;var k=m.find('input[type="range"]').is(":disabled");if(k===true){return false}var o=p.pageX-i;if(o<=l&&!(o<"0")){slider_move(m,o,l,true)}var n=function(q){$(this).off(j)};var j={mouseup:n,touchend:n};$(document).on(j)})}function sliderDiscrete_tmplt(){var a='<div class="slider"><div class="slider-fill"></div><div class="slider-handle"><div class="slider-label"><span>0</span></div></div></div>';return a}function slider_move(g,a,h,e){var i=parseInt(Math.round(a/h*100));var b=g.find(".slider-fill");var c=g.find(".slider-handle");var f=g.find('input[type="range"]');b.css("width",i+"%");c.css({left:i+"%",transition:"none","-webkit-transition":"none","-moz-transition":"none"});f.val(i);if(g.find(".slider-handle span").text()!=i){g.find(".slider-handle span").text(i);var d=g.attr("id").substring(2);if(e){websock.send("slvalue:"+i+":"+d)}}};
|
||||
)=====";
|
134
tools/prepare_static_ui_sources.py
Executable file
@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from jsmin import jsmin as jsminify
|
||||
from htmlmin import minify as htmlminify
|
||||
from csscompressor import compress as cssminify
|
||||
import gzip
|
||||
import sys
|
||||
import os.path
|
||||
import argparse
|
||||
import re
|
||||
from glob import glob
|
||||
|
||||
TARGET_TEMPLATE = '''const char {constant}[] PROGMEM = R"=====(
|
||||
{minidata}
|
||||
)=====";
|
||||
|
||||
const uint8_t {constant}_GZIP[{gziplen}] PROGMEM = {{ {gzipdata} }};
|
||||
'''
|
||||
|
||||
def parse_arguments(args=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Prepares ESPUI header files by minifying and gzipping HTML, JS and CSS source files.")
|
||||
parser.add_argument("--auto", "--all", "-a", dest="auto", action="store_true",
|
||||
help="Automatically find all source files in data/ and write C header files to src/")
|
||||
parser.add_argument("--source", "--sources", "-s", dest="sources", default=None,
|
||||
help="Sources directory containing CSS or JS files OR one specific file to minify")
|
||||
parser.add_argument("--target", "-t", dest="target", default=None,
|
||||
help="Target directory containing C header files OR one C header file")
|
||||
parser.add_argument("--nostoremini", "-m", action="store_false", dest="storemini",
|
||||
help="Do not store intermediate minified files next to the originals (i.e. only write to the C header files)")
|
||||
args = parser.parse_args(args)
|
||||
if not args.auto and (not args.sources or not args.target):
|
||||
print("ERROR: You need to specify either --auto or both --source and --target\n")
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
return args
|
||||
|
||||
def get_context(infile, outfile):
|
||||
infile = os.path.realpath(infile)
|
||||
dir, name, type = (os.path.basename(os.path.dirname(infile)), os.path.basename(infile).split(os.path.extsep)[0], os.path.basename(infile).split(os.path.extsep)[-1] )
|
||||
type = type.strip(".").lower()
|
||||
if dir.lower() == type:
|
||||
dir = os.path.basename(os.path.dirname(os.path.dirname(infile)))
|
||||
if type == "htm":
|
||||
type = 'html'
|
||||
name = os.path.basename(name)
|
||||
indir = os.path.dirname(infile)
|
||||
if os.path.isdir(outfile):
|
||||
outdir = os.path.realpath(outfile)
|
||||
outfilename = "%s%s%s.h" % (dir, name.capitalize(), type.upper())
|
||||
outfile = os.path.realpath(os.path.sep.join([outdir, outfilename]))
|
||||
else:
|
||||
outfile = os.path.realpath(outfile)
|
||||
outdir = os.path.dirname(outfile)
|
||||
outfilename = os.path.basename(outfile)
|
||||
minifile = re.sub('\.([^.]+)$', '.min.\\1', infile) if not ".min." in infile else infile
|
||||
constant = '%s_%s' % (type.upper(), name.upper())
|
||||
return locals()
|
||||
|
||||
def perform_gzip(c):
|
||||
compressed = gzip.compress(bytes(c['minidata'], 'utf-8'))
|
||||
c['gzipdata'] = ','.join([ str(b) for b in compressed ])
|
||||
c['gziplen'] = len(compressed)
|
||||
print(" GZIP data length: %s" % c['gziplen'])
|
||||
return c
|
||||
|
||||
def perform_minify(c):
|
||||
with open(c['infile']) as infile:
|
||||
minifier = {
|
||||
'css': cssminify,
|
||||
'js': jsminify,
|
||||
'html': htmlminify
|
||||
}.get(c['type']) or htmlminify
|
||||
print(" Using %s minifier" % c['type'])
|
||||
c['minidata'] = minifier(infile.read())
|
||||
return perform_gzip(c)
|
||||
|
||||
def process_file(infile, outdir, storemini=True):
|
||||
print("Processing file %s" % infile)
|
||||
c = get_context(infile, outdir)
|
||||
c = perform_minify(c)
|
||||
if storemini:
|
||||
if c['infile'] == c['minifile']:
|
||||
print(" Original file is already minified, refusing to overwrite it")
|
||||
else:
|
||||
print(" Writing minified file %s" % c['minifile'])
|
||||
with open(c['minifile'], 'w+') as minifile:
|
||||
minifile.write(c['minidata'])
|
||||
with open(c['outfile'], 'w+') as outfile:
|
||||
print(" Using C constant names %s and %s_GZIP" % (c['constant'], c['constant']))
|
||||
print(" Writing C header file %s" % c['outfile'])
|
||||
outfile.write(TARGET_TEMPLATE.format(**c))
|
||||
|
||||
def filenamefilter(pattern, strings):
|
||||
return filter(re.compile(pattern).search, strings)
|
||||
|
||||
def process_dir(sourcedir, outdir, recursive=True, storemini=True):
|
||||
pattern = r'/*\.(css|js|htm|html)$'
|
||||
files = glob(sourcedir + "/**/*", recursive=True)+glob(sourcedir + "/*") if recursive else glob(sourcedir + "/*")
|
||||
files = filenamefilter(pattern, files)
|
||||
for f in set(files):
|
||||
if not '.min.' in f:
|
||||
process_file(f, outdir, storemini)
|
||||
elif not os.path.isfile(f.replace(".min.", ".")):
|
||||
process_file(f, outdir, storemini)
|
||||
|
||||
def check_args(args):
|
||||
abort = 0
|
||||
if not os.path.exists(args.sources):
|
||||
print("ERROR: Source %s does not exist" % args.sources)
|
||||
abort += 2
|
||||
if not os.path.isdir(os.path.dirname(args.target)):
|
||||
print("ERROR: Parent directory of target %s does not exist" % args.target)
|
||||
abort += 4
|
||||
if os.path.isdir(args.sources) and not os.path.isdir(args.target):
|
||||
print("ERROR: Source %s is a directory, target %s is not" % (args.sources, args.target))
|
||||
abort += 8
|
||||
if abort > 0:
|
||||
print("Aborting.")
|
||||
sys.exit(abort)
|
||||
|
||||
def main(args):
|
||||
args.sources = os.path.realpath(args.sources or os.sep.join((os.path.dirname(os.path.realpath(__file__)), "..", "data")))
|
||||
args.target = os.path.realpath(args.target or os.sep.join((os.path.dirname(os.path.realpath(__file__)), "..", "src")))
|
||||
check_args(args)
|
||||
if os.path.isfile(args.sources):
|
||||
print("Source %s is a file, will process one file only." % args.sources)
|
||||
process_file(args.sources, args.target, storemini = args.storemini)
|
||||
elif os.path.isdir(args.sources):
|
||||
print("Source %s is a directory, searching for files recursively..." % args.sources)
|
||||
process_dir(args.sources, args.target, recursive = True, storemini = args.storemini)
|
||||
|
||||
if __name__ == "__main__" and "get_ipython" not in dir():
|
||||
main(parse_arguments())
|