Experimental Macros

pull/110/head
openbuilds-engineer 2018-11-26 21:22:53 +02:00
rodzic 752a0374d3
commit 5b30504e73
8 zmienionych plików z 5935 dodań i 0 usunięć

Wyświetl plik

@ -10,6 +10,16 @@ body {
supported by Chrome and Opera */
}
#macros {
/* Note only uses height attribs from here, before we connect to websocket. After that, it gets set by websocket.js */
height: calc(100vh - 480px);
width: 100%;
border-top: 1px solid #ccc;
/* margin-top: 5px; */
box-shadow: 0 0 2px 2px #ddd;
background-color: #fff;
}
#renderArea {
/* Note only uses height attribs from here, before we connect to websocket. After that, it gets set by websocket.js */
height: calc(100vh - 480px);
@ -17,6 +27,7 @@ body {
border-top: 1px solid #ccc;
/* margin-top: 5px; */
box-shadow: 0 0 2px 2px #ddd;
background-color: #fff;
}

Wyświetl plik

@ -10,6 +10,7 @@
<meta name="metro4:init" content="true">
<script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
<link rel="stylesheet" href="lib/metro4/css/metro-all.min.css" />
<link rel="stylesheet" href="lib/iconpicker/css/fontawesome-iconpicker.min.css" />
<link rel="stylesheet" href="css/buttons.css" />
<link rel="stylesheet" href="css/main.css" />
</head>
@ -541,6 +542,7 @@
<li><a href="#tab-one" id="consoletab"><i class="fas fa-fw fa-terminal"></i> Serial Console</a></li>
<li><a href="#tab-two" id="gcodeeditortab"><i class="far fa-fw fa-edit"></i> GCODE Editor</a></li>
<li><a href="#tab-three" id="gcodeviewertab" onclick="fixRenderSize();"><i class="mif-3d-rotation fa-fw"></i> 3D View</a></li>
<li><a href="#tab-four" id="macrostab"><i class="fas fa-th fa-fw"></i> Macros</a></li>
</ul>
@ -583,6 +585,9 @@
<button id="resetViewBtn" title="Stop Sim" class="button dark" onclick="resetView(object)"><i class="fas fa-stop"></i> Reset View</button>&nbsp;
</div>
</div>
<div class="section" id="tab-four">
<div id="macros"></div>
</div>
</div>
</nav>
</div>
@ -831,6 +836,9 @@
<script type="text/javascript" src="/lib/lodash.core.js"></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript" src="/lib/iconpicker/js/fontawesome-iconpicker.min.js"></script>
<script type="text/javascript" src="/js/macros.js"></script>
<script type="text/javascript" src="lib/threejs/three.min.js"></script>
<script type="text/javascript" src="lib/threejs/GridRect.js"></script>
<script type="text/javascript" src="lib/threejs/OrbitControls.js"></script>

149
app/js/macros.js 100644
Wyświetl plik

@ -0,0 +1,149 @@
var buttonsarray = []
function populateMacroButtons() {
$("#macros").empty();
for (i = 0; i < buttonsarray.length; i++) {
var button = `
<button id="macro` + i + `" onclick="sendGcode('` + buttonsarray[i].gcode + `');" class="shortcut outline rounded no-caption m-1 ` + buttonsarray[i].class + `">
<span class="tag"><span onclick="edit(` + i + `, event);" id="edit` + i + `" class="fas fa-cogs"></span></span>
<span class="caption">` + buttonsarray[i].title + `</span>
<span class="` + buttonsarray[i].icon + ` icon"></span>
</button>`
$("#macros").append(button);
}
// append add button
var button = `
<button class="shortcut outline rounded no-caption m-1" onclick="edit(10, event)">
<span class="caption">Add Macro</span>
<span class="fas fa-plus icon"></span>
</button>`
$("#macros").append(button);
localStorage.setItem('macroButtons', JSON.stringify(buttonsarray));
}
function edit(i, evt) {
evt.preventDefault();
evt.stopPropagation();
console.log("Editing " + i)
if (buttonsarray[i]) {
var icon = buttonsarray[i].icon;
var title = buttonsarray[i].title;
var gcode = buttonsarray[i].gcode;
var cls = buttonsarray[i].class;
} else {
var icon = "far fa-question-circle";
var title = "";
var gcode = "";
var cls = "";
}
var macroTemplate = `<form>
<div class="row mb-2">
<label class="cell-sm-2">Icon</label>
<div class="cell-sm-10">
<input id="macroicon" type="text" value="` + icon + `">
</div>
</div>
<div class="row mb-2">
<label class="cell-sm-2">Label</label>
<div class="cell-sm-10">
<input id="macrotitle" type="text" value="` + title + `">
</div>
</div>
<div class="row mb-2">
<label class="cell-sm-2">GCODE</label>
<div class="cell-sm-10">
<input id="macrogcode" type="text" value="` + gcode + `">
</div>
</div>
<div class="row mb-2">
<label class="cell-sm-2">Color</label>
<div class="cell-sm-10">
<select data-role="select" id="macrocls">
<option value="" selected>Default</option>
<option value="primary">Blue</option>
<option value="info">Light Blue</option>
<option value="secondary">Blue-Gray</option>
<option value="success">Green</option>
<option value="alert">Red</option>
<option value="warning">Orange</option>
<option value="yellow">Yellow</option>
<option value="dark">Dark</option>
<option value="light">Light</option>
</select>
</div>
</div>
<input type="hidden" id="macroseq" value="` + i + `" />
</form>`
Metro.dialog.create({
title: "Edit Macro",
content: macroTemplate,
actions: [{
caption: "Cancel",
cls: "js-dialog-close",
onclick: function() {
//
}
},
{
caption: "Delete Macro",
cls: "js-dialog-close alert",
onclick: function() {
buttonsarray.splice(i, 1);
populateMacroButtons();
}
},
{
caption: "Apply",
cls: "js-dialog-close success",
onclick: function() {
var seq = $('#macroseq').val();
if (buttonsarray[seq]) {
buttonsarray[seq].icon = $('#macroicon').val();
buttonsarray[seq].title = $('#macrotitle').val();
buttonsarray[seq].gcode = $('#macrogcode').val();
buttonsarray[seq].class = $('#macrocls').val();
populateMacroButtons();
} else {
buttonsarray.push({
title: $('#macrotitle').val(),
icon: $('#macroicon').val(),
gcode: $('#macrogcode').val(),
class: $('#macrocls').val()
})
populateMacroButtons();
}
}
}
]
});
var options = {
placement: 'bottom',
collision: 'none',
animation: true,
hideOnSelect: true,
};
// fa iconpicker https://github.com/farbelous/fontawesome-iconpicker
$('#macroicon').iconpicker(options);
$("#macrocls").val(cls).trigger("change");
}
function run(i, evt) {
evt.preventDefault();
evt.stopPropagation();
console.log("Run " + i)
}
// run it to begin
if (localStorage.getItem('macroButtons')) {
buttonsarray = JSON.parse(localStorage.getItem('macroButtons'));
}
populateMacroButtons()

Wyświetl plik

@ -0,0 +1,132 @@
fontawesome-iconpicker
========================
<!--[![Build Status](https://img.shields.io/travis/farbelous/fontawesome-iconpicker/master.svg?style=flat-square)](https://travis-ci.org/farbelous/fontawesome-iconpicker)-->
<!--[![npm@next](https://img.shields.io/npm/v/fontawesome-iconpicker/next.svg?style=flat-square)](https://www.npmjs.com/package/fontawesome-iconpicker?activeTab=versions)-->
[![npm](https://img.shields.io/npm/v/fontawesome-iconpicker.svg?style=flat-square)](https://www.npmjs.com/package/fontawesome-iconpicker)
[![Donate](https://img.shields.io/badge/%E2%9D%A4-Donate%20to%20this%20project-e0a61d.svg?longCache=true&style=flat-square)](https://github.com/itsjavi/itsjavi.github.io/blob/master/BACKERS.md#sponsors--backers)
[![Supporters](https://img.shields.io/badge/%F0%9F%92%AA-Supporters-333333.svg?longCache=true&style=flat-square)](https://github.com/itsjavi/itsjavi.github.io/blob/master/BACKERS.md#sponsors)
Font Awesome Icon Picker is a fully customizable plugin for Twitter Bootstrap,
with a powerful base API, based on [bootstrap-popover-picker](https://farbelous.github.io/bootstrap-popover-picker/)
You can use Font Awesome 5 or another font icon set of your choice (icon list is totally customizable).
[View demos](https://farbelous.github.io/fontawesome-iconpicker/)
## Instantiation
You can call the plugin in several ways:
```javascript
// Create instance if not exists (returns a jQuery object)
$('.my').iconpicker();
$('.my').iconpicker({ /*options*/ }); // you can also specify options via data-* attributes
// For the first matched element, access to a plugin property value
$('.my').data('iconpicker').iconpickerProperty;
// For the first matched element, call a plugin instance method with the given args
$('.my').data('iconpicker').iconpickerMethod('methodArg1', 'methodArg2' /* , other args */);
// Call and apply a plugin method to EACH matched element.
$.iconpicker.batch('.my', 'iconpickerMethod', 'methodArg1', 'methodArg2' /* , other args */); ->
```
## Triggered Events
All of them exposes the plugin instance through event.iconpickerInstance
In order of call:
* iconpickerCreate
* iconpickerCreated
* iconpickerShow
* iconpickerShown
* iconpickerSelect (also exposes event.iconpickerItem and event.iconpickerValue)
* iconpickerUpdate
* iconpickerInvalid (also exposes event.iconpickerValue)
* iconpickerSetValue (also exposes event.iconpickerValue)
* iconpickerSetSourceValue (also exposes event.iconpickerValue)
* iconpickerUpdated
* iconpickerSelected (also exposes event.iconpickerItem and event.iconpickerValue)
* iconpickerHide
* iconpickerHidden
* iconpickerDestroy
* iconpickerDestroyed
```javascript
// Bind iconpicker events to the element
$('.my').on('iconpickerSelected', function(event){
/* event.iconpickerValue */
});
```
## Popover placement extensions
This plugin comes with more placement options than the original Bootstrap Popover.
Here are all the possibilities in detail:
1 2 3 4 5
G 6
F 7
E 8
D C B A 9
0. inline (no placement, display as inline-block)
1. topLeftCorner
2. topLeft
3. top (center)
4. topRight
5. topRightCorner
6. rightTop
7. right (center)
8. rightBottom
9. bottomRightCorner
A. bottomRight
B. bottom (center)
C. bottomLeft
D. bottomLeftCorner
E. leftBottom
F. left (center)
G. leftTop
## Available options
```javascript
var options = {
title: false, // Popover title (optional) only if specified in the template
selected: false, // use this value as the current item and ignore the original
defaultValue: false, // use this value as the current item if input or element value is empty
placement: 'bottom', // (has some issues with auto and CSS). auto, top, bottom, left, right
collision: 'none', // If true, the popover will be repositioned to another position when collapses with the window borders
animation: true, // fade in/out on show/hide ?
//hide iconpicker automatically when a value is picked. it is ignored if mustAccept is not false and the accept button is visible
hideOnSelect: false,
showFooter: false,
searchInFooter: false, // If true, the search will be added to the footer instead of the title
mustAccept: false, // only applicable when there's an iconpicker-btn-accept button in the popover footer
selectedCustomClass: 'bg-primary', // Appends this class when to the selected item
icons: [], // list of icon objects [{title:String, searchTerms:String}]. By default, all Font Awesome icons are included.
fullClassFormatter: function(val) {
return 'fa ' + val;
},
input: 'input,.iconpicker-input', // children input selector
inputSearch: false, // use the input as a search box too?
container: false, // Appends the popover to a specific element. If not set, the selected element or element parent is used
component: '.input-group-addon,.iconpicker-component', // children component jQuery selector or object, relative to the container element
// Plugin templates:
templates: {
popover: '<div class="iconpicker-popover popover"><div class="arrow"></div>' +
'<div class="popover-title"></div><div class="popover-content"></div></div>',
footer: '<div class="popover-footer"></div>',
buttons: '<button class="iconpicker-btn iconpicker-btn-cancel btn btn-default btn-sm">Cancel</button>' +
' <button class="iconpicker-btn iconpicker-btn-accept btn btn-primary btn-sm">Accept</button>',
search: '<input type="search" class="form-control iconpicker-search" placeholder="Type to filter" />',
iconpicker: '<div class="iconpicker"><div class="iconpicker-items"></div></div>',
iconpickerItem: '<a role="button" href="#" class="iconpicker-item"><i></i></a>',
}
};
```

Wyświetl plik

@ -0,0 +1,311 @@
/*!
* Font Awesome Icon Picker
* https://farbelous.github.io/fontawesome-iconpicker/
*
* @author Javi Aguilar, itsjavi.com
* @license MIT License
* @see https://github.com/farbelous/fontawesome-iconpicker/blob/master/LICENSE
*/
.iconpicker-popover.popover {
position: absolute;
top: 0;
left: 0;
display: none;
max-width: none;
padding: 1px;
text-align: left;
width: 234px;
background: #f7f7f7;
z-index: 9;
}
.iconpicker-popover.popover.top,
.iconpicker-popover.popover.topLeftCorner,
.iconpicker-popover.popover.topLeft,
.iconpicker-popover.popover.topRight,
.iconpicker-popover.popover.topRightCorner {
margin-top: -10px;
}
.iconpicker-popover.popover.right,
.iconpicker-popover.popover.rightTop,
.iconpicker-popover.popover.rightBottom {
margin-left: 10px;
}
.iconpicker-popover.popover.bottom,
.iconpicker-popover.popover.bottomRightCorner,
.iconpicker-popover.popover.bottomRight,
.iconpicker-popover.popover.bottomLeft,
.iconpicker-popover.popover.bottomLeftCorner {
margin-top: 10px;
}
.iconpicker-popover.popover.left,
.iconpicker-popover.popover.leftBottom,
.iconpicker-popover.popover.leftTop {
margin-left: -10px;
}
.iconpicker-popover.popover.inline {
margin: 0 0 12px 0;
position: relative;
display: inline-block;
opacity: 1;
top: auto;
left: auto;
bottom: auto;
right: auto;
max-width: 100%;
box-shadow: none;
z-index: auto;
vertical-align: top;
}
.iconpicker-popover.popover.inline > .arrow {
display: none;
}
.dropdown-menu .iconpicker-popover.inline {
margin: 0;
border: none;
}
.dropdown-menu.iconpicker-container {
padding: 0;
}
.iconpicker-popover.popover .popover-title {
padding: 12px;
font-size: 13px;
line-height: 15px;
border-bottom: 1px solid #ebebeb;
background-color: #f7f7f7;
}
.iconpicker-popover.popover .popover-title input[type=search].iconpicker-search {
margin: 0 0 2px 0;
}
.iconpicker-popover.popover .popover-title-text ~ input[type=search].iconpicker-search {
margin-top: 12px;
}
.iconpicker-popover.popover .popover-content {
padding: 0px;
text-align: center;
}
.iconpicker-popover .popover-footer {
float: none;
clear: both;
padding: 12px;
text-align: right;
margin: 0;
border-top: 1px solid #ebebeb;
background-color: #f7f7f7;
}
.iconpicker-popover .popover-footer:before,
.iconpicker-popover .popover-footer:after {
content: " ";
display: table;
}
.iconpicker-popover .popover-footer:after {
clear: both;
}
.iconpicker-popover .popover-footer .iconpicker-btn {
margin-left: 10px;
}
.iconpicker-popover .popover-footer input[type=search].iconpicker-search {
/*width:auto;
float:left;*/
margin-bottom: 12px;
}
.iconpicker-popover.popover > .arrow,
.iconpicker-popover.popover > .arrow:after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.iconpicker-popover.popover > .arrow {
border-width: 11px;
}
.iconpicker-popover.popover > .arrow:after {
border-width: 10px;
content: "";
}
.iconpicker-popover.popover.top > .arrow,
.iconpicker-popover.popover.topLeft > .arrow,
.iconpicker-popover.popover.topRight > .arrow {
left: 50%;
margin-left: -11px;
border-bottom-width: 0;
border-top-color: #999999;
border-top-color: rgba(0, 0, 0, 0.25);
bottom: -11px;
}
.iconpicker-popover.popover.top > .arrow:after,
.iconpicker-popover.popover.topLeft > .arrow:after,
.iconpicker-popover.popover.topRight > .arrow:after {
content: " ";
bottom: 1px;
margin-left: -10px;
border-bottom-width: 0;
border-top-color: #fff;
}
.iconpicker-popover.popover.topLeft > .arrow {
left: 8px;
margin-left: 0;
}
.iconpicker-popover.popover.topRight > .arrow {
left: auto;
right: 8px;
margin-left: 0;
}
.iconpicker-popover.popover.right > .arrow,
.iconpicker-popover.popover.rightTop > .arrow,
.iconpicker-popover.popover.rightBottom > .arrow {
top: 50%;
left: -11px;
margin-top: -11px;
border-left-width: 0;
border-right-color: #999999;
border-right-color: rgba(0, 0, 0, 0.25);
}
.iconpicker-popover.popover.right > .arrow:after,
.iconpicker-popover.popover.rightTop > .arrow:after,
.iconpicker-popover.popover.rightBottom > .arrow:after {
content: " ";
left: 1px;
bottom: -10px;
border-left-width: 0;
border-right-color: #fff;
}
.iconpicker-popover.popover.rightTop > .arrow {
top: auto;
bottom: 8px;
margin-top: 0;
}
.iconpicker-popover.popover.rightBottom > .arrow {
top: 8px;
margin-top: 0;
}
.iconpicker-popover.popover.bottom > .arrow,
.iconpicker-popover.popover.bottomRight > .arrow,
.iconpicker-popover.popover.bottomLeft > .arrow {
left: 50%;
margin-left: -11px;
border-top-width: 0;
border-bottom-color: #999999;
border-bottom-color: rgba(0, 0, 0, 0.25);
top: -11px;
}
.iconpicker-popover.popover.bottom > .arrow:after,
.iconpicker-popover.popover.bottomRight > .arrow:after,
.iconpicker-popover.popover.bottomLeft > .arrow:after {
content: " ";
top: 1px;
margin-left: -10px;
border-top-width: 0;
border-bottom-color: #fff;
}
.iconpicker-popover.popover.bottomLeft > .arrow {
left: 8px;
margin-left: 0;
}
.iconpicker-popover.popover.bottomRight > .arrow {
left: auto;
right: 8px;
margin-left: 0;
}
.iconpicker-popover.popover.left > .arrow,
.iconpicker-popover.popover.leftBottom > .arrow,
.iconpicker-popover.popover.leftTop > .arrow {
top: 50%;
right: -11px;
margin-top: -11px;
border-right-width: 0;
border-left-color: #999999;
border-left-color: rgba(0, 0, 0, 0.25);
}
.iconpicker-popover.popover.left > .arrow:after,
.iconpicker-popover.popover.leftBottom > .arrow:after,
.iconpicker-popover.popover.leftTop > .arrow:after {
content: " ";
right: 1px;
border-right-width: 0;
border-left-color: #fff;
bottom: -10px;
}
.iconpicker-popover.popover.leftBottom > .arrow {
top: 8px;
margin-top: 0;
}
.iconpicker-popover.popover.leftTop > .arrow {
top: auto;
bottom: 8px;
margin-top: 0;
}
.iconpicker {
position: relative;
text-align: left;
text-shadow: none;
line-height: 0;
display: block;
margin: 0;
overflow: hidden;
}
.iconpicker * {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
position: relative;
}
.iconpicker:before,
.iconpicker:after {
content: " ";
display: table;
}
.iconpicker:after {
clear: both;
}
.iconpicker .iconpicker-items {
position: relative;
clear: both;
float: none;
padding: 12px 0 0 12px;
background: #fff;
margin: 0;
overflow: hidden;
overflow-y: auto;
min-height: 49px;
max-height: 246px;
}
.iconpicker .iconpicker-items:before,
.iconpicker .iconpicker-items:after {
content: " ";
display: table;
}
.iconpicker .iconpicker-items:after {
clear: both;
}
.iconpicker .iconpicker-item {
float: left;
width: 14px;
height: 14px;
padding: 12px;
margin: 0 12px 12px 0;
text-align: center;
cursor: pointer;
border-radius: 3px;
font-size: 14px;
box-shadow: 0 0 0 1px #ddd;
color: inherit;
/*&:nth-child(4n+4) {
margin-right: 0;
}
&:nth-last-child(-n+4) {
margin-bottom: 0;
}*/
}
.iconpicker .iconpicker-item:hover:not(.iconpicker-selected) {
background-color: #eee;
}
.iconpicker .iconpicker-item.iconpicker-selected {
box-shadow: none;
color: #fff;
background: #000;
}
.iconpicker-component {
cursor: pointer;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long