commit b3581d255c9596f4ff9672eb2191237d866c4717 Author: Tomek Wójcik Date: Sat Aug 15 20:04:20 2015 +0200 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea0a80b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +appinfo.json +appinfo.site.json +build/ +.lock-waf* +/pebble_screenshot*.png diff --git a/GFX/amiclock.idraw b/GFX/amiclock.idraw new file mode 100644 index 0000000..5663e3a Binary files /dev/null and b/GFX/amiclock.idraw differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bad49a1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Tomek Wójcik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c19b92f --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# IntuiClock + +IntuiClock is a Pebble Time watchface inspired by the Clock program from Amiga® +Workbench 3.1. + +## License + +IntuiClock is licensed under MIT License. + +## Author and credits + +IntuiClock was written by [Tomek Wójcik](http://www.tomekwojcik.com/). + +This project uses Topaz font (CC BY-NC-SA 3.0) by dMG/t!s^dS. + +This project uses Slate frontend framework (MIT) by Pebble Technology. + +Amiga® is a brand of Amiga Inc. This project is not an official Amiga Inc. +product. diff --git a/appinfo.in.json b/appinfo.in.json new file mode 100644 index 0000000..92f7569 --- /dev/null +++ b/appinfo.in.json @@ -0,0 +1,39 @@ +{ + "uuid": null, + "shortName": null, + "longName": null, + "companyName": null, + "versionLabel": null, + "sdkVersion": "3", + "targetPlatforms": ["basalt"], + "watchapp": { + "watchface": true + }, + "resources": { + "media": [ + { + "type": "png", + "name": "IMG_BACKGROUND", + "file": "background.png" + }, + { + "type": "png", + "name": "IMG_BATTERY", + "file": "battery.png" + }, + { + "type": "font", + "name": "FONT_TOPAZ_16", + "file": "topaz1200.ttf" + } + ] + }, + "capabilities": [ + "configurable" + ], + "appKeys": { + "KEY_SECONDS_HAND": 0, + "KEY_BATTERY_INDICATOR": 1, + "KEY_DATE_FORMAT": 2 + } +} diff --git a/config/css/slate.min.css b/config/css/slate.min.css new file mode 100755 index 0000000..0a9dcfe --- /dev/null +++ b/config/css/slate.min.css @@ -0,0 +1 @@ +@font-face{font-family:'PFDinDisplayProLightWebfont';src:url("../fonts/PFDinDisplayPro-Light.woff") format("woff");font-weight:normal;font-style:normal;font-variant:normal}@font-face{font-family:'PTSansRegularWebfont';src:url("../fonts/PTSans-regular.woff") format("woff");font-weight:normal;font-style:normal;font-variant:normal}*{margin:0;padding:0}*:focus{outline-width:0}a{color:#ff4700;text-decoration:none}body{background-color:#eaeaea;margin-bottom:15px;font-size:1.2em;line-height:1.4em;-webkit-user-select:none !important;-moz-user-select:none !important;-ms-user-select:none !important;user-select:none !important}body,select,input[type=text],input[type=time],input[type=date]{font-family:'PFDinDisplayPro-Light',PFDinDisplayProLightWebfont,sans-serif;font-weight:normal}select,input[type=time],input[type=date]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;position:absolute;top:13px;color:#a8a8a8;font-size:1em;line-height:1em;background-color:#f7f7f7}input[type=date]{direction:rtl}select{right:30px;top:14px}input[type=time]{right:10px !important}input[type=date]{right:10px !important}.select-triangle{position:absolute;right:10px;top:20px;width:0;height:0;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ff4700}.item-container{color:#333;margin-top:15px}.item-container-header{padding:3px 10px;text-transform:uppercase;font-family:'PT Sans',PTSansRegularWebfont,sans-serif;font-size:.8em;font-weight:normal;color:#a8a8a8}.item-container-content{background-color:#f7f7f7;border-top:1px solid #dedede;border-bottom:1px solid #dedede}.item-container-footer{padding:3px 10px;font-size:.7em;line-height:1.4em;color:#a8a8a8}.item{position:relative;padding:10px;display:block;overflow:hidden}.item:not(:first-child){border-top:1px solid #dedede}.item-subtitle-wrapper{font-size:1em}.item-subtitle-wrapper .item-styled-toggle-wrapper{top:16px}.item-subtitle-wrapper .item-styled-checkbox{top:18px}.item-subtitle-wrapper .item-styled-radio{top:16px}.item-subtitle-wrapper .item-draggable-handle{top:18px}.item-subtitle{font-size:.7em;line-height:.7em;padding:.3em 0}.item-styled-toggle-wrapper{position:absolute;right:10px;top:8px;width:56px;height:30px;border-radius:5px;transition-timing-function:ease-in-out;transition-duration:.3s;transition-property:background-color}.item-styled-toggle{position:relative;background-color:#fff;width:28px;height:28px;border-radius:5px;top:1px;transition-timing-function:ease-in-out;transition-duration:.3s;transition-property:left}.item-toggle{display:none}.item-toggle+.item-styled-toggle-wrapper{background-color:#a8a8a8}.item-toggle:checked+.item-styled-toggle-wrapper{background-color:#ff4700}.item-toggle+.item-styled-toggle-wrapper .item-styled-toggle{left:1px}.item-toggle:checked+.item-styled-toggle-wrapper .item-styled-toggle{left:27px}.item-styled-toggle-bar{width:3px;height:15px;margin-left:3px;background-color:#eaeaea;float:left;position:relative;left:4px;top:7px}.item-styled-checkbox{position:absolute;right:10px;top:10px;width:21px;height:21px;border-radius:5px;border-width:2px;border-style:solid}.item-checkbox{display:none}.item-checkbox+.item-styled-checkbox{border-color:#dedede}.item-checkbox:checked+.item-styled-checkbox{border-color:#ff4700;background-color:#ff4700}.item-checkbox:checked+.item-styled-checkbox:before{content:"";display:block;position:relative;left:7px;width:6px;height:14px;border-color:#f7f7f7;border-width:0 2px 2px 0;border-style:solid;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.item-styled-radio{position:absolute;right:10px;top:10px;width:21px;height:21px;border-radius:12px;border-width:2px;border-style:solid}.item-radio{display:none}.item-radio+.item-styled-radio{border-color:#dedede}.item-radio:checked+.item-styled-radio{border-color:#ff4700;background-color:#ff4700}.item-radio:checked+.item-styled-radio:before{content:"";display:block;position:relative;top:1px;left:6px;width:6px;height:14px;border-color:#f7f7f7;border-width:0 2px 2px 0;border-style:solid;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.item-color{display:none}.item-styled-color{background:#f7f7f7}.item-styled-color .value{position:absolute;right:10px;top:10px;width:56px;height:30px;border-radius:5px;border-color:#a8a8a8;border-width:1px;border-style:solid}.item-styled-color .color-box-wrap{display:none;box-sizing:border-box;position:relative;height:0;width:100%;padding:0 0 100% 0;margin:.6em 0 0}.item-styled-color .color-box-wrap.show{display:block}.item-styled-color .color-box-wrap .color-box-container{position:absolute;height:99.97%;width:100%;left:0;top:0}.item-styled-color .color-box-wrap .color-box-container .color-box{float:left;cursor:pointer}.item-styled-color .color-box-wrap .color-box-container .color-box.rounded-tl{border-top-left-radius:5px}.item-styled-color .color-box-wrap .color-box-container .color-box.rounded-tr{border-top-right-radius:5px}.item-styled-color .color-box-wrap .color-box-container .color-box.rounded-bl{border-bottom-left-radius:5px}.item-styled-color .color-box-wrap .color-box-container .color-box.rounded-br{border-bottom-right-radius:5px}.item-date,.item-time{position:absolute;color:#f7f7f7 !important}.item-styled-date,.item-styled-time{position:absolute;top:13px;right:10px;color:#a8a8a8;font-size:1em;line-height:1em;background-color:#f7f7f7}.item-input-wrapper{border-radius:5px;border:2px solid #dedede}.item-input-wrapper-button{box-sizing:border-box;width:77%}.item-input{border:0;background-color:transparent;padding:0 10px 7px 10px;font-size:13px;width:100%;box-sizing:border-box}.button-container{text-align:center}.item-button{width:60%;height:35px;background-color:#ff4700;border-radius:5px;color:white;font-size:.8em;border:0;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none}.item-input-button{position:absolute;right:10px;top:9px;width:20%}.tab-buttons{display:table;width:100%;box-sizing:border-box;table-layout:fixed}.tab-button{display:table-cell;position:relative;color:#ff4700;border:1px solid #ff4700;border-right-width:0;font-size:14px;padding:5px 0;text-align:center;right:-1px}.tab-button:first-child{border-top-left-radius:5px;border-bottom-left-radius:5px;border-right-width:0}.tab-button:last-child{border-top-right-radius:5px;border-bottom-right-radius:5px;border-right-width:1px}.tab-button.active{background-color:#ff4700;color:#f7f7f7}.item-slider{position:relative;top:8px;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;height:30px;width:79%;overflow:hidden;background-color:transparent;margin-top:-10px}.item-slider::-webkit-slider-thumb:before{content:"";position:absolute;top:11px;left:-1001px;height:2px;width:1000px;background:#ff4700}.item-slider::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;position:relative;top:-13px;height:28px;width:28px;background-color:#fff;border-radius:5px;border:2px solid #eaeaea}.item-slider::-webkit-slider-runnable-track{height:2px;background-color:#dedede}.item-slider::-webkit-slider-thumb:after{content:"lll";position:absolute;left:4px;top:3px;height:12px;width:10px;font-weight:normal;text-align:center;color:#dedede;font-size:16px;letter-spacing:1px}.item-slider-text{position:absolute;top:6px;right:10px;width:16%}.item-slider-text .item-input{text-align:center}.delete-item{width:30px;height:30px;right:5px;top:5px;position:absolute;border-radius:6px}.delete-item:before,.delete-item:after{content:'';position:absolute;width:24px;height:2px;background-color:#a8a8a8;border-radius:2px;top:16px}.delete-item:before{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg);left:3px}.delete-item:after{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg);right:3px}.add-item{color:#ff4700}.item-draggable-handle{position:absolute;right:5px;top:10px;height:28px;width:28px}.item-draggable-handle-bar{margin-top:5px;height:2px;width:20px;background-color:#a8a8a8;text-align:center}[draggable=true]{background-color:#f7f7f7;border:2px solid #eaeaea;border-radius:2px} \ No newline at end of file diff --git a/config/fonts/PFDinDisplayPro-Light.woff b/config/fonts/PFDinDisplayPro-Light.woff new file mode 100755 index 0000000..1a206ff Binary files /dev/null and b/config/fonts/PFDinDisplayPro-Light.woff differ diff --git a/config/fonts/ptsans-regular.woff b/config/fonts/ptsans-regular.woff new file mode 100755 index 0000000..48d9d3f Binary files /dev/null and b/config/fonts/ptsans-regular.woff differ diff --git a/config/index.html b/config/index.html new file mode 100644 index 0000000..d4966e4 --- /dev/null +++ b/config/index.html @@ -0,0 +1,106 @@ + + + + + + IntuiClock Config + + + + + +
+
+
Features
+
+ + + +
+ +
+ +
+
+ +
+
+
+ + + + diff --git a/config/js/slate.min.js b/config/js/slate.min.js new file mode 100755 index 0000000..6781b7c --- /dev/null +++ b/config/js/slate.min.js @@ -0,0 +1,2 @@ +!function(t){"use strict";"function"==typeof define&&define.amd?define(t):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=t():"undefined"!=typeof Package?Sortable=t():window.Sortable=t()}(function(){"use strict";function t(t,e){this.el=t,this.options=e=v({},e),t[P]=this;var i={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(t.nodeName)?"li":">*",ghostClass:"sortable-ghost",ignore:"a, img",filter:null,animation:0,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0};for(var r in i)!(r in e)&&(e[r]=i[r]);var o=e.group;o&&"object"==typeof o||(o=e.group={name:o}),["pull","put"].forEach(function(t){t in o||(o[t]=!0)}),e.groups=" "+o.name+(o.put.join?" "+o.put.join(" "):"")+" ";for(var s in this)"_"===s.charAt(0)&&(this[s]=n(this,this[s]));a(t,"mousedown",this._onTapStart),a(t,"touchstart",this._onTapStart),a(t,"dragover",this),a(t,"dragenter",this),z.push(this._onDragOver),e.store&&this.sort(e.store.get(this))}function e(t){b&&b.state!==t&&(c(b,"display",t?"none":""),!t&&b.state&&x.insertBefore(b,g),b.state=t)}function n(t,e){var n=$.call(arguments,2);return e.bind?e.bind.apply(e,[t].concat(n)):function(){return e.apply(t,n.concat($.call(arguments)))}}function i(t,e,n){if(t){n=n||k,e=e.split(".");var i=e.shift().toUpperCase(),r=new RegExp("\\s("+e.join("|")+")\\s","g");do if(">*"===i&&t.parentNode===n||(""===i||t.nodeName.toUpperCase()==i)&&(!e.length||((" "+t.className+" ").match(r)||[]).length==e.length))return t;while(t!==n&&(t=t.parentNode))}return null}function r(t){t.dataTransfer.dropEffect="move",t.preventDefault()}function a(t,e,n){t.addEventListener(e,n,!1)}function o(t,e,n){t.removeEventListener(e,n,!1)}function s(t,e,n){if(t)if(t.classList)t.classList[n?"add":"remove"](e);else{var i=(" "+t.className+" ").replace(O," ").replace(" "+e+" "," ");t.className=(i+(n?" "+e:"")).replace(O," ")}}function c(t,e,n){var i=t&&t.style;if(i){if(void 0===n)return k.defaultView&&k.defaultView.getComputedStyle?n=k.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in i||(e="-webkit-"+e),i[e]=n+("string"==typeof n?"":"px")}}function l(t,e,n){if(t){var i=t.getElementsByTagName(e),r=0,a=i.length;if(n)for(;a>r;r++)n(i[r],r);return i}return[]}function u(t){t.draggable=!1}function f(){B=!1}function h(t,e){var n=t.lastElementChild,i=n.getBoundingClientRect();return e.clientY-(i.top+i.height)>5&&n}function d(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,i=0;n--;)i+=e.charCodeAt(n);return i.toString(36)}function p(t){for(var e=0;t&&(t=t.previousElementSibling);)"TEMPLATE"!==t.nodeName.toUpperCase()&&e++;return e}function m(t,e){var n,i;return function(){void 0===n&&(n=arguments,i=this,setTimeout(function(){1===n.length?t.call(i,n[0]):t.apply(i,n),n=void 0},e))}}function v(t,e){if(t&&e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var g,y,b,x,A,w,F,E,C,S,T,D,_,N,j={},O=/\s+/g,P="Sortable"+(new Date).getTime(),L=window,k=L.document,R=L.parseInt,M=!!("draggable"in k.createElement("div")),B=!1,Z=function(t,e,n,i,r,a,o){var s=k.createEvent("Event"),c=(t||e[P]).options,l="on"+n.charAt(0).toUpperCase()+n.substr(1);s.initEvent(n,!0,!0),s.item=i||e,s.from=r||e,s.clone=b,s.oldIndex=a,s.newIndex=o,c[l]&&c[l].call(t,s),e.dispatchEvent(s)},I=Math.abs,$=[].slice,z=[],Y=m(function(t,e,n){if(n&&e.scroll){var i,r,a,o,s=e.scrollSensitivity,c=e.scrollSpeed,l=t.clientX,u=t.clientY,f=window.innerWidth,h=window.innerHeight;if(F!==n&&(w=e.scroll,F=n,w===!0)){w=n;do if(w.offsetWidth=f-l)-(s>=l),o=(s>=h-u)-(s>=u),(a||o)&&(i=L)),(j.vx!==a||j.vy!==o||j.el!==i)&&(j.el=i,j.vx=a,j.vy=o,clearInterval(j.pid),i&&(j.pid=setInterval(function(){i===L?L.scrollTo(L.pageXOffset+a*c,L.pageYOffset+o*c):(o&&(i.scrollTop+=o*c),a&&(i.scrollLeft+=a*c))},24)))}},30);return t.prototype={constructor:t,_onTapStart:function(t){var e=this,n=this.el,r=this.options,a=t.type,o=t.touches&&t.touches[0],s=(o||t).target,c=s,l=r.filter;if(!("mousedown"===a&&0!==t.button||r.disabled)&&(s=i(s,r.draggable,n))){if(S=p(s),"function"==typeof l){if(l.call(this,t,s,this))return Z(e,c,"filter",s,n,S),void t.preventDefault()}else if(l&&(l=l.split(",").some(function(t){return t=i(c,t.trim(),n),t?(Z(e,t,"filter",s,n,S),!0):void 0})))return void t.preventDefault();(!r.handle||i(c,r.handle,n))&&this._prepareDragStart(t,o,s)}},_prepareDragStart:function(t,e,n){var i,r=this,o=r.el,s=r.options,c=o.ownerDocument;n&&!g&&n.parentNode===o&&(_=t,x=o,g=n,A=g.nextSibling,D=s.group,i=function(){r._disableDelayedDrag(),g.draggable=!0,s.ignore.split(",").forEach(function(t){l(g,t.trim(),u)}),r._triggerDragStart(e)},a(c,"mouseup",r._onDrop),a(c,"touchend",r._onDrop),a(c,"touchcancel",r._onDrop),s.delay?(a(c,"mousemove",r._disableDelayedDrag),a(c,"touchmove",r._disableDelayedDrag),r._dragStartTimer=setTimeout(i,s.delay)):i())},_disableDelayedDrag:function(){var t=this.el.ownerDocument;clearTimeout(this._dragStartTimer),o(t,"mousemove",this._disableDelayedDrag),o(t,"touchmove",this._disableDelayedDrag)},_triggerDragStart:function(t){t?(_={target:g,clientX:t.clientX,clientY:t.clientY},this._onDragStart(_,"touch")):M?(a(g,"dragend",this),a(x,"dragstart",this._onDragStart)):this._onDragStart(_,!0);try{k.selection?k.selection.empty():window.getSelection().removeAllRanges()}catch(e){}},_dragStarted:function(){x&&g&&(s(g,this.options.ghostClass,!0),t.active=this,Z(this,x,"start",g,x,S))},_emulateDragOver:function(){if(N){c(y,"display","none");var t=k.elementFromPoint(N.clientX,N.clientY),e=t,n=" "+this.options.group.name,i=z.length;if(e)do{if(e[P]&&e[P].options.groups.indexOf(n)>-1){for(;i--;)z[i]({clientX:N.clientX,clientY:N.clientY,target:t,rootEl:e});break}t=e}while(e=e.parentNode);c(y,"display","")}},_onTouchMove:function(t){if(_){var e=t.touches?t.touches[0]:t,n=e.clientX-_.clientX,i=e.clientY-_.clientY,r=t.touches?"translate3d("+n+"px,"+i+"px,0)":"translate("+n+"px,"+i+"px)";N=e,c(y,"webkitTransform",r),c(y,"mozTransform",r),c(y,"msTransform",r),c(y,"transform",r),t.preventDefault()}},_onDragStart:function(t,e){var n=t.dataTransfer,i=this.options;if(this._offUpEvents(),"clone"==D.pull&&(b=g.cloneNode(!0),c(b,"display","none"),x.insertBefore(b,g)),e){var r,o=g.getBoundingClientRect(),s=c(g);y=g.cloneNode(!0),c(y,"top",o.top-R(s.marginTop,10)),c(y,"left",o.left-R(s.marginLeft,10)),c(y,"width",o.width),c(y,"height",o.height),c(y,"opacity","0.8"),c(y,"position","fixed"),c(y,"zIndex","100000"),x.appendChild(y),r=y.getBoundingClientRect(),c(y,"width",2*o.width-r.width),c(y,"height",2*o.height-r.height),"touch"===e?(a(k,"touchmove",this._onTouchMove),a(k,"touchend",this._onDrop),a(k,"touchcancel",this._onDrop)):(a(k,"mousemove",this._onTouchMove),a(k,"mouseup",this._onDrop)),this._loopId=setInterval(this._emulateDragOver,150)}else n&&(n.effectAllowed="move",i.setData&&i.setData.call(this,n,g)),a(k,"drop",this);setTimeout(this._dragStarted,0)},_onDragOver:function(t){var n,r,a,o=this.el,s=this.options,l=s.group,u=l.put,d=D===l,p=s.sort;if(void 0!==t.preventDefault&&(t.preventDefault(),!s.dragoverBubble&&t.stopPropagation()),D&&!s.disabled&&(d?p||(a=!x.contains(g)):D.pull&&u&&(D.name===l.name||u.indexOf&&~u.indexOf(D.name)))&&(void 0===t.rootEl||t.rootEl===this.el)){if(Y(t,s,this.el),B)return;if(n=i(t.target,s.draggable,o),r=g.getBoundingClientRect(),a)return e(!0),void(b||A?x.insertBefore(g,b||A):p||x.appendChild(g));if(0===o.children.length||o.children[0]===y||o===t.target&&(n=h(o,t))){if(n){if(n.animated)return;v=n.getBoundingClientRect()}e(d),o.appendChild(g),this._animate(r,g),n&&this._animate(v,n)}else if(n&&!n.animated&&n!==g&&void 0!==n.parentNode[P]){E!==n&&(E=n,C=c(n));var m,v=n.getBoundingClientRect(),w=v.right-v.left,F=v.bottom-v.top,S=/left|right|inline/.test(C.cssFloat+C.display),T=n.offsetWidth>g.offsetWidth,_=n.offsetHeight>g.offsetHeight,N=(S?(t.clientX-v.left)/w:(t.clientY-v.top)/F)>.5,j=n.nextElementSibling;B=!0,setTimeout(f,30),e(d),m=S?n.previousElementSibling===g&&!T||N&&T:j!==g&&!_||N&&_,m&&!j?o.appendChild(g):n.parentNode.insertBefore(g,m?j:n),this._animate(r,g),this._animate(v,n)}}},_animate:function(t,e){var n=this.options.animation;if(n){var i=e.getBoundingClientRect();c(e,"transition","none"),c(e,"transform","translate3d("+(t.left-i.left)+"px,"+(t.top-i.top)+"px,0)"),e.offsetWidth,c(e,"transition","all "+n+"ms"),c(e,"transform","translate3d(0,0,0)"),clearTimeout(e.animated),e.animated=setTimeout(function(){c(e,"transition",""),c(e,"transform",""),e.animated=!1},n)}},_offUpEvents:function(){var t=this.el.ownerDocument;o(k,"touchmove",this._onTouchMove),o(t,"mouseup",this._onDrop),o(t,"touchend",this._onDrop),o(t,"touchcancel",this._onDrop)},_onDrop:function(e){var n=this.el,i=this.options;clearInterval(this._loopId),clearInterval(j.pid),clearTimeout(this.dragStartTimer),o(k,"drop",this),o(k,"mousemove",this._onTouchMove),o(n,"dragstart",this._onDragStart),this._offUpEvents(),e&&(e.preventDefault(),!i.dropBubble&&e.stopPropagation(),y&&y.parentNode.removeChild(y),g&&(o(g,"dragend",this),u(g),s(g,this.options.ghostClass,!1),x!==g.parentNode?(T=p(g),Z(null,g.parentNode,"sort",g,x,S,T),Z(this,x,"sort",g,x,S,T),Z(null,g.parentNode,"add",g,x,S,T),Z(this,x,"remove",g,x,S,T)):(b&&b.parentNode.removeChild(b),g.nextSibling!==A&&(T=p(g),Z(this,x,"update",g,x,S,T),Z(this,x,"sort",g,x,S,T))),t.active&&Z(this,x,"end",g,x,S,T)),x=g=y=A=b=w=F=_=N=E=C=D=t.active=null,this.save())},handleEvent:function(t){var e=t.type;"dragover"===e||"dragenter"===e?g&&(this._onDragOver(t),r(t)):("drop"===e||"dragend"===e)&&this._onDrop(t)},toArray:function(){for(var t,e=[],n=this.el.children,r=0,a=n.length,o=this.options;a>r;r++)t=n[r],i(t,o.draggable,this.el)&&e.push(t.getAttribute(o.dataIdAttr)||d(t));return e},sort:function(t){var e={},n=this.el;this.toArray().forEach(function(t,r){var a=n.children[r];i(a,this.options.draggable,n)&&(e[t]=a)},this),t.forEach(function(t){e[t]&&(n.removeChild(e[t]),n.appendChild(e[t]))})},save:function(){var t=this.options.store;t&&t.set(this)},closest:function(t,e){return i(t,e||this.options.draggable,this.el)},option:function(t,e){var n=this.options;return void 0===e?n[t]:void(n[t]=e)},destroy:function(){var t=this.el;t[P]=null,o(t,"mousedown",this._onTapStart),o(t,"touchstart",this._onTapStart),o(t,"dragover",this),o(t,"dragenter",this),Array.prototype.forEach.call(t.querySelectorAll("[draggable]"),function(t){t.removeAttribute("draggable")}),z.splice(z.indexOf(this._onDragOver),1),this._onDrop(),this.el=t=null}},t.utils={on:a,off:o,css:c,find:l,bind:n,is:function(t,e){return!!i(t,e,t)},extend:v,throttle:m,closest:i,toggleClass:s,index:p},t.version="1.2.0",t.create=function(e,n){return new t(e,n)},t});var Zepto=function(){function t(t){return null==t?String(t):q[U.call(t)]||"object"}function e(e){return"function"==t(e)}function n(t){return null!=t&&t==t.window}function i(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function r(e){return"object"==t(e)}function a(t){return r(t)&&!n(t)&&Object.getPrototypeOf(t)==Object.prototype}function o(t){return"number"==typeof t.length}function s(t){return _.call(t,function(t){return null!=t})}function c(t){return t.length>0?F.fn.concat.apply([],t):t}function l(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function u(t){return t in O?O[t]:O[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function f(t,e){return"number"!=typeof e||P[l(t)]?e:e+"px"}function h(t){var e,n;return j[t]||(e=N.createElement(t),N.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),j[t]=n),j[t]}function d(t){return"children"in t?D.call(t.children):F.map(t.childNodes,function(t){return 1==t.nodeType?t:void 0})}function p(t,e,n){for(w in e)n&&(a(e[w])||G(e[w]))?(a(e[w])&&!a(t[w])&&(t[w]={}),G(e[w])&&!G(t[w])&&(t[w]=[]),p(t[w],e[w],n)):e[w]!==A&&(t[w]=e[w])}function m(t,e){return null==e?F(t):F(t).filter(e)}function v(t,n,i,r){return e(n)?n.call(t,i,r):n}function g(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function y(t,e){var n=t.className||"",i=n&&n.baseVal!==A;return e===A?i?n.baseVal:n:void(i?n.baseVal=e:t.className=e)}function b(t){try{return t?"true"==t||("false"==t?!1:"null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?F.parseJSON(t):t):t}catch(e){return t}}function x(t,e){e(t);for(var n=0,i=t.childNodes.length;i>n;n++)x(t.childNodes[n],e)}var A,w,F,E,C,S,T=[],D=T.slice,_=T.filter,N=window.document,j={},O={},P={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},L=/^\s*<(\w+|!)[^>]*>/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,M=/^(?:body|html)$/i,B=/([A-Z])/g,Z=["val","css","html","text","data","width","height","offset"],I=["after","prepend","before","append"],$=N.createElement("table"),z=N.createElement("tr"),Y={tr:N.createElement("tbody"),tbody:$,thead:$,tfoot:$,td:z,th:z,"*":N.createElement("div")},H=/complete|loaded|interactive/,X=/^[\w-]*$/,q={},U=q.toString,V={},W=N.createElement("div"),J={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},G=Array.isArray||function(t){return t instanceof Array};return V.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,r=t.parentNode,a=!r;return a&&(r=W).appendChild(t),i=~V.qsa(r,e).indexOf(t),a&&W.removeChild(t),i},C=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},S=function(t){return _.call(t,function(e,n){return t.indexOf(e)==n})},V.fragment=function(t,e,n){var i,r,o;return k.test(t)&&(i=F(N.createElement(RegExp.$1))),i||(t.replace&&(t=t.replace(R,"<$1>")),e===A&&(e=L.test(t)&&RegExp.$1),e in Y||(e="*"),o=Y[e],o.innerHTML=""+t,i=F.each(D.call(o.childNodes),function(){o.removeChild(this)})),a(n)&&(r=F(i),F.each(n,function(t,e){Z.indexOf(t)>-1?r[t](e):r.attr(t,e)})),i},V.Z=function(t,e){return t=t||[],t.__proto__=F.fn,t.selector=e||"",t},V.isZ=function(t){return t instanceof V.Z},V.init=function(t,n){var i;if(!t)return V.Z();if("string"==typeof t)if(t=t.trim(),"<"==t[0]&&L.test(t))i=V.fragment(t,RegExp.$1,n),t=null;else{if(n!==A)return F(n).find(t);i=V.qsa(N,t)}else{if(e(t))return F(N).ready(t);if(V.isZ(t))return t;if(G(t))i=s(t);else if(r(t))i=[t],t=null;else if(L.test(t))i=V.fragment(t.trim(),RegExp.$1,n),t=null;else{if(n!==A)return F(n).find(t);i=V.qsa(N,t)}}return V.Z(i,t)},F=function(t,e){return V.init(t,e)},F.extend=function(t){var e,n=D.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){p(t,n,e)}),t},V.qsa=function(t,e){var n,r="#"==e[0],a=!r&&"."==e[0],o=r||a?e.slice(1):e,s=X.test(o);return i(t)&&s&&r?(n=t.getElementById(o))?[n]:[]:1!==t.nodeType&&9!==t.nodeType?[]:D.call(s&&!r?a?t.getElementsByClassName(o):t.getElementsByTagName(e):t.querySelectorAll(e))},F.contains=N.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},F.type=t,F.isFunction=e,F.isWindow=n,F.isArray=G,F.isPlainObject=a,F.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},F.inArray=function(t,e,n){return T.indexOf.call(e,t,n)},F.camelCase=C,F.trim=function(t){return null==t?"":String.prototype.trim.call(t)},F.uuid=0,F.support={},F.expr={},F.map=function(t,e){var n,i,r,a=[];if(o(t))for(i=0;i=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return T.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return e(t)?this.not(this.not(t)):F(_.call(this,function(e){return V.matches(e,t)}))},add:function(t,e){return F(S(this.concat(F(t,e))))},is:function(t){return this.length>0&&V.matches(this[0],t)},not:function(t){var n=[];if(e(t)&&t.call!==A)this.each(function(e){t.call(this,e)||n.push(this)});else{var i="string"==typeof t?this.filter(t):o(t)&&e(t.item)?D.call(t):F(t);this.forEach(function(t){i.indexOf(t)<0&&n.push(t)})}return F(n)},has:function(t){return this.filter(function(){return r(t)?F.contains(this,t):F(this).find(t).size()})},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!r(t)?t:F(t)},last:function(){var t=this[this.length-1];return t&&!r(t)?t:F(t)},find:function(t){var e,n=this;return e=t?"object"==typeof t?F(t).filter(function(){var t=this;return T.some.call(n,function(e){return F.contains(e,t)})}):1==this.length?F(V.qsa(this[0],t)):this.map(function(){return V.qsa(this,t)}):F()},closest:function(t,e){var n=this[0],r=!1;for("object"==typeof t&&(r=F(t));n&&!(r?r.indexOf(n)>=0:V.matches(n,t));)n=n!==e&&!i(n)&&n.parentNode;return F(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=F.map(n,function(t){return(t=t.parentNode)&&!i(t)&&e.indexOf(t)<0?(e.push(t),t):void 0});return m(e,t)},parent:function(t){return m(S(this.pluck("parentNode")),t)},children:function(t){return m(this.map(function(){return d(this)}),t)},contents:function(){return this.map(function(){return D.call(this.childNodes)})},siblings:function(t){return m(this.map(function(t,e){return _.call(d(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return F.map(this,function(e){return e[t]})},show:function(){return this.each(function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=h(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var n=e(t);if(this[0]&&!n)var i=F(t).get(0),r=i.parentNode||this.length>1;return this.each(function(e){F(this).wrapAll(n?t.call(this,e):r?i.cloneNode(!0):i)})},wrapAll:function(t){if(this[0]){F(this[0]).before(t=F(t));for(var e;(e=t.children()).length;)t=e.first();F(t).append(this)}return this},wrapInner:function(t){var n=e(t);return this.each(function(e){var i=F(this),r=i.contents(),a=n?t.call(this,e):t;r.length?r.wrapAll(a):i.append(a)})},unwrap:function(){return this.parent().each(function(){F(this).replaceWith(F(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(t){return this.each(function(){var e=F(this);(t===A?"none"==e.css("display"):t)?e.show():e.hide()})},prev:function(t){return F(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return F(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var n=this.innerHTML;F(this).empty().append(v(this,t,e,n))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=v(this,t,e,this.textContent);this.textContent=null==n?"":""+n}):0 in this?this[0].textContent:null},attr:function(t,e){var n;return"string"!=typeof t||1 in arguments?this.each(function(n){if(1===this.nodeType)if(r(t))for(w in t)g(this,w,t[w]);else g(this,t,v(this,e,n,this.getAttribute(t)))}):this.length&&1===this[0].nodeType?!(n=this[0].getAttribute(t))&&t in this[0]?this[0][t]:n:A},removeAttr:function(t){return this.each(function(){1===this.nodeType&&t.split(" ").forEach(function(t){g(this,t)},this)})},prop:function(t,e){return t=J[t]||t,1 in arguments?this.each(function(n){this[t]=v(this,e,n,this[t])}):this[0]&&this[0][t]},data:function(t,e){var n="data-"+t.replace(B,"-$1").toLowerCase(),i=1 in arguments?this.attr(n,e):this.attr(n);return null!==i?b(i):A},val:function(t){return 0 in arguments?this.each(function(e){this.value=v(this,t,e,this.value)}):this[0]&&(this[0].multiple?F(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var n=F(this),i=v(this,t,e,n.offset()),r=n.offsetParent().offset(),a={top:i.top-r.top,left:i.left-r.left};"static"==n.css("position")&&(a.position="relative"),n.css(a)});if(!this.length)return null;var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(e,n){if(arguments.length<2){var i,r=this[0];if(!r)return;if(i=getComputedStyle(r,""),"string"==typeof e)return r.style[C(e)]||i.getPropertyValue(e);if(G(e)){var a={};return F.each(e,function(t,e){a[e]=r.style[C(e)]||i.getPropertyValue(e)}),a}}var o="";if("string"==t(e))n||0===n?o=l(e)+":"+f(e,n):this.each(function(){this.style.removeProperty(l(e))});else for(w in e)e[w]||0===e[w]?o+=l(w)+":"+f(w,e[w])+";":this.each(function(){this.style.removeProperty(l(w))});return this.each(function(){this.style.cssText+=";"+o})},index:function(t){return t?this.indexOf(F(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return t?T.some.call(this,function(t){return this.test(y(t))},u(t)):!1},addClass:function(t){return t?this.each(function(e){if("className"in this){E=[];var n=y(this),i=v(this,t,e,n);i.split(/\s+/g).forEach(function(t){F(this).hasClass(t)||E.push(t)},this),E.length&&y(this,n+(n?" ":"")+E.join(" "))}}):this},removeClass:function(t){return this.each(function(e){if("className"in this){if(t===A)return y(this,"");E=y(this),v(this,t,e,E).split(/\s+/g).forEach(function(t){E=E.replace(u(t)," ")}),y(this,E.trim())}})},toggleClass:function(t,e){return t?this.each(function(n){var i=F(this),r=v(this,t,n,y(this));r.split(/\s+/g).forEach(function(t){(e===A?!i.hasClass(t):e)?i.addClass(t):i.removeClass(t)})}):this},scrollTop:function(t){if(this.length){var e="scrollTop"in this[0];return t===A?e?this[0].scrollTop:this[0].pageYOffset:this.each(e?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var e="scrollLeft"in this[0];return t===A?e?this[0].scrollLeft:this[0].pageXOffset:this.each(e?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),i=M.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(F(t).css("margin-top"))||0,n.left-=parseFloat(F(t).css("margin-left"))||0,i.top+=parseFloat(F(e[0]).css("border-top-width"))||0,i.left+=parseFloat(F(e[0]).css("border-left-width"))||0,{top:n.top-i.top,left:n.left-i.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||N.body;t&&!M.test(t.nodeName)&&"static"==F(t).css("position");)t=t.offsetParent;return t})}},F.fn.detach=F.fn.remove,["width","height"].forEach(function(t){var e=t.replace(/./,function(t){return t[0].toUpperCase()});F.fn[t]=function(r){var a,o=this[0];return r===A?n(o)?o["inner"+e]:i(o)?o.documentElement["scroll"+e]:(a=this.offset())&&a[t]:this.each(function(e){o=F(this),o.css(t,v(this,r,e,o[t]()))})}}),I.forEach(function(e,n){var i=n%2;F.fn[e]=function(){var e,r,a=F.map(arguments,function(n){return e=t(n),"object"==e||"array"==e||null==n?n:V.fragment(n)}),o=this.length>1;return a.length<1?this:this.each(function(t,e){r=i?e:e.parentNode,e=0==n?e.nextSibling:1==n?e.firstChild:2==n?e:null;var s=F.contains(N.documentElement,r);a.forEach(function(t){if(o)t=t.cloneNode(!0);else if(!r)return F(t).remove();r.insertBefore(t,e),s&&x(t,function(t){null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src||window.eval.call(window,t.innerHTML)})})})},F.fn[i?e+"To":"insert"+(n?"Before":"After")]=function(t){return F(t)[e](this),this}}),V.Z.prototype=F.fn,V.uniq=S,V.deserializeValue=b,F.zepto=V,F}();window.Zepto=Zepto,void 0===window.$&&(window.$=Zepto),function(t){function e(t){return t._zid||(t._zid=h++)}function n(t,n,a,o){if(n=i(n),n.ns)var s=r(n.ns);return(v[e(t)]||[]).filter(function(t){return!(!t||n.e&&t.e!=n.e||n.ns&&!s.test(t.ns)||a&&e(t.fn)!==e(a)||o&&t.sel!=o)})}function i(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function r(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function a(t,e){return t.del&&!y&&t.e in b||!!e}function o(t){return x[t]||y&&b[t]||t}function s(n,r,s,c,u,h,d){var p=e(n),m=v[p]||(v[p]=[]);r.split(/\s/).forEach(function(e){if("ready"==e)return t(document).ready(s);var r=i(e);r.fn=s,r.sel=u,r.e in x&&(s=function(e){var n=e.relatedTarget;return!n||n!==this&&!t.contains(this,n)?r.fn.apply(this,arguments):void 0}),r.del=h;var p=h||s;r.proxy=function(t){if(t=l(t),!t.isImmediatePropagationStopped()){t.data=c;var e=p.apply(n,t._args==f?[t]:[t].concat(t._args));return e===!1&&(t.preventDefault(),t.stopPropagation()),e}},r.i=m.length,m.push(r),"addEventListener"in n&&n.addEventListener(o(r.e),r.proxy,a(r,d))})}function c(t,i,r,s,c){var l=e(t);(i||"").split(/\s/).forEach(function(e){n(t,e,r,s).forEach(function(e){delete v[l][e.i],"removeEventListener"in t&&t.removeEventListener(o(e.e),e.proxy,a(e,c))})})}function l(e,n){return(n||!e.isDefaultPrevented)&&(n||(n=e),t.each(E,function(t,i){var r=n[t];e[t]=function(){return this[i]=A,r&&r.apply(n,arguments)},e[i]=w}),(n.defaultPrevented!==f?n.defaultPrevented:"returnValue"in n?n.returnValue===!1:n.getPreventDefault&&n.getPreventDefault())&&(e.isDefaultPrevented=A)),e}function u(t){var e,n={originalEvent:t};for(e in t)F.test(e)||t[e]===f||(n[e]=t[e]);return l(n,t)}var f,h=1,d=Array.prototype.slice,p=t.isFunction,m=function(t){return"string"==typeof t},v={},g={},y="onfocusin"in window,b={focus:"focusin",blur:"focusout"},x={mouseenter:"mouseover",mouseleave:"mouseout"};g.click=g.mousedown=g.mouseup=g.mousemove="MouseEvents",t.event={add:s,remove:c},t.proxy=function(n,i){var r=2 in arguments&&d.call(arguments,2);if(p(n)){var a=function(){return n.apply(i,r?r.concat(d.call(arguments)):arguments)};return a._zid=e(n),a}if(m(i))return r?(r.unshift(n[i],n),t.proxy.apply(null,r)):t.proxy(n[i],n);throw new TypeError("expected function")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var A=function(){return!0},w=function(){return!1},F=/^([A-Z]|returnValue$|layer[XY]$)/,E={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,n,i,r,a){var o,l,h=this;return e&&!m(e)?(t.each(e,function(t,e){h.on(t,n,i,e,a)}),h):(m(n)||p(r)||r===!1||(r=i,i=n,n=f),(p(i)||i===!1)&&(r=i,i=f),r===!1&&(r=w),h.each(function(f,h){a&&(o=function(t){return c(h,t.type,r),r.apply(this,arguments)}),n&&(l=function(e){var i,a=t(e.target).closest(n,h).get(0);return a&&a!==h?(i=t.extend(u(e),{currentTarget:a,liveFired:h}),(o||r).apply(a,[i].concat(d.call(arguments,1)))):void 0}),s(h,e,r,i,n,l||o)}))},t.fn.off=function(e,n,i){var r=this;return e&&!m(e)?(t.each(e,function(t,e){r.off(t,n,e)}),r):(m(n)||p(i)||i===!1||(i=n,n=f),i===!1&&(i=w),r.each(function(){c(this,e,i,n)}))},t.fn.trigger=function(e,n){return e=m(e)||t.isPlainObject(e)?t.Event(e):l(e),e._args=n,this.each(function(){e.type in b&&"function"==typeof this[e.type]?this[e.type]():"dispatchEvent"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,i){var r,a;return this.each(function(o,s){r=u(m(e)?t.Event(e):e),r._args=i,r.target=s,t.each(n(s,e.type||e),function(t,e){return a=e.proxy(r),r.isImmediatePropagationStopped()?!1:void 0})}),a},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e){t.fn[e]=function(t){return 0 in arguments?this.bind(e,t):this.trigger(e)}}),t.Event=function(t,e){m(t)||(e=t,t=e.type);var n=document.createEvent(g[t]||"Events"),i=!0;if(e)for(var r in e)"bubbles"==r?i=!!e[r]:n[r]=e[r];return n.initEvent(t,i,!0),l(n)}}(Zepto),function(t){function e(e,n,i){var r=t.Event(n);return t(e).trigger(r,i),!r.isDefaultPrevented()}function n(t,n,i,r){return t.global?e(n||y,i,r):void 0}function i(e){e.global&&0===t.active++&&n(e,null,"ajaxStart")}function r(e){e.global&&!--t.active&&n(e,null,"ajaxStop")}function a(t,e){var i=e.context;return e.beforeSend.call(i,t,e)===!1||n(e,i,"ajaxBeforeSend",[t,e])===!1?!1:void n(e,i,"ajaxSend",[t,e])}function o(t,e,i,r){var a=i.context,o="success";i.success.call(a,t,o,e),r&&r.resolveWith(a,[t,o,e]),n(i,a,"ajaxSuccess",[e,i,t]),c(o,e,i)}function s(t,e,i,r,a){var o=r.context;r.error.call(o,i,e,t),a&&a.rejectWith(o,[i,e,t]),n(r,o,"ajaxError",[i,r,t||e]),c(e,i,r)}function c(t,e,i){var a=i.context;i.complete.call(a,e,t),n(i,a,"ajaxComplete",[e,i]),r(i)}function l(){}function u(t){return t&&(t=t.split(";",2)[0]),t&&(t==F?"html":t==w?"json":x.test(t)?"script":A.test(t)&&"xml")||"text"}function f(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function h(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()||(e.url=f(e.url,e.data),e.data=void 0)}function d(e,n,i,r){return t.isFunction(n)&&(r=i,i=n,n=void 0),t.isFunction(i)||(r=i,i=void 0),{url:e,data:n,success:i,dataType:r}}function p(e,n,i,r){var a,o=t.isArray(n),s=t.isPlainObject(n);t.each(n,function(n,c){a=t.type(c),r&&(n=i?r:r+"["+(s||"object"==a||"array"==a?n:"")+"]"),!r&&o?e.add(c.name,c.value):"array"==a||!i&&"object"==a?p(e,c,i,n):e.add(n,c)})}var m,v,g=0,y=window.document,b=/)<[^<]*)*<\/script>/gi,x=/^(?:text|application)\/javascript/i,A=/^(?:text|application)\/xml/i,w="application/json",F="text/html",E=/^\s*$/,C=y.createElement("a");C.href=window.location.href,t.active=0,t.ajaxJSONP=function(e,n){if(!("type"in e))return t.ajax(e);var i,r,c=e.jsonpCallback,l=(t.isFunction(c)?c():c)||"jsonp"+ ++g,u=y.createElement("script"),f=window[l],h=function(e){t(u).triggerHandler("error",e||"abort")},d={abort:h};return n&&n.promise(d),t(u).on("load error",function(a,c){clearTimeout(r),t(u).off().remove(),"error"!=a.type&&i?o(i[0],d,e,n):s(null,c||"error",d,e,n),window[l]=f,i&&t.isFunction(f)&&f(i[0]),f=i=void 0}),a(d,e)===!1?(h("abort"),d):(window[l]=function(){i=arguments},u.src=e.url.replace(/\?(.+)=\?/,"?$1="+l),y.head.appendChild(u),e.timeout>0&&(r=setTimeout(function(){h("timeout")},e.timeout)),d)},t.ajaxSettings={ +type:"GET",beforeSend:l,success:l,error:l,complete:l,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:w,xml:"application/xml, text/xml",html:F,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0},t.ajax=function(e){var n,r=t.extend({},e||{}),c=t.Deferred&&t.Deferred();for(m in t.ajaxSettings)void 0===r[m]&&(r[m]=t.ajaxSettings[m]);i(r),r.crossDomain||(n=y.createElement("a"),n.href=r.url,n.href=n.href,r.crossDomain=C.protocol+"//"+C.host!=n.protocol+"//"+n.host),r.url||(r.url=window.location.toString()),h(r);var d=r.dataType,p=/\?.+=\?/.test(r.url);if(p&&(d="jsonp"),r.cache!==!1&&(e&&e.cache===!0||"script"!=d&&"jsonp"!=d)||(r.url=f(r.url,"_="+Date.now())),"jsonp"==d)return p||(r.url=f(r.url,r.jsonp?r.jsonp+"=?":r.jsonp===!1?"":"callback=?")),t.ajaxJSONP(r,c);var g,b=r.accepts[d],x={},A=function(t,e){x[t.toLowerCase()]=[t,e]},w=/^([\w-]+:)\/\//.test(r.url)?RegExp.$1:window.location.protocol,F=r.xhr(),S=F.setRequestHeader;if(c&&c.promise(F),r.crossDomain||A("X-Requested-With","XMLHttpRequest"),A("Accept",b||"*/*"),(b=r.mimeType||b)&&(b.indexOf(",")>-1&&(b=b.split(",",2)[0]),F.overrideMimeType&&F.overrideMimeType(b)),(r.contentType||r.contentType!==!1&&r.data&&"GET"!=r.type.toUpperCase())&&A("Content-Type",r.contentType||"application/x-www-form-urlencoded"),r.headers)for(v in r.headers)A(v,r.headers[v]);if(F.setRequestHeader=A,F.onreadystatechange=function(){if(4==F.readyState){F.onreadystatechange=l,clearTimeout(g);var e,n=!1;if(F.status>=200&&F.status<300||304==F.status||0==F.status&&"file:"==w){d=d||u(r.mimeType||F.getResponseHeader("content-type")),e=F.responseText;try{"script"==d?(1,eval)(e):"xml"==d?e=F.responseXML:"json"==d&&(e=E.test(e)?null:t.parseJSON(e))}catch(i){n=i}n?s(n,"parsererror",F,r,c):o(e,F,r,c)}else s(F.statusText||null,F.status?"error":"abort",F,r,c)}},a(F,r)===!1)return F.abort(),s(null,"abort",F,r,c),F;if(r.xhrFields)for(v in r.xhrFields)F[v]=r.xhrFields[v];var T="async"in r?r.async:!0;F.open(r.type,r.url,T,r.username,r.password);for(v in x)S.apply(F,x[v]);return r.timeout>0&&(g=setTimeout(function(){F.onreadystatechange=l,F.abort(),s(null,"timeout",F,r,c)},r.timeout)),F.send(r.data?r.data:null),F},t.get=function(){return t.ajax(d.apply(null,arguments))},t.post=function(){var e=d.apply(null,arguments);return e.type="POST",t.ajax(e)},t.getJSON=function(){var e=d.apply(null,arguments);return e.dataType="json",t.ajax(e)},t.fn.load=function(e,n,i){if(!this.length)return this;var r,a=this,o=e.split(/\s/),s=d(e,n,i),c=s.success;return o.length>1&&(s.url=o[0],r=o[1]),s.success=function(e){a.html(r?t("
").html(e.replace(b,"")).find(r):e),c&&c.apply(a,arguments)},t.ajax(s),this};var S=encodeURIComponent;t.param=function(e,n){var i=[];return i.add=function(e,n){t.isFunction(n)&&(n=n()),null==n&&(n=""),this.push(S(e)+"="+S(n))},p(i,e,n),i.join("&").replace(/%20/g,"+")}}(Zepto),function(t){t.fn.serializeArray=function(){var e,n,i=[],r=function(t){return t.forEach?t.forEach(r):void i.push({name:e,value:t})};return this[0]&&t.each(this[0].elements,function(i,a){n=a.type,e=a.name,e&&"fieldset"!=a.nodeName.toLowerCase()&&!a.disabled&&"submit"!=n&&"reset"!=n&&"button"!=n&&"file"!=n&&("radio"!=n&&"checkbox"!=n||a.checked)&&r(t(a).val())}),i},t.fn.serialize=function(){var t=[];return this.serializeArray().forEach(function(e){t.push(encodeURIComponent(e.name)+"="+encodeURIComponent(e.value))}),t.join("&")},t.fn.submit=function(e){if(0 in arguments)this.bind("submit",e);else if(this.length){var n=t.Event("submit");this.eq(0).trigger(n),n.isDefaultPrevented()||this.get(0).submit()}return this}}(Zepto),function(t){"__proto__"in{}||t.extend(t.zepto,{Z:function(e,n){return e=e||[],t.extend(e,t.fn),e.selector=n||"",e.__Z=!0,e},isZ:function(e){return"array"===t.type(e)&&"__Z"in e}});try{getComputedStyle(void 0)}catch(e){var n=getComputedStyle;window.getComputedStyle=function(t){try{return n(t)}catch(e){return null}}}}(Zepto),function(t,e){var n={COLOR:{EMPTY:"transparent"}};t.extend(t.fn,{itemToggle:function(){this.each(function(){var e=t(this),n=e.parent(),i=t('
');n.append(i)})},itemCheckbox:function(){this.each(function(){var e=t(this),n=e.parent(),i=t('
');n.append(i)})},itemSelect:function(){this.each(function(){var e=t(this),n=e.parent();n.append('
')})},itemDate:function(){this.each(function(){function e(){r.text(n.val())}var n=t(this),i=n.parent(),r=t('
');e(),i.append(r),n.change(function(){e()})})},itemTime:function(){this.each(function(){function e(){r.text(n.val())}var n=t(this),i=n.parent(),r=t('
');e(),i.append(r),n.change(function(){e()})})},itemRadio:function(){this.each(function(){var e=t(this),n=e.parent(),i=t('
');n.append(i)})},itemColor:function(e){var e=t.extend({},{sunny:!1},e||{}),i=[[!1,!1,"#55FF00","#AAFF55",!1,"#FFFF55","#FFFFAA",!1,!1],[!1,"#AAFFAA","#55FF55","#00FF00","#AAFF00","#FFFF00","#FFAA55","#FFAAAA",!1],["#55FFAA","#00FF55","#00AA00","#55AA00","#AAAA55","#AAAA00","#FFAA00","#FF5500","#FF5555"],["#AAFFFF","#00FFAA","#00AA55","#55AA55","#005500","#555500","#AA5500","#FF0000","#FF0055"],[!1,"#55AAAA","#00AAAA","#005555","#FFFFFF","#000000","#AA5555","#AA0000",!1],["#55FFFF","#00FFFF","#00AAFF","#0055AA","#AAAAAA","#555555","#550000","#AA0055","#FF55AA"],["#55AAFF","#0055FF","#0000FF","#0000AA","#000055","#550055","#AA00AA","#FF00AA","#FFAAFF"],[!1,"#5555AA","#5555FF","#5500FF","#5500AA","#AA00FF","#FF00FF","#FF55FF",!1],[!1,!1,!1,"#AAAAFF","#AA55FF","#AA55AA",!1,!1,!1]],r={"000000":"000000","000055":"001e41","0000aa":"004387","0000ff":"0068ca","005500":"2b4a2c","005555":"27514f","0055aa":"16638d","0055ff":"007dce","00aa00":"5e9860","00aa55":"5c9b72","00aaaa":"57a5a2","00aaff":"4cb4db","00ff00":"8ee391","00ff55":"8ee69e","00ffaa":"8aebc0","00ffff":"84f5f1",550000:"4a161b",550055:"482748","5500aa":"40488a","5500ff":"2f6bcc",555500:"564e36",555555:"545454","5555aa":"4f6790","5555ff":"4180d0","55aa00":"759a64","55aa55":"759d76","55aaaa":"71a6a4","55aaff":"69b5dd","55ff00":"9ee594","55ff55":"9de7a0","55ffaa":"9becc2","55ffff":"95f6f2",aa0000:"99353f",aa0055:"983e5a",aa00aa:"955694",aa00ff:"8f74d2",aa5500:"9d5b4d",aa5555:"9d6064",aa55aa:"9a7099",aa55ff:"9587d5",aaaa00:"afa072",aaaa55:"aea382",aaaaaa:"ababab",ffffff:"ffffff",aaaaff:"a7bae2",aaff00:"c9e89d",aaff55:"c9eaa7",aaffaa:"c7f0c8",aaffff:"c3f9f7",ff0000:"e35462",ff0055:"e25874",ff00aa:"e16aa3",ff00ff:"de83dc",ff5500:"e66e6b",ff5555:"e6727c",ff55aa:"e37fa7",ff55ff:"e194df",ffaa00:"f1aa86",ffaa55:"f1ad93",ffaaaa:"efb5b8",ffaaff:"ecc3eb",ffff00:"ffeeab",ffff55:"fff1b5",ffffaa:"fff6d3"};this.each(function(){for(var a=t(this),o=a.parent(),s="",c=100/i[0].length,l=100/i.length,u=c*i.length,f=0;f'}var b=t('
'+s+"
");o.append(b);var x=b.find(".value");a.on("click",function(t){o.find(".color-box-wrap").toggleClass("show")}),o.find(".color-box.selectable").on("click",function(e){e.preventDefault();var n=t(this).data("value");a.val(n),x.css("background-color",n.replace(/^0x/,"#")),o.find(".color-box-wrap").removeClass("show")})})},tab:function(){this.each(function(){var e=t(this);e.click(function(){var e=t(this),n=e.attr("name");t("a[name="+n+"]").each(function(){t(this).removeClass("active")}),e.addClass("active")})})},itemSlider:function(){this.each(function(){var e=t(this),n=e.attr("name"),i=t("input[name="+n+"][class=item-input]");e.on("input",function(){var e=t(this);i.val(e.val())}),i.change(function(){var n=t(this);e.val(n.val())})})},itemDraggableList:function(){this.each(function(){var n='
';t(this).children("label").append(n),e.create(this,{handle:".item-draggable-handle"})})},itemDynamicList:function(){this.each(function(){var e=t(this);e.children("label").each(function(){var e=t('
');e.click(function(){t(this).parent().remove()}),t(this).append(e)});var n=t('
Add one more...
');e.append(n),n.click(function(){function n(e,n){var i=e.val();n.text(i);var r=t('
');r.click(function(){t(this).parent().remove()}),n.append(r)}var i=t('
');i.insertBefore(e.children().last());var r=i.find("input");r.focus(),r.keypress(function(t){var e=t.which;13===e&&n(r,i)}),r.focusout(function(){n(r,i)})})})}}),t(function(){t(".item-toggle").itemToggle(),t(".item-checkbox").itemCheckbox(),t(".item-select").itemSelect(),t(".item-date").itemDate(),t(".item-time").itemTime(),t(".item-radio").itemRadio(),t(".item-color-normal").itemColor({sunny:!1}),t(".item-color-sunny").itemColor({sunny:!0}),t(".tab-button").tab(),t(".item-slider").itemSlider(),t(".item-draggable-list").itemDraggableList(),t(".item-dynamic-list").itemDynamicList()})}(Zepto,Sortable); \ No newline at end of file diff --git a/fabfile.py b/fabfile.py new file mode 100644 index 0000000..6474026 --- /dev/null +++ b/fabfile.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015 Tomek Wójcik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import codecs +import json + +from fabric.api import local, task + + +def _load_appinfo(path): + appinfo = None + with codecs.open(path, 'r', 'utf-8') as appinfo_in_f: + appinfo = json.loads(appinfo_in_f.read()) + + return appinfo + + +@task +def build(emulator=None, phone=None): + appinfo = _load_appinfo('appinfo.in.json') + assert appinfo + + appinfo_site = _load_appinfo('appinfo.site.json') + if appinfo_site: + appinfo.update(appinfo_site) + + with open('appinfo.json', 'w') as appinfo_f: + appinfo_f.write(json.dumps(appinfo, indent=4)) + + local('pebble build') + + +@task +def emu(platform='basalt'): + local('pebble install --emulator=%s' % platform) + + +@task +def phone(ip): + local('pebble install --phone=%s' % ip) diff --git a/resources/background.png b/resources/background.png new file mode 100644 index 0000000..95bb76f Binary files /dev/null and b/resources/background.png differ diff --git a/resources/battery.png b/resources/battery.png new file mode 100644 index 0000000..9623305 Binary files /dev/null and b/resources/battery.png differ diff --git a/resources/topaz1200.ttf b/resources/topaz1200.ttf new file mode 100755 index 0000000..2f7ec44 Binary files /dev/null and b/resources/topaz1200.ttf differ diff --git a/src/intuiclock.c b/src/intuiclock.c new file mode 100644 index 0000000..653b2ac --- /dev/null +++ b/src/intuiclock.c @@ -0,0 +1,349 @@ +/** + * Copyright (c) 2015 Tomek Wójcik + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include + +static Window *s_main_window; +static GBitmap *s_background_bitmap; +static GBitmap *s_battery_bitmap; +static GFont s_text_font; +static GPath *s_minute_hand; +static GPath *s_hour_hand; +static BitmapLayer *s_background_layer; +static TextLayer *s_title_layer; +static Layer *s_hands_layer; +static TextLayer *s_date_layer; +static TextLayer *s_ampm_layer; +static BitmapLayer *s_battery_icon_layer; +static Layer *s_battery_indicator_layer; +static struct tm *t = NULL; +static uint8_t battery_charge = 0; +static bool hide_seconds_hand = false; +static bool hide_battery_indicator = false; +static char date_format[2]; + +static const GPathInfo MINUTE_HAND_POINTS = { + 4, + (GPoint []) { + { 0, 0 }, + { -4.5, -26 }, + { 0, -38 }, + { 4.5, -26 } + } +}; + +static const GPathInfo HOUR_HAND_POINTS = { + 4, + (GPoint []) { + { 0, 0 }, + { -4.5, -22 }, + { 0, -29 }, + { 4.5, -22 } + } +}; + +#define AMPM_TEXT_SIZE 3 +#define DUMMY_AMPM_TEXT "" + +#define DATE_TEXT_SIZE 12 +#define DUMMY_DATE_TEXT "23 Jul 1985" + +#define KEY_SECONDS_HAND 0 +#define KEY_BATTERY_INDICATOR 1 +#define KEY_DATE_FORMAT 2 + +static void update_date_text_layer() { + static char date_text[DATE_TEXT_SIZE]; + size_t result = 0; + + if (strcmp(date_format, "d") == 0) { + result = strftime(date_text, DATE_TEXT_SIZE, "%d/%m/%y", t); + } else if (strcmp(date_format, "m") == 0) { + result = strftime(date_text, DATE_TEXT_SIZE, "%m/%d/%y", t); + } else { + result = strftime(date_text, DATE_TEXT_SIZE, "%e %b %Y", t); + } + + if (result != 0) { + text_layer_set_text(s_date_layer, date_text); + } else { + text_layer_set_text(s_date_layer, DUMMY_DATE_TEXT); + } +} + +static void update_ampm_text_layer() { + static char ampm_text[AMPM_TEXT_SIZE]; + + if (clock_is_24h_style()) { + text_layer_set_text(s_ampm_layer, DUMMY_AMPM_TEXT); + } else { + size_t result = strftime(ampm_text, AMPM_TEXT_SIZE, "%p", t); + if (result != 0) { + text_layer_set_text(s_ampm_layer, ampm_text); + } else { + text_layer_set_text(s_ampm_layer, DUMMY_AMPM_TEXT); + } + } +} + +static void tick_handler(struct tm *tick_time, TimeUnits changed_units) { + // Getting the current time. + time_t now = time(NULL); + t = localtime(&now); + + // Updating views. + layer_mark_dirty(s_hands_layer); + update_date_text_layer(); + update_ampm_text_layer(); +} + +static void s_hands_layer_update(Layer *layer, GContext *ctx) { + GRect bounds = layer_get_bounds(layer); + GPoint center = grect_center_point(&bounds); + + // Drawing the minute hand. + graphics_context_set_fill_color(ctx, GColorBlack); + graphics_context_set_stroke_color(ctx, GColorBlack); + gpath_move_to(s_minute_hand, (GPoint){39.5, 39}); + gpath_rotate_to(s_minute_hand, TRIG_MAX_ANGLE * t->tm_min / 60); + gpath_draw_outline(ctx, s_minute_hand); + gpath_draw_filled(ctx, s_minute_hand); + + // Drawing the hour hand. + graphics_context_set_fill_color(ctx, GColorBlack); + graphics_context_set_stroke_color(ctx, GColorBlack); + gpath_move_to(s_hour_hand, (GPoint){39.5, 39}); + gpath_rotate_to(s_hour_hand, (TRIG_MAX_ANGLE * (((t->tm_hour % 12) * 6) + (t->tm_min / 10))) / (12 * 6)); + gpath_draw_outline(ctx, s_hour_hand); + gpath_draw_filled(ctx, s_hour_hand); + + // Drawing the second hand. + if (hide_seconds_hand == false) { + graphics_context_set_antialiased(ctx, false); + int32_t second_angle = TRIG_MAX_ANGLE * t->tm_sec / 60; + int16_t second_hand_length = (bounds.size.w / 2) - 1; + GPoint second_hand = { + .x = (int16_t)(sin_lookup(second_angle) * (int32_t)second_hand_length / TRIG_MAX_RATIO) + center.x, + .y = (int16_t)(-cos_lookup(second_angle) * (int32_t)second_hand_length / TRIG_MAX_RATIO) + center.y, + }; + + graphics_context_set_stroke_color(ctx, GColorPictonBlue); + graphics_draw_line(ctx, second_hand, center); + graphics_context_set_antialiased(ctx, true); + } +} + +static void s_battery_indicator_layer_update(Layer *layer, GContext *ctx) { + GRect bounds = layer_get_bounds(layer); + + graphics_context_set_fill_color(ctx, GColorGreen); + if (battery_charge <= 10) { + graphics_context_set_fill_color(ctx, GColorRed); + } else if (battery_charge <= 60) { + graphics_context_set_fill_color(ctx, GColorYellow); + } + + graphics_fill_rect(ctx, bounds, 0, GCornerNone); +} + +static void battery_state_handler(BatteryChargeState charge) { + if (charge.charge_percent != battery_charge) { + battery_charge = charge.charge_percent; + layer_mark_dirty(s_battery_indicator_layer); + } +} + +static void start_time_tracking() { + TimeUnits unit = MINUTE_UNIT; + + if (hide_seconds_hand == false) { + unit = SECOND_UNIT; + } + + tick_handler(NULL, unit); + tick_timer_service_subscribe(unit, tick_handler); +} + +static void start_battery_tracking() { + if (hide_battery_indicator == false) { + BatteryChargeState charge = battery_state_service_peek(); + battery_state_handler(charge); + battery_state_service_subscribe(battery_state_handler); + } else { + battery_state_service_unsubscribe(); + } + + layer_set_hidden(bitmap_layer_get_layer(s_battery_icon_layer), hide_battery_indicator); + layer_set_hidden(s_battery_indicator_layer, hide_battery_indicator); +} + +static void inbox_received_handler(DictionaryIterator *iter, void *context) { + // Handling seconds_hand setting. + Tuple *seconds_hand_t = dict_find(iter, KEY_SECONDS_HAND); + if (seconds_hand_t && seconds_hand_t->value->int32 > 0) { + hide_seconds_hand = false; + } else { + hide_seconds_hand = true; + } + + persist_write_bool(KEY_SECONDS_HAND, hide_seconds_hand); + start_time_tracking(); + + // Handling battery_indicator setting. + Tuple *battery_indicator_t = dict_find(iter, KEY_BATTERY_INDICATOR); + if (battery_indicator_t && battery_indicator_t->value->int32 > 0) { + hide_battery_indicator = false; + } else { + hide_battery_indicator = true; + } + + persist_write_bool(KEY_BATTERY_INDICATOR, hide_battery_indicator); + start_battery_tracking(); + + // Handling date_format setting. + Tuple *date_format_t = dict_find(iter, KEY_DATE_FORMAT); + if (date_format_t) { + strcpy(date_format, date_format_t->value->cstring); + } + + persist_write_string(KEY_DATE_FORMAT, date_format); + update_date_text_layer(); +} + +static void main_window_load(Window *window) { + // Loading resources. + s_background_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMG_BACKGROUND); + s_battery_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMG_BATTERY); + s_text_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_TOPAZ_16)); + + // Creating hand paths. + s_minute_hand = gpath_create(&MINUTE_HAND_POINTS); + s_hour_hand = gpath_create(&HOUR_HAND_POINTS); + + Layer *window_layer = window_get_root_layer(window); + GRect bounds = layer_get_bounds(window_layer); + + // Creating background image layer. + s_background_layer = bitmap_layer_create(bounds); + bitmap_layer_set_bitmap(s_background_layer, s_background_bitmap); + bitmap_layer_set_compositing_mode(s_background_layer, GCompOpSet); + layer_add_child(window_layer, bitmap_layer_get_layer(s_background_layer)); + + // Creating title text layer. + s_title_layer = text_layer_create(GRect(36, 2, 46, 18)); + text_layer_set_background_color(s_title_layer, GColorClear); + text_layer_set_text(s_title_layer, "Clock"); + text_layer_set_font(s_title_layer, s_text_font); + layer_add_child(window_layer, text_layer_get_layer(s_title_layer)); + + // Creating hands layer. + s_hands_layer = layer_create(GRect(32, 38, 78, 78)); + layer_set_update_proc(s_hands_layer, s_hands_layer_update); + layer_add_child(window_layer, s_hands_layer); + + // Creating date layer. + s_date_layer = text_layer_create(GRect(17, 130, 109, 16)); + text_layer_set_text_alignment(s_date_layer, GTextAlignmentCenter); + text_layer_set_background_color(s_date_layer, GColorClear); + text_layer_set_font(s_date_layer, s_text_font); + layer_add_child(window_layer, text_layer_get_layer(s_date_layer)); + + // Creating AM/PM layer. + s_ampm_layer = text_layer_create(GRect(107, 26, 16, 16)); + text_layer_set_text_alignment(s_ampm_layer, GTextAlignmentCenter); + text_layer_set_background_color(s_ampm_layer, GColorClear); + text_layer_set_text_color(s_ampm_layer, GColorWhite); + text_layer_set_font(s_ampm_layer, s_text_font); + layer_add_child(window_layer, text_layer_get_layer(s_ampm_layer)); + + // Creating battery icon layer. + s_battery_icon_layer = bitmap_layer_create(GRect(20, 26, 16, 7)); + bitmap_layer_set_bitmap(s_battery_icon_layer, s_battery_bitmap); + bitmap_layer_set_compositing_mode(s_battery_icon_layer, GCompOpSet); + layer_add_child(window_layer, bitmap_layer_get_layer(s_battery_icon_layer)); + + // Creating battery indicator layer. + s_battery_indicator_layer = layer_create(GRect(21, 27, 13, 5)); + layer_set_update_proc(s_battery_indicator_layer, s_battery_indicator_layer_update); + layer_add_child(window_layer, s_battery_indicator_layer); + + // Read date_format setting from persistent storage. + int result = persist_read_string(KEY_DATE_FORMAT, date_format, 2); + if (result == E_DOES_NOT_EXIST) { + strcpy(date_format, "t"); + } + + // Starting time tracking. + hide_seconds_hand = persist_read_bool(KEY_SECONDS_HAND); + start_time_tracking(); + + // Starting battery tracking. + hide_battery_indicator = persist_read_bool(KEY_BATTERY_INDICATOR); + start_battery_tracking(); +} + +static void main_window_unload(Window *window) { + battery_state_service_unsubscribe(); + tick_timer_service_unsubscribe(); + + if (t) { + free(t); + } + + layer_destroy(s_battery_indicator_layer); + bitmap_layer_destroy(s_battery_icon_layer); + text_layer_destroy(s_ampm_layer); + text_layer_destroy(s_date_layer); + layer_destroy(s_hands_layer); + text_layer_destroy(s_title_layer); + bitmap_layer_destroy(s_background_layer); + + gpath_destroy(s_hour_hand); + gpath_destroy(s_minute_hand); + + fonts_unload_custom_font(s_text_font); + gbitmap_destroy(s_battery_bitmap); + gbitmap_destroy(s_background_bitmap); +} + +static void init() { + s_main_window = window_create(); + + window_set_window_handlers(s_main_window, (WindowHandlers) { + .load = main_window_load, + .unload = main_window_unload + }); + + window_stack_push(s_main_window, true); + + app_message_register_inbox_received(inbox_received_handler); + app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum()); +} + +static void deinit() { + window_destroy(s_main_window); +} + +int main(void) { + init(); + app_event_loop(); + deinit(); +} diff --git a/src/js/pebble-js-app.js b/src/js/pebble-js-app.js new file mode 100644 index 0000000..c5c743d --- /dev/null +++ b/src/js/pebble-js-app.js @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2015 Tomek Wójcik + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +Pebble.addEventListener('ready', function(e) { + console.log('JS Ready!'); +}); + +Pebble.addEventListener('showConfiguration', function(e) { + Pebble.openURL('https://pconf.bthlabs.pl/intuiclock/index.html'); +}); + +Pebble.addEventListener('webviewclosed', function(e) { + var config_data = JSON.parse(decodeURIComponent(e.response)); + console.log('Configuration page returned: ' + JSON.stringify(config_data)); + + var dict = {}; + dict['KEY_SECONDS_HAND'] = config_data['seconds_hand']; + dict['KEY_BATTERY_INDICATOR'] = config_data['battery_indicator']; + dict['KEY_DATE_FORMAT'] = config_data['date_format']; + + Pebble.sendAppMessage(dict, function() { + console.log('Send successful!'); + }, function() { + console.log('Send failed!'); + }); +}); diff --git a/wscript b/wscript new file mode 100644 index 0000000..040ab7c --- /dev/null +++ b/wscript @@ -0,0 +1,41 @@ + +# +# This file is the default set of rules to compile a Pebble project. +# +# Feel free to customize this to your needs. +# + +import os.path + +top = '.' +out = 'build' + +def options(ctx): + ctx.load('pebble_sdk') + +def configure(ctx): + ctx.load('pebble_sdk') + +def build(ctx): + ctx.load('pebble_sdk') + + build_worker = os.path.exists('worker_src') + binaries = [] + + for p in ctx.env.TARGET_PLATFORMS: + ctx.set_env(ctx.all_envs[p]) + ctx.set_group(ctx.env.PLATFORM_NAME) + app_elf='{}/pebble-app.elf'.format(ctx.env.BUILD_DIR) + ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), + target=app_elf) + + if build_worker: + worker_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR) + binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf}) + ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'), + target=worker_elf) + else: + binaries.append({'platform': p, 'app_elf': app_elf}) + + ctx.set_group('bundle') + ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/*.js'))