keyboard-layout-editor/kb.html
2015-07-05 17:34:16 -04:00

755 lines
No EOL
39 KiB
HTML

<!--***********************************************
KEYBOARD LAYOUT EDITOR
Copyright (C) 2013-2015 Ian Prest
All rights reserved.
************************************************-->
<!DOCTYPE html>
<html ng-app="kbApp">
<head>
<title>Keyboard Layout Editor</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" media="screen">
<link rel="stylesheet" type="text/css" href="css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="css/hint.min.css">
<link rel="stylesheet" type="text/css" href="css/colorpicker.min.css">
<link rel="stylesheet" type="text/css" href="kb.css">
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="js/angular-sanitize.min.js"></script>
<script type="text/javascript" src="js/ui-utils.min.js"></script>
<script type="text/javascript" src="js/jquery-2.0.2.min.js"></script>
<script type="text/javascript" src="js/ui-bootstrap-tpls-0.12.0.min.js"></script>
<script type="text/javascript" src="js/urlon.js"></script>
<script type="text/javascript" src="js/md5.js"></script>
<script type="text/javascript" src="js/jsonl.min.js"></script>
<script type="text/javascript" src="js/color.js"></script>
<script type="text/javascript" src="js/marked.min.js"></script>
<script type="text/javascript" src="js/FileSaver.min.js"></script>
<script type="text/javascript" src="js/ng-file-upload.min.js"></script>
<script type="text/javascript" src="js/draganddrop.min.js"></script>
<script type="text/javascript" src="js/bootstrap-colorpicker-module.min.js"></script>
<script type="text/javascript" src="extensions.js"></script>
<script type="text/javascript" src="render.js"></script>
<script type="text/javascript" src="serial.js"></script>
<script type="text/javascript" src="utils.js"></script>
<script type="text/javascript" src="kb.js"></script>
</head>
<body ng-controller="kbCtrl"
ng-mouseup="selectRelease($event)"
ng-mousemove="selectMove($event)"
ui-keydown="{'shift-191' : 'showHelp($event)',
112 : 'showHelp($event)',
118 : 'showOptions($event)',
'ctrl-83' : 'save($event)' }">
<div id="wrap">
<!--***********************************************
Nav Bar / Header
************************************************-->
<nav class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="navbar-header">
<!-- Hamburger menu, when width is too small -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- Main branding icon/title -->
<a class="navbar-brand" href="#"><i class="fa fa-keyboard-o"></i> keyboard-layout-editor.com</a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<!-- Left-aligned NavBar buttons -->
<ul class="nav navbar-nav">
<!-- Presets dropdown -->
<li class="dropdown" dropdown>
<a class="dropdown-toggle" dropdown-toggle><i class="fa fa-keyboard-o"></i> Preset <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class="dropdown-header">Standard Layouts:</li>
<li ng-repeat="v in layouts"><a ng-click="loadPreset(v.data)" href="#">{{v.name}}</a></li>
<li class="divider"></li>
<li class="dropdown-header">Complex Samples:</li>
<li ng-repeat="(k,v) in samples"><a ng-click="loadSample(v)" href="#">{{k}}</a></li>
</ul>
</li>
<!-- Color swatches dropdown -->
<li class="dropdown" dropdown>
<a class="dropdown-toggle" dropdown-toggle><i class="fa fa-th"></i> Color Swatches <b class="caret"></b></a>
<ul class="dropdown-menu">
<li ng-repeat="pal in palettes"><a ng-click="loadPalette(pal)" href="#">{{pal.name}}</a></li>
</ul>
</li>
</ul>
<!-- Right-aligned NavBar buttons -->
<ul class="nav navbar-nav navbar-right" style="">
<!-- Options button -->
<li><a href="#" ng-click="showOptions()"><i class="fa fa-cog"></i> Options</a></li>
<!-- Permalink button -->
<li><a ng-href="{{getPermalink()}}" target="_blank" ng-click="dirty = false"><i class="fa fa-link"></i> Permalink</a></li>
</ul>
</div>
</nav>
<div class="body" ng-cloak>
<!--***********************************************
Main Toolbar
************************************************-->
<!-- Add Key button w/dropdown -->
<div class="btn-group" dropdown>
<button type="button" class="btn btn-primary" ng-click="addKey()"><i class="fa fa-plus-circle"></i> Add Key</button>
<button type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a ng-click="addKeys(1)">Add 1 Key</a></li>
<li><a ng-click="addKeys(5)">Add 5 Keys</a></li>
<li><a ng-click="addKeys(10)">Add 10 Keys</a></li>
<li><a ng-click="addKeys(25)">Add 25 Keys</a></li>
<li class="divider" ng-class="{hidden: !specialKeys}"></li>
<li ng-repeat="(k,v) in specialKeys"><a ng-click="addKey(v)">Add '{{k}}' Key</a></li>
</ul>
</div>
<!-- Delete Key button -->
<div class="btn-group">
<button type="button" class="btn btn-danger" ng-class="{disabled:selectedKeys.length<1}" ng-click="deleteKeys()">
<i class="fa fa-minus-circle"></i> Delete Keys
</button>
</div>
<!-- Undo/Redo button group -->
<div class="btn-group">
<button type="button" class="btn btn-default" ng-class="{disabled:!canUndo()}" ng-click="undo()"><i class="fa fa-undo"></i> Undo</button>
<button type="button" class="btn btn-default" ng-class="{disabled:!canRedo()}" ng-click="redo()"><i class="fa fa-repeat"></i> Redo</button>
</div>
<!-- Clipboard button group -->
<div class="btn-group">
<button type="button" class="btn btn-default" ng-class="{disabled:!canCopy()}" ng-click="cut()"><i class="fa fa-cut"></i> Cut</button>
<button type="button" class="btn btn-default" ng-class="{disabled:!canCopy()}" ng-click="copy()"><i class="fa fa-copy"></i> Copy</button>
<button type="button" class="btn btn-default" ng-class="{disabled:!canPaste()}" ng-click="paste()"><i class="fa fa-paste"></i> Paste</button>
</div>
<!-- Save button (right aligned) -->
<div class="btn-group pull-right">
<button type="button" class="btn btn-success" ng-class="{disabled:!canSave()}" ng-click="save()"><i class="fa fa-save"></i> Save</button>
</div>
<!--***********************************************
Main Keyboard Preview/Editor area
************************************************-->
<div id="keyboard" ng-cloak
tabindex="0"
ng-style="{height: kbHeight + 'px', 'background-color': keyboard.meta.backcolor}"
ui-keydown="{ left:'moveKeys(-moveStep,0,$event)',
right:'moveKeys(moveStep,0,$event)',
up:'moveKeys(0,-moveStep,$event)',
down:'moveKeys(0,moveStep,$event)',
'shift-left':'sizeKeys(-sizeStep,0,$event)',
'shift-right':'sizeKeys(sizeStep,0,$event)',
'shift-up':'sizeKeys(0,-sizeStep,$event)',
'shift-down':'sizeKeys(0,sizeStep,$event)',
'pageup':'rotateKeys(-rotateStep,$event)',
'pagedown':'rotateKeys(rotateStep,$event)',
'ctrl-left':'moveCenterKeys(-moveStep,0,$event)',
'ctrl-right':'moveCenterKeys(moveStep,0,$event)',
'ctrl-up':'moveCenterKeys(0,-moveStep,$event)',
'ctrl-down':'moveCenterKeys(0,moveStep,$event)',
delete:'deleteKeys()',
insert:'addKey()',
74: 'prevKey($event)',
75: 'nextKey($event)',
'shift-74': 'prevKey($event)',
'shift-75': 'nextKey($event)',
113: 'focusEditor()',
esc: 'unselectAll()',
'ctrl-65': 'selectAll($event)',
'ctrl-67 ctrl-45': 'copy($event)',
'ctrl-88 shift-46': 'cut($event)',
'ctrl-86 shift-45': 'paste($event)',
'ctrl-90' : 'undo()',
'ctrl-shift-90' : 'redo()',
'ctrl-89' : 'redo()' }"
ng-mousedown="selectClick($event)"
ngf-drop="true" ngf-change="uploadJson($files, $event)" ngf-drag-over-class="drag-over">
<div ng-repeat="key in keys()"
class="key {{key.profile}}"
style="{{rotationStyle(key)}}"
ng-mouseover="hoveredKey=key"
ng-mouseleave="hoveredKey=null"
ng-class="{hover: hoveredKey==key, selected: selectedKeys.indexOf(key)>=0}"
ng-bind-html="key.html">
</div>
<div style="position:relative;line-height:1.2;padding-left:4px;" ng-style="{top:(kbHeight-32)+'px'}"><a href="#" ng-click="previewNotes()">{{keyboard.meta.name}}<br/><i>{{keyboard.meta.author}}</i></a></div>
<div style='clear:both'></div>
{{calcKbHeight()}}
</div>
<div id="selectionRectangle" ng-style="{display:selRect.display, left:selRect.l+'px', width:selRect.w+'px', top:selRect.t+'px', height:selRect.h+'px'}"></div>
<div id="rotationCrosshairs" ng-style="{display:multi.crosshairs, left:(keyboardLeft()+multi.crosshairs_x-5)+'px', top:(keyboardTop()+multi.crosshairs_y-7)+'px'}"><i class="fa fa-crosshairs"></i></div>
<!--***********************************************
Editor controls
************************************************-->
<!-- Tab strip -->
<ul class="nav nav-tabs" ng-cloak>
<li ng-class="{active:selTab==0}"><a ng-click="selTab=0" data-toggle="tab"><i class="fa fa-edit"></i> Properties</a></li>
<li ng-class="{active:selTab==1}"><a ng-click="selTab=1" data-toggle="tab"><i class="fa fa-keyboard-o"></i> Keyboard Properties</a></li>
<li ng-class="{active:selTab==2}"><a ng-click="selTab=2" data-toggle="tab"><i class="fa fa-code"></i> Raw data</a></li>
</ul>
<div id="tab-content" class='col-md-12 col-lg-12 row' ui-keydown="{esc:'focusKb()'}" ng-cloak>
<!-- PROPERTIES EDITOR -->
<div id="properties" ng-class="{hidden:selTab!=0}">
<form class="form-horizontal col-sm-8 col-md-5 col-lg-5">
<!-- Top Label -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="labeleditor0">Top Label:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline">
<kbd-label-editor label-index="0" hint-text="Specify the primary text of the keycap; typically displayed top-left, unless the centering options are used."></kbd-label-editor>
<kbd-label-editor label-index="2" hint-text="Specify secondary text for the keycap; typically displayed top-right."></kbd-label-editor>
<kbd-multi-check field="centerx" hint-text="Center the keycap text horizontally; the labels that would normally be left-aligned will be centered instead.">Center X</kbd-multi-check>
</div>
</div>
</div>
<!-- Center Label -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="labeleditor6">Center Label:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline">
<kbd-label-editor label-index="6" hint-text="Specify secondary text for the keycap; typically displayed center-left. You can specify a horizontal rule with <hr>."></kbd-label-editor>
<kbd-label-editor label-index="7" hint-text="Specify secondary text for the keycap; typically displayed center-right."></kbd-label-editor>
<kbd-multi-check field="centery" hint-text="Center the keycap text vertically; the labels that would normally be top-aligned will be centered instead.">Center Y</kbd-multi-check>
</div>
</div>
</div>
<!-- Bottom Label -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="labeleditor1">Bottom Label:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline">
<kbd-label-editor label-index="1" hint-text="Specify secondary text for the keycap; typically displayed bottom-left."></kbd-label-editor>
<kbd-label-editor label-index="3" hint-text="Specify secondary text for the keycap; typically displayed bottom-right."></kbd-label-editor>
</div>
</div>
</div>
<!-- Side-Print Label -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="labeleditor4">Side-Print Label:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline">
<kbd-label-editor label-index="4" hint-text="Specify the primary side-printed text for the keycap."></kbd-label-editor>
<kbd-label-editor label-index="5" hint-text="Specify secondary side-printed text for the keycap."></kbd-label-editor>
<kbd-multi-check field="centerf" hint-text="Center the side-printed text.">Center</kbd-multi-check>
</div>
</div>
</div>
<!-- Legend Size -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="fontheight-editor">Legend Size:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline hint--top hint--rounded"
data-hint="Specify the primary and secondary sizes for the keycap legends. The primary size affects only the primary text legend, while the secondary size is applied to all other legends.">
<kbd-multi-numbox field="fontheight" size="6" min="1" max="9"></kbd-multi-numbox>
<div class="form-group form-group-sm"> / </div>
<kbd-multi-numbox field="fontheight2" size="6" min="1" max="9"></kbd-multi-numbox>
</div>
</div>
</div>
<!-- Width -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="width-editor">Width:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline hint--top hint--rounded"
data-hint="Specify the primary and secondary widths for the keycap. The secondary width is used to specify the size of non-rectangular or stepped keys.">
<kbd-multi-numbox field="width" size="6" min="0.5" max="12" step='{{sizeStep}}'></kbd-multi-numbox>
<div class="form-group form-group-sm"> / </div>
<kbd-multi-numbox field="width2" size="6" min="0.5" max="12" step='{{sizeStep}}'></kbd-multi-numbox>
</div>
</div>
</div>
<!-- Height -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="height-editor">Height:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline hint--top hint--rounded"
data-hint="Specify the primary and secondary heights for the keycap. The secondary height is used to specify the size of non-rectangular or stepped keys.">
<kbd-multi-numbox field="height" size="6" min="0.5" max="12" step='{{sizeStep}}'></kbd-multi-numbox>
<div class="form-group form-group-sm"> / </div>
<kbd-multi-numbox field="height2" size="6" min="0.5" max="12" step='{{sizeStep}}'></kbd-multi-numbox>
</div>
</div>
</div>
<!-- X -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="x-editor">X:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline hint--top hint--rounded"
data-hint="Specify the X position of the keycap. An X-offset can also be specified to indicate how non-rectangular keys should be displayed.">
<kbd-multi-numbox field="x" size="6" min="0" max="36" step='{{moveStep}}'></kbd-multi-numbox>
<div class="form-group form-group-sm"> + </div>
<kbd-multi-numbox field="x2" size="6" min="-6" max="6" step='{{moveStep}}'></kbd-multi-numbox>
</div>
</div>
</div>
<!-- Y -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="y-editor">Y:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline hint--top hint--rounded"
data-hint="Specify the Y position of the keycap. A Y-offset can also be specified to indicate how non-rectangular keys should be displayed.">
<kbd-multi-numbox field="y" size="6" min="0" max="36" step='{{moveStep}}'></kbd-multi-numbox>
<div class="form-group form-group-sm"> + </div>
<kbd-multi-numbox field="y2" size="6" min="-6" max="6" step='{{moveStep}}'></kbd-multi-numbox>
</div>
</div>
</div>
<!-- Profile / Row -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="profileeditor">Profile / Row:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline hint--top hint--rounded"
data-hint="Specify the profile and (optionally) the row-number of the selected keys, e.g., 'DCS R1', 'DSA', 'DSA SPACE', etc.">
<div class="form-group form-group-sm">
<input id="profileeditor" class="form-control input-sm" size="24" type='text'
ng-model="multi.profile"
ng-change="updateMulti('profile')"
ng-blur="validateMulti('profile')"
ng-disabled="selectedKeys.length<1">
</div>
</div>
</div>
</div>
<!-- Key Color -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="coloreditor">Key Color:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline">
<kbd-color-picker picker-id="coloreditor" picker-position="top"
ng-model="multi.color"
ng-change="updateMulti('color')"
ng-blur="validateMulti('color')"
ng-disabled="selectedKeys.length<1"
hint-text="Specify the color to use for the background of the selected keycaps."
ui-on-Drop="dropSwatch($data,$event,false)" drop-channel="dragColor"></kbd-color-picker>
<div class="form-group form-group-sm color-name">{{colorName(multi.color)}}</div>
</div>
<!-- Swap Colors Button -->
<div>
<div id="swap-colors"
class="hint--top hint--rounded"
data-hint="Swap the text and keycap colors.">
<button class="btn btn-default"
ng-click="swapColors()"
ng-disabled="selectedKeys.length<1" >
<i class="fa fa-random"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Label Color -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="textcoloreditor">Label Color:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline">
<kbd-color-picker picker-id="textcoloreditor" picker-position="top"
ng-model="multi.text[0]"
ng-change="updateMulti('text',-1)"
ng-blur="validateMulti('text')"
ng-disabled="selectedKeys.length<1"
hint-text="Specify the color to use for the legend text on the selected keycaps."
ui-on-Drop="dropSwatch($data,$event,true,-1)" drop-channel="dragColor"></kbd-color-picker>
<div class="form-group form-group-sm color-name">{{colorName(multi.text[0])}}</div>
</div>
</div>
</div>
<!-- Rotation -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap" for="rotation_angle-editor">Rotation:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline hint--top hint--rounded"
data-hint="Specify the angle (in degrees) by which to rotate the keycaps, and the x &amp; y coordinates of the center of rotation.">
<kbd-multi-numbox field="rotation_angle" size="3" min="-180" max="180" step='{{rotateStep}}'></kbd-multi-numbox>
<div class="form-group form-group-sm"> &#176; </div>
<kbd-multi-numbox field="rotation_x" size="6" min="0" max="36" step='{{moveStep}}'></kbd-multi-numbox>
<div class="form-group form-group-sm"> , </div>
<kbd-multi-numbox field="rotation_y" size="6" min="0" max="36" step='{{moveStep}}'></kbd-multi-numbox>
</div>
</div>
</div>
<!-- Misc -->
<div class="form-group form-group-sm">
<label class="control-label col-md-3 col-lg-3 text-nowrap">Misc:</label>
<div class="col-md-9 col-lg-9">
<div class="form-inline">
<kbd-multi-check field="ghost" hint-text="Specify whether the selected keys should be rendered slightly transparently; this is useful to draw attention to the other, non-ghosted keycaps.">Ghosted</kbd-multi-check>
<kbd-multi-check field="stepped" hint-text="Specify whether the selected keys are 'stepped', i.e., part of the key is at a lower height than the rest. The secondary 'width' indicates the width of the stepped part.">Stepped</kbd-multi-check>
</div>
</div>
</div>
</form>
<div class="col-md-4 col-lg-4" ng-class="{hidden:!palette.name}">
{{palette.name}} <a ng-href='{{palette.href}}' data-hint="{{palette.description}}" class="hint--top hint--rounded" target="_blank">(more info)</a>
<ul id="swatches" ng-class="{disabled:selectedKeys.length<1}">
<li ng-repeat="color in palette.colors"
ng-style="{'background-color':color.css}"
ng-click="clickSwatch(color,$event)"
class="swatch hint--top"
ng-class="{'selected-bg': color.css === multi.color, 'selected-fg': color.css === multi.text[0]}"
data-hint="{{color.name}}"
ui-draggable="true" drag-channel="dragColor" drag="color">
<div class='highlight fg'></div>
<div class='highlight bg'></div>
</li>
</ul>
<alert type="warning" style="margin-top:10px;" ng-hide="paletteAlertHidden" close="paletteAlertHidden = true">
<i class="fa fa-info-circle"></i> Click on a swatch to set the color of the selected key(s), or Ctrl+Click to set the text color. You can also drag color swatches to individual labels to set different colors for each one.
</alert>
</div>
</div>
<!-- KEYBOARD PROPERTIES EDITOR -->
<div id="kbdproperties" ng-class="{hidden:selTab!=1}">
<form class="form-horizontal col-sm-12 col-md-12 col-lg-12">
<!-- Keyboard Color -->
<div class="form-group form-group-sm">
<label class="control-label col-md-2 col-lg-1 text-nowrap" for="kbdcoloreditor">Keyboard Color:</label>
<div class="col-md-10 col-lg-11">
<div class="form-inline">
<kbd-color-picker picker-id="kbdcoloreditor"
ng-model="meta.backcolor"
ng-change="updateMeta('backcolor')"
ng-blur="validateMeta('backcolor')"
hint-text="Specify the background color for the keyboard."></kbd-color-picker>
</div>
</div>
</div>
<!-- Keyboard Name -->
<div class="form-group form-group-sm">
<label class="control-label col-md-2 col-lg-1 text-nowrap" for="kbdnameeditor">Keyboard Name:</label>
<div class="col-md-10 col-lg-11 form-outdent hint--top hint--rounded"
data-hint="Specify the name of this keyboard layout.">
<input id="kbdnameeditor" class="form-control input-sm" type='text'
ng-model="meta.name"
ng-change="updateMeta('name')"
ng-blur="validateMeta('name')">
</div>
</div>
<!-- Author -->
<div class="form-group form-group-sm">
<label class="control-label col-md-2 col-lg-1 text-nowrap" for="authoreditor">Author:</label>
<div class="col-md-10 col-lg-11 form-outdent hint--top hint--rounded"
data-hint="Specify the author of this keyboard layout.">
<input id="authoreditor" class="form-control input-sm" type='text'
ng-model="meta.author"
ng-change="updateMeta('author')"
ng-blur="validateMeta('author')">
</div>
</div>
<!-- Notes -->
<div class="form-group form-group-sm">
<label class="control-label col-md-2 col-lg-1 text-nowrap" for="noteseditor">Notes:</label>
<div class="col-md-10 col-lg-11 form-outdent">
<div class="hint--top hint--rounded" style="width:100%"
data-hint="Specify any additional notes about this keyboard layout, e.g., links to manufacturers, colors used, additional credits, etc. GitHub-Flavored Markdown is supported for rich formatting.">
<textarea id="noteseditor" class="form-control" rows="15" spellcheck="true"
ng-model="meta.notes"
ng-change="updateMeta('notes')"
ng-blur="validateMeta('notes')"></textarea>
</div>
<div class="text-right">
<div class="btn-group btn-group-xs" role="group">
<button type="button" class="btn btn-success" ng-click="previewNotes()"><i class="fa fa-eye"></i> Preview</button>
</div>
<div class="btn-group btn-group-xs" role="group">
<a class="btn btn-primary" href="https://help.github.com/articles/markdown-basics/" target='_blank'><i class="fa fa-question-circle"></i> Markdown Syntax</a>
</div>
</div>
</div>
</div>
</form>
</div>
<!-- RAW DATA EDITOR -->
<div id="tab-rawdata" ng-class="{hidden:selTab!=2}">
<div ngf-drop="true" ngf-change="uploadJson($files, $event)" ngf-drag-over-class="drag-over">
<textarea id="rawdata" spellcheck="false" ng-model="serialized" ng-change="updateFromSerialized()" ng-class="{error:deserializeException!==''}" rows="15"></textarea>
</div>
<div style='text-align:right;margin-top:4px;'>
<div class="btn-group btn-group-xs" role="group">
<button type="button" class="btn btn-success" ng-click="downloadJson()"><i class="fa fa-download"></i> Download JSON</button>
<button ngf-select="true" class="btn btn-success" ngf-change="uploadJson($files, $event)"><i class="fa fa-upload"></i> Upload JSON</button>
</div>
<div class="btn-group btn-group-xs" role="group">
<a class="btn btn-primary" href="https://github.com/ijprest/keyboard-layout-editor/wiki/Serialized-Data-Format" target='_blank'><i class="fa fa-question-circle"></i> Raw Data Syntax</a>
</div>
</div>
<div id="rawdata-error" class="alert alert-danger" style='margin-top:1em;margin-bottom:0px' ng-class="{hidden:!deserializeException}">{{deserializeException}}</div>
</div>
</div>
<div class="col-md-12 col-lg-12 row" style="margin-top:1em;margin-left:0px;">
<alert type="success" ng-hide="!saved" close="saved=false" ng-cloak>
Saved! Your saved layout can be accessed via <a class="alert-link" ng-href="#/layouts/{{saved}}">this link</a>.
</alert>
<alert type="danger" ng-hide="!saveError" close="saveError=''" ng-cloak>
<P>There was an error saving your layout on the server: {{saveError}}</P>
<P>To ensure you don't lose any data, it is recommended that you <a class="alert-link" ng-click="downloadJson()">download your layout as JSON</a>.</P>
</alert>
<alert type="danger" ng-hide="!loadError" close="loadError=false" ng-cloak>
The requested layout does not exist.
</alert>
</div>
</div>
</div>
<!--***********************************************
Footer
************************************************-->
<div id="footer" ng-cloak>
<div class="container">
<p class="text-muted credit" style="float:left">
Keyboard Layout Editor v{{version}} (<a href='#' ng-click="showMarkdown('CHANGELOG.md', $event)">changelog</a>)<br/>
Copyright &copy; 2013-2015 &mdash; Ian Prest (<a href='#' ng-click="showMarkdown('CONTRIB.md', $event)">and contributors</a>)<br/>
All rights reserved. (<a href='#' ng-click="showMarkdown('LICENSE.md', $event)">LICENSE</a>)
</p>
<div style="float:right; text-alignment:right;">
<a href="#" ng-click="showHelp($event)"><i class="fa fa-question-circle"></i> Help &amp; keyboard shortcuts</a><br/>
<a href="https://github.com/ijprest/keyboard-layout-editor/issues" target="_blank"><i class="fa fa-bug"></i> Found a bug?</a><br/>
<a href="https://github.com/ijprest/keyboard-layout-editor" target="_blank"><i class="fa fa-github"></i> Code hosted on GitHub</a><br/>
</div>
</div>
</div>
<!--***********************************************
Help Dialog
************************************************-->
<script type="text/ng-template" id="helpDialog.html">
<div class="modal-header">
<button type="button" class="close" ng-click="cancel()">&times;</button>
<h4 class="modal-title">How to use keyboard-layout-editor.com</h4>
</div>
<div class="modal-body">
<h5>Getting Started:</h5>
<ul>
<li>Try loading one of the preset layouts from the dropdown at the top of the page.</li>
<ul>
<li>The <em>standard layouts</em> are intended to be used as a starting point for customization.</li>
<li>The <em>complex samples</em> are intended to give you an idea of the editor's capabilities, and to show off some awesome user-creations!</li>
</ul>
<li>Select a key in the editor by clicking on it; then try changing the various properties in the property-editor form.</li>
<li>You can select multiple keys by holding down CTRL and clicking on them, or extend the current selection by SHIFT-clicking on an item. You can also drag a marquee rectangle around the keys you want to select.</li>
<li>Try the keyboard shortcuts (described below); they make editing various properties much quicker.</li>
<li>You can save your layout to the server by clicking the 'Save' button on the toolbar.</li>
<li>You can save your layout locally by bookmarking the 'Permalink' (at the top of the page) in your bookmarks list.</li>
</ul>
<h5>Global Keyboard Shortcuts:</h5>
<dl class='dl-horizontal'>
<dt><kbd>F1</kbd> / <kbd>?</kbd></dt><dd>Show this help dialog</dd>
<dt><kbd>F7</kbd></dt><dd>Show the Options dialog</dd>
<dt><kbd>Ctrl&ndash;S</kbd></dt><dd>Save your layout (on the server)</dd>
</dl>
<h5>Editor Keyboard Shortcuts (these require that the editor has input focus):</h5>
<dl class='dl-horizontal' style='float:left;width:50%;'>
<dt><kbd></kbd></dt><dd>Move the selected keys</dd>
<dt><kbd>Shift&ndash;</kbd></dt><dd>Resize the selected keys</dd>
<dt><kbd>Ctrl&ndash;</kbd></dt><dd>Move the center of rotation for the selected keys</dd>
<dt><kbd>PgUp</kbd> / <kbd>PgDn</kbd></dt><dd>Change the angle of rotation for the selected keys</dd>
<dt><kbd>Ins</kbd></dt><dd>Add a new key</dd>
<dt><kbd>Del</kbd></dt><dd>Delete the selected keys</dd>
<dt><kbd>F2</kbd></dt><dd>Edit the text of the selected key</dd>
</dl>
<dl class='dl-horizontal' style='float:left;width:50%;'>
<dt><kbd>Ctrl&ndash;A</kbd> / <kbd>Esc</kbd></dt><dd>Select / deselect all keys</dd>
<dt><kbd>J</kbd> / <kbd>K</kbd></dt><dd>Select the previous / next key in the editor.</dd>
<dt><kbd>Ctrl&ndash;Z</kbd></dt><dd>Undo</dd>
<dt><kbd>Ctrl&ndash;Shift&ndash;Z</kbd> or <kbd>Ctrl&ndash;Y</kbd></dt><dd>Redo</dd>
<dt><kbd>Ctrl&ndash;X</kbd> or <kbd>Shift&ndash;Del</kbd></dt><dd>Cut the selected keys</dd>
<dt><kbd>Ctrl&ndash;C</kbd> or <kbd>Ctrl&ndash;Ins</kbd></dt><dd>Copy the selected keys</dd>
<dt><kbd>Ctrl&ndash;V</kbd> or <kbd>Shift&ndash;Ins</kbd></dt><dd>Paste keys from the clipboard</dd>
</dl>
<p>&nbsp;</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="ok()">OK</button>
</div>
</script>
<!--***********************************************
Markdown dialog for displaying README, etc.
************************************************-->
<script type="text/ng-template" id="markdownDialog.html">
<div class="modal-header">
<button type="button" class="close" ng-click="cancel()">&times;</button>
<h4 class="modal-title">{{$parent.markdownTitle}}</h4>
</div>
<div class="modal-body" ng-bind-html="$parent.markdownContent">&nbsp;</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="ok()">OK</button>
</div>
</script>
<!--***********************************************
Options Dialog
************************************************-->
<script type="text/ng-template" id="optionsDialog.html">
<div class="modal-header">
<button type="button" class="close" ng-click="cancel()">&times;</button>
<h4 class="modal-title">Options</h4>
</div>
<div class="modal-body">
<h5>Editor Step Sizes:</h5>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<label for="moveStepEditor" class="col-sm-6 col-md-3 col-lg-2 control-label">Move Step:</label>
<div class="col-sm-6 col-md-9 col-lg-10">
<div class="form-inline">
<div class="form-group form-group-sm">
<div class="input-group input-group-sm hint--top hint--rounded"
data-hint="Controls the step size when moving keys around the keyboard layout.">
<input id="moveStepEditor" class="form-control" type="number" min="0.05" max="2.5" step="0.05" size="6" ng-model="params.moveStep">
<span class="input-group-addon">units</span>
</div>
</div>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="sizeStepEditor" class="col-sm-6 col-md-3 col-lg-2 control-label">Size Step:</label>
<div class="col-sm-6 col-md-9 col-lg-10">
<div class="form-inline">
<div class="form-group form-group-sm">
<div class="input-group input-group-sm hint--top hint--rounded"
data-hint="Controls the step size when resizing keys in the keyboard layout.">
<input id="sizeStepEditor" class="form-control" type="number" min="0.05" max="2.5" step="0.05" size="6" ng-model="params.sizeStep">
<span class="input-group-addon">units</span>
</div>
</div>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="rotateStepEditor" class="col-sm-6 col-md-3 col-lg-2 control-label">Rotate Step:</label>
<div class="col-sm-6 col-md-9 col-lg-10">
<div class="form-inline">
<div class="form-group form-group-sm">
<div class="input-group input-group-sm hint--top hint--rounded"
data-hint="Controls the step size when rotating keys in the keyboard layout.">
<input id="rotateStepEditor" class="form-control" type="number" min="1" max="90" step="1" size="6" ng-model="params.rotateStep">
<span class="input-group-addon">degrees</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" ng-click="cancel()">Cancel</button>
<button type="button" class="btn btn-primary" ng-click="ok()">OK</button>
</div>
</script>
<!-- Color Picker Template -->
<script type="text/ng-template" id="colorPicker.html">
<div class="form-group form-group-sm">
<div class="input-group input-group-sm hint--top hint--rounded" ng-attr-data-hint="{{hintText}}">
<input id="{{pickerId}}" class="form-control" size="8" type='text'
ng-model="color" ng-change="onChange()" ng-blur="onBlur()" ng-disabled="isDisabled &amp;&amp; isDisabled()"
colorpicker="hex" colorpicker-close-on-select="true" colorpicker-position="{{pickerPosition || 'bottom'}}">
<span class="input-group-btn">
<button class="btn btn-default" ng-style="{'background-color':color}" ng-model="color" ng-change="onChange()" ng-disabled="isDisabled &amp;&amp; isDisabled()"
colorpicker="hex" colorpicker-close-on-select="true" colorpicker-position="{{pickerPosition || 'bottom'}}">&nbsp;</button>
</span>
</div>
</div>
</script>
<!-- Simple Editor Templates -->
<script type="text/ng-template" id="multiCheck.html">
<div class="form-group form-group-sm">
<div class="checkbox hint--top hint--rounded" ng-attr-data-hint="{{hintText}}">
<label>
<input id="{{field}}" type="checkbox"
ng-model="$parent.multi[field]"
ng-change="$parent.updateMulti(field)"
ng-blur="$parent.validateMulti(field)"
ng-disabled="$parent.selectedKeys.length<1">
<span ng-transclude></span>
</label>
</div>
</div>
</script>
<script type="text/ng-template" id="multiNumbox.html">
<div class="form-group form-group-sm">
<input id="{{field}}-editor" class="form-control input-sm" size="{{size}}" type='number' min="{{min}}" max="{{max}}" step="{{step || 1}}"
ng-model="$parent.multi[field]"
ng-change="$parent.updateMulti(field)"
ng-blur="$parent.validateMulti(field)"
ng-disabled="$parent.selectedKeys.length<1">
</div>
</script>
<!-- Label Editor Template -->
<script type="text/ng-template" id="labelEditor.html">
<div class="form-group form-group-sm">
<div class="input-group input-group-sm hint--top hint--rounded" ng-attr-data-hint="{{hintText}}"
ui-on-Drop="$parent.dropSwatch($data,$event,true,labelIndex)" drop-channel="dragColor">
<input id="labeleditor{{labelIndex}}" class="form-control" size="6" type='text'
ng-model="$parent.multi.labels[labelIndex]"
ng-change="$parent.updateMulti('labels',labelIndex)"
ng-blur="$parent.validateMulti('labels',labelIndex)"
ng-disabled="$parent.labelDisabled(labelIndex)">
<span class="input-group-btn">
<button class="btn btn-default"
ng-style="{'background-color':$parent.getTextColor($parent.multi.text,labelIndex)}"
ng-model="$parent.multi.text[labelIndex]"
ng-change="$parent.updateMulti('text',labelIndex)"
colorpicker="hex"
colorpicker-close-on-select="true"
colorpicker-with-input="true"
ng-disabled="$parent.labelDisabled(labelIndex)">&nbsp;</button>
</span>
</div>
</div>
</script>
</body>
</html>