UI cleanup

This commit is contained in:
Vince 2012-09-16 04:33:26 +02:00
parent b761750766
commit cfd5050901
33 changed files with 614 additions and 152 deletions

View file

@ -0,0 +1,8 @@
.tooltip.in {
opacity: 0.95;
filter: alpha(opacity=95);
}
.tooltip {
line-height: 20px;
}

112
css/bootstrap/bootstrap.css vendored Executable file
View file

@ -0,0 +1,112 @@
/*!
* Bootstrap v2.1.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
.clearfix {
*zoom: 1;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
line-height: 0;
}
.clearfix:after {
clear: both;
}
.hide-text {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
.input-block-level {
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.tooltip {
position: absolute;
z-index: 1030;
display: block;
visibility: visible;
padding: 5px;
font-size: 11px;
opacity: 0;
filter: alpha(opacity=0);
}
.tooltip.in {
opacity: 0.8;
filter: alpha(opacity=80);
}
.tooltip.top {
margin-top: -3px;
}
.tooltip.right {
margin-left: 3px;
}
.tooltip.bottom {
margin-top: 3px;
}
.tooltip.left {
margin-left: -3px;
}
.tooltip-inner {
max-width: 200px;
padding: 3px 8px;
color: #ffffff;
text-align: center;
text-decoration: none;
background-color: #000000;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.tooltip-arrow {
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.tooltip.top .tooltip-arrow {
bottom: 0;
left: 50%;
margin-left: -5px;
border-width: 5px 5px 0;
border-top-color: #000000;
}
.tooltip.right .tooltip-arrow {
top: 50%;
left: 0;
margin-top: -5px;
border-width: 5px 5px 5px 0;
border-right-color: #000000;
}
.tooltip.left .tooltip-arrow {
top: 50%;
right: 0;
margin-top: -5px;
border-width: 5px 0 5px 5px;
border-left-color: #000000;
}
.tooltip.bottom .tooltip-arrow {
top: 0;
left: 50%;
margin-left: -5px;
border-width: 0 5px 5px;
border-bottom-color: #000000;
}
.tooltip {
line-height: 20px;
}

1
css/bootstrap/readme.txt Normal file
View file

@ -0,0 +1 @@
Bootstrap custom build containing only the tooltip component

View file

@ -0,0 +1,20 @@
.preview-container {
position : absolute;
bottom : 0; right : 0;
height : 256px;
width : 256px;
background : white;
border : 0px Solid black;
border-radius:5px 0px 0px 5px;
box-shadow : 0px 0px 2px rgba(0,0,0,0.2);
}
.preview-container canvas {
border : 0px Solid transparent;
border-radius:5px 0px 0px 5px;
}
#preview-fps {
width : 200px;
}

View file

@ -1,12 +1,32 @@
.preview-list-wrapper {
overflow-y: scroll;
position: absolute;
top: 30px;
right:0;
bottom: 0;
left: 0;
}
.preview-list {
list-style-type: none;
padding-left: 7px;
padding-right: 7px;
}
.preview-tile {
padding : 10px;
overflow: hidden;
background-color: gray;
border-radius: 2px;
-webkit-box-shadow: 0 0 7px 0 rgba(0, 0, 0, 1);
box-shadow: 0 0 7px 0 rgba(0, 0, 0, 1);
}
.preview-tile:hover {
-webkit-box-shadow: 0 0 10px 0 rgba(0, 0, 0, 1);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 1);
}
.preview-tile .canvas-container {
@ -15,18 +35,33 @@
.preview-tile .tile-view {
float: left;
border: blue 1px solid;
border: #ccc 1px solid;
}
.preview-tile .tile-action {
display: none;
float: right;
cursor: pointer;
width: 30px;
height: 30px;
background-color: transparent;
background-repeat: no-repeat;
background-position: 7px 7px;
border: none;
}
.preview-tile:hover .tile-action {
display: block;
}
.preview-tile .tile-action.duplicate-frame-action {
background-image: url(../img/actions/duplicate.png);
}
.preview-tile .tile-action.delete-frame-action {
background-image: url(../img/actions/delete.png);
}
.preview-tile:hover {
background-color: lightgray;
}

View file

@ -17,4 +17,17 @@ ul, li {
margin : 0;
padding : 0;
list-style-type: none;
}
/* Force apparition of scrollbars on leopard */
::-webkit-scrollbar {
-webkit-appearance: none;
width: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: rgba(180,180,180,.7);
-webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}

View file

@ -1,58 +1,59 @@
/**
* Top menubars
*/
.menubar {
position: absolute;
top: 0; left: 0;
width: 100%; height: 30px;
background-color: #fff;
width: 100%;
height: 30px;
}
.left-nav {
position:absolute;
top : 30px; bottom : 0;
width : 200px;
overflow-y: scroll;
background : #000;
padding : 10px;
/**
* Application layout
*/
.left-section {
position: absolute;
top: 0;
bottom: 0;
width: 220px;
background: #666;
}
.main-panel {
position:absolute;
top : 30px; bottom : 0; left : 220px; right : 0;
background : #ccc;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 220px;
background: #ccc;
}
.preview-container {
position : absolute;
bottom : 0; right : 0;
height : 256px;
width : 256px;
background : white;
border : 0px Solid black;
border-radius:5px 0px 0px 5px;
box-shadow : 0px 0px 2px rgba(0,0,0,0.2);
/**
* CSS Helpers
*/
.overlay-total {
position: absolute;
top: 0;
right:0;
bottom: 0;
left: 0;
}
.preview-container canvas {
border : 0px Solid transparent;
border-radius:5px 0px 0px 5px;
}
#cursorInfo {
position : fixed;
cursor : default;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/**
* Canvases layout
*/
.action-button {
background-color : white;
width : 150px;
display : inline-block;
.canvas {
position: relative;
z-index: 1;
}
.canvas-container {
position: relative;
display: block;
@ -67,42 +68,35 @@
left: 0;
}
.canvas {
position: relative;
z-index: 1;
}
.drawing-canvas {
float: left;
}
.canvas-overlay {
.canvas.canvas-overlay {
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
.drawing-canvas {
float: left;
}
.drawing-canvas-container {
float: left;
}
#preview-fps {
width : 200px;
}
/**
* User messages
*/
.user-message {
position: absolute;
top: 2px;
right: 0;
bottom: 0;
left: 25%;
background-color: #F9EDBE;
padding: 4px 12px;
padding-right: 20px;
border-top-left-radius: 7px;
border-bottom-left-radius: 7px;
border-top-right-radius: 7px;
border-right: 0;
color: #222;
border: #F0C36D 1px solid;
@ -124,15 +118,3 @@
.user-message .close:hover {
color: black;
}
/* Force apparition of scrollbars on leopard */
::-webkit-scrollbar {
-webkit-appearance: none;
width: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: rgba(180,180,180,.7);
-webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}

View file

@ -1,7 +1,7 @@
.tools-group {
float: left;
height: 30px;
border-right: 1px solid #ccc;
border-left: 1px solid #ccc;
padding: 0 3px;
}
@ -19,11 +19,11 @@
* Framesheet level actions:
*/
.tool-icon.tool-save {
background-image: url(../img/tools/icons/save.png);
background-image: url(../img/actions/save.png);
}
.tool-icon.tool-add-frame {
background-image: url(../img/tools/icons/add-frame.png);
background-image: url(../img/actions/add.png);
}
@ -31,47 +31,47 @@
* Tool icons:
*/
.tool-icon.tool-pen {
background-image: url(../img/tools/icons/pen.png);
background-image: url(../img/tools/pen.png);
}
.tool-icon.tool-vertical-mirror-pen {
background-image: url(../img/tools/icons/vertical-mirror-pen.png);
background-image: url(../img/tools/vertical-mirror-pen.png);
}
.tool-icon.tool-paint-bucket {
background-image: url(../img/tools/icons/paint-bucket.png);
background-image: url(../img/tools/paint-bucket.png);
}
.tool-icon.tool-eraser {
background-image: url(../img/tools/icons/eraser.png);
background-image: url(../img/tools/eraser.png);
}
.tool-icon.tool-stroke {
background-image: url(../img/tools/icons/stroke.png);
background-image: url(../img/tools/stroke.png);
}
.tool-icon.tool-rectangle {
background-image: url(../img/tools/icons/rectangle.png);
background-image: url(../img/tools/rectangle.png);
}
.tool-icon.tool-circle {
background-image: url(../img/tools/cursors/circle.png);
background-image: url(../img/tools/circle.png);
}
.tool-icon.tool-move {
background-image: url(../img/tools/icons/hand.png);
background-image: url(../img/tools/hand.png);
}
.tool-icon.tool-rectangle-select {
background-image: url(../img/tools/icons/select.png);
background-image: url(../img/tools/select.png);
}
.tool-icon.tool-shape-select {
background-image: url(../img/tools/icons/wand.png);
background-image: url(../img/tools/wand.png);
}
/*.tool-icon.tool-palette {
background-image: url(../img/tools/icons/color-palette.png);
background-image: url(../img/tools/color-palette.png);
}*/
/*
@ -79,43 +79,43 @@
*/
.tool-paint-bucket .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/paint-bucket.png) 14 12, pointer;
cursor: url(../img/tools/paint-bucket.png) 14 12, pointer;
}
.tool-vertical-mirror-pen .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/vertical-mirror-pen.png) 14 12, pointer;
cursor: url(../img/tools/vertical-mirror-pen.png) 14 12, pointer;
}
.tool-pen .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/pen.png) 2 21, pointer;
cursor: url(../img/tools/pen.png) 2 21, pointer;
}
.tool-eraser .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/eraser.png) 2 21, pointer;
cursor: url(../img/tools/eraser.png) 2 21, pointer;
}
.tool-stroke .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/pen.png) 2 21, pointer;
cursor: url(../img/tools/pen.png) 2 21, pointer;
}
.tool-rectangle .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/rectangle.png) 4 21, pointer;
cursor: url(../img/tools/rectangle.png) 4 21, pointer;
}
.tool-circle .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/circle.png) 4 21, pointer;
cursor: url(../img/tools/circle.png) 4 21, pointer;
}
.tool-move .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/hand.png) 14 12, pointer;
cursor: url(../img/tools/hand.png) 14 12, pointer;
}
.tool-rectangle-select .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/select.png) 14 12, pointer;
cursor: url(../img/tools/select.png) 14 12, pointer;
}
.tool-shape-select .drawing-canvas-container:hover {
cursor: url(../img/tools/cursors/wand.png) 14 12, pointer;
cursor: url(../img/tools/wand.png) 14 12, pointer;
}
.tool-grid,
@ -136,6 +136,7 @@
.tool-color-picker {
padding: 5px 0 0 5px;
height: 25px;
cursor : default;
}
@ -148,7 +149,7 @@
position : relative;
}
#secondary-color-picker {
.secondary-color-picker {
top : 8px;
}

View file

Before

Width:  |  Height:  |  Size: 733 B

After

Width:  |  Height:  |  Size: 733 B

BIN
img/actions/delete.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

BIN
img/actions/duplicate.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

View file

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 620 B

BIN
img/tools/circle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

BIN
img/tools/color-palette.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

BIN
img/tools/eraser.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

BIN
img/tools/hand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

BIN
img/tools/mirror-pen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

BIN
img/tools/paint-bucket.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

BIN
img/tools/pen.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

BIN
img/tools/rectangle.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

BIN
img/tools/select.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
img/tools/stroke.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

BIN
img/tools/wand.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

View file

@ -12,57 +12,51 @@
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/tools.css">
<link rel="stylesheet" href="css/bootstrap/bootstrap.css">
<link rel="stylesheet" href="css/bootstrap/bootstrap-tooltip-custom.css">
<link rel="stylesheet" href="css/preview-film-section.css">
<link rel="stylesheet" href="css/preview-animation-section.css">
</head>
<body>
<!-- Tool section: -->
<div id="menubar" class="menubar">
<ul class="tools-group">
<!-- TODO: Remove that from here or change CSS class naming since
they are framesheet level actions, not tools -->
<li class="tool-icon tool-save" data-tool-id="tool-save" title="Save" onclick="piskel.storeSheet()"></li>
<li class="tool-icon tool-add-frame" id="add-frame-button" data-tool-id="tool-add-frame" title="Add a frame"></li>
</ul>
<ul id="tools-container" class="tools-group"></ul>
<ul class="tools-group">
<li class="tool-icon tool-palette" data-tool-id="tool-palette" title="Color palette">
<ul id="palette" class="palette">
<span class="palette-color transparent-color" data-color="TRANSPARENT" title="Transparent"></span>
</ul>
</li>
<li class="tool-icon tool-color-picker">
<input id="color-picker" class="color {hash:true}" type="text" value="" />
<input id="secondary-color-picker" class="color {hash:true}" type="text" value="" />
</li>
</ul>
<ul class="tools-group">
<li class="tool-preview-fps">
<input id="preview-fps" type="range" min="1" max="24" value="12" style="width:200px;"/>
<span id="display-fps">12 fps</span>
</li>
</ul>
<ul class="tools-group">
<li class="tool-grid">
<input id="show-grid" type="checkbox"/>
<label for="show-grid">Show grid</label>
</li>
</ul>
</div>
<div class='left-nav'>
<div class='left-section'>
<div class="menubar">
<ul class="tools-group">
<!-- TODO: Remove that from here or change CSS class naming since
they are framesheet level actions, not tools -->
<li class="tool-icon tool-save" data-tool-id="tool-save" title="Save" onclick="piskel.storeSheet()" rel="tooltip" data-placement="bottom" ></li>
<li class="tool-icon tool-add-frame" id="add-frame-button" data-tool-id="tool-add-frame" title="Add a frame" rel="tooltip" data-placement="bottom" ></li>
</ul>
</div>
<!-- List of frames: -->
<ul class="preview-list" id="preview-list"></ul>
<div class="preview-list-wrapper">
<ul class="preview-list" id="preview-list"></ul>
</div>
</div>
<div class='main-panel'>
<div id="menubar" class="menubar">
<ul id="tools-container" class="tools-group"></ul>
<ul class="tools-group">
<li class="tool-icon tool-palette">
<ul id="palette" class="palette">
<span class="tool-icon palette-color transparent-color" data-color="TRANSPARENT" title="Transparent"></span>
</ul>
</li>
<li class="tool-icon tool-color-picker">
<input id="color-picker" class="color {hash:true}" type="text" value="" />
<input id="secondary-color-picker" class="secondary-color-picker color {hash:true}" type="text" value="" />
</li>
</ul>
<ul class="tools-group">
<li class="tool-grid">
<input id="show-grid" type="checkbox"/>
<label for="show-grid">Show grid</label>
</li>
</ul>
</div>
<!-- Drawing area: -->
<div id="drawing-canvas-container" class="drawing-canvas-container canvas-container">
<div class="canvas-background"></div>
@ -70,17 +64,19 @@
<!-- Animation preview: -->
<div class='preview-container'>
<input id="preview-fps" type="range" min="1" max="24" value="12" style="width:200px;"/>
<span id="display-fps">12 FPS</span>
<div id='preview-canvas-container' class="canvas-container">
<div class="canvas-background"></div>
</div>
</div>
</div>
<div id="cursorInfo"></div>
<!-- Core libraries: -->
<script src="js/lib/jquery-1.8.0.js"></script>
<script src="js/lib/jquery-ui-1.8.23.custom.js"></script>
<script src="js/lib/pubsub.js"></script>
<script src="js/lib/pubsub.js"></script>
<script src="js/lib/bootstrap/bootstrap.js"></script>
<!-- Application wide configuration -->
<script src="js/Constants.js"></script>

View file

@ -24,7 +24,7 @@ pskl.Palette = (function() {
*/
var createPalette_ = function (colors) {
// Always adding transparent color
paletteRoot.html('<span class="palette-color transparent-color" data-color="TRANSPARENT" title="Transparent"></span>');
paletteRoot.html('<span class="palette-color transparent-color" data-color="TRANSPARENT" rel="tooltip" data-placement="bottom" title="Transparent"></span>');
for(var color in colors) {
if(color != Constants.TRANSPARENT_COLOR) {
addColorToPalette_(color);
@ -39,6 +39,8 @@ pskl.Palette = (function() {
if (paletteColors.indexOf(color) == -1 && color != Constants.TRANSPARENT_COLOR) {
var colorEl = document.createElement("li");
colorEl.className = "palette-color";
colorEl.setAttribute("rel", "tooltip");
colorEl.setAttribute("data-placement", "bottom");
colorEl.setAttribute("data-color", color);
colorEl.setAttribute("title", color);
colorEl.style.background = color;

View file

@ -20,7 +20,8 @@
};
ns.AnimatedPreviewController.prototype.onFPSSliderChange = function(evt) {
this.fps = parseInt($("#preview-fps")[0].value, 10);
this.fps = parseInt($("#preview-fps")[0].value, 10);
$("#display-fps").html(this.fps + " FPS")
};
ns.AnimatedPreviewController.prototype.render = function (delta) {

View file

@ -35,7 +35,10 @@
};
ns.PreviewFilmController.prototype.createPreviews_ = function () {
this.container.html("");
this.container.html("");
// Manually remove tooltips since mouseout events were shortcut by the DOM refresh:
$(".tooltip").remove();
var frameCount = this.framesheet.getFrameCount();
@ -174,9 +177,11 @@
previewTileRoot.addEventListener('click', this.onPreviewClick_.bind(this, tileNumber));
var canvasPreviewDuplicateAction = document.createElement("button");
canvasPreviewDuplicateAction.className = "tile-action"
canvasPreviewDuplicateAction.innerHTML = "dup"
canvasPreviewDuplicateAction.setAttribute('rel', 'tooltip');
canvasPreviewDuplicateAction.setAttribute('data-placement', 'right');
canvasPreviewDuplicateAction.setAttribute('title', 'Duplicate this frame');
canvasPreviewDuplicateAction.className = "tile-action duplicate-frame-action"
canvasPreviewDuplicateAction.addEventListener('click', this.onAddButtonClick_.bind(this, tileNumber));
// TODO(vincz): Eventually optimize this part by not recreating a FrameRenderer. Note that the real optim
@ -190,8 +195,10 @@
if(tileNumber > 0 || this.framesheet.getFrameCount() > 1) {
var canvasPreviewDeleteAction = document.createElement("button");
canvasPreviewDeleteAction.className = "tile-action"
canvasPreviewDeleteAction.innerHTML = "del"
canvasPreviewDeleteAction.setAttribute('rel', 'tooltip');
canvasPreviewDeleteAction.setAttribute('data-placement', 'right');
canvasPreviewDeleteAction.setAttribute('title', 'Delete this frame');
canvasPreviewDeleteAction.className = "tile-action delete-frame-action"
canvasPreviewDeleteAction.addEventListener('click', this.onDeleteButtonClick_.bind(this, tileNumber));
previewTileRoot.appendChild(canvasPreviewDeleteAction);
}

View file

@ -72,7 +72,7 @@
// TODO(vincz): Tools rendering order is not enforced by the data stucture (this.toolInstances), fix that.
for (var toolKey in this.toolInstances) {
currentTool = this.toolInstances[toolKey];
toolMarkup += '<li class="tool-icon ' + currentTool.toolId + '" data-tool-id="' + currentTool.toolId +
toolMarkup += '<li rel="tooltip" data-placement="bottom" class="tool-icon ' + currentTool.toolId + '" data-tool-id="' + currentTool.toolId +
'" title="' + currentTool.helpText + '"></li>';
}
$('#tools-container').html(toolMarkup);

View file

@ -22,10 +22,10 @@
*/
ns.SimplePen.prototype.applyToolAt = function(col, row, color, frame, overlay) {
if (frame.containsPixel(col, row)) {
this.previousCol = col;
this.previousRow = row;
frame.setPixel(col, row, color);
frame.setPixel(col, row, color);
}
this.previousCol = col;
this.previousRow = row;
};
ns.SimplePen.prototype.moveToolAt = function(col, row, color, frame, overlay) {

275
js/lib/bootstrap/bootstrap.js vendored Executable file
View file

@ -0,0 +1,275 @@
/* ===========================================================
* bootstrap-tooltip.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#tooltips
* Inspired by the original jQuery.tipsy by Jason Frame
* ===========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* TOOLTIP PUBLIC CLASS DEFINITION
* =============================== */
var Tooltip = function (element, options) {
this.init('tooltip', element, options)
}
Tooltip.prototype = {
constructor: Tooltip
, init: function (type, element, options) {
var eventIn
, eventOut
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.enabled = true
if (this.options.trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (this.options.trigger != 'manual') {
eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
this.options.selector ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
}
, getOptions: function (options) {
options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay
, hide: options.delay
}
}
return options
}
, enter: function (e) {
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
if (!self.options.delay || !self.options.delay.show) return self.show()
clearTimeout(this.timeout)
self.hoverState = 'in'
this.timeout = setTimeout(function() {
if (self.hoverState == 'in') self.show()
}, self.options.delay.show)
}
, leave: function (e) {
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
if (this.timeout) clearTimeout(this.timeout)
if (!self.options.delay || !self.options.delay.hide) return self.hide()
self.hoverState = 'out'
this.timeout = setTimeout(function() {
if (self.hoverState == 'out') self.hide()
}, self.options.delay.hide)
}
, show: function () {
var $tip
, inside
, pos
, actualWidth
, actualHeight
, placement
, tp
if (this.hasContent() && this.enabled) {
$tip = this.tip()
this.setContent()
if (this.options.animation) {
$tip.addClass('fade')
}
placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement
inside = /in/.test(placement)
$tip
.remove()
.css({ top: 0, left: 0, display: 'block' })
.appendTo(inside ? this.$element : document.body)
pos = this.getPosition(inside)
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
switch (inside ? placement.split(' ')[1] : placement) {
case 'bottom':
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
break
case 'top':
tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
break
case 'left':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
break
case 'right':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
break
}
$tip
.css(tp)
.addClass(placement)
.addClass('in')
}
}
, setContent: function () {
var $tip = this.tip()
, title = this.getTitle()
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.removeClass('fade in top bottom left right')
}
, hide: function () {
var that = this
, $tip = this.tip()
$tip.removeClass('in')
function removeWithAnimation() {
var timeout = setTimeout(function () {
$tip.off($.support.transition.end).remove()
}, 500)
$tip.one($.support.transition.end, function () {
clearTimeout(timeout)
$tip.remove()
})
}
$.support.transition && this.$tip.hasClass('fade') ?
removeWithAnimation() :
$tip.remove()
return this
}
, fixTitle: function () {
var $e = this.$element
if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
}
}
, hasContent: function () {
return this.getTitle()
}
, getPosition: function (inside) {
return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
width: this.$element[0].offsetWidth
, height: this.$element[0].offsetHeight
})
}
, getTitle: function () {
var title
, $e = this.$element
, o = this.options
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
}
, tip: function () {
return this.$tip = this.$tip || $(this.options.template)
}
, validate: function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
, enable: function () {
this.enabled = true
}
, disable: function () {
this.enabled = false
}
, toggleEnabled: function () {
this.enabled = !this.enabled
}
, toggle: function () {
this[this.tip().hasClass('in') ? 'hide' : 'show']()
}
, destroy: function () {
this.hide().$element.off('.' + this.type).removeData(this.type)
}
}
/* TOOLTIP PLUGIN DEFINITION
* ========================= */
$.fn.tooltip = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('tooltip')
, options = typeof option == 'object' && option
if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tooltip.Constructor = Tooltip
$.fn.tooltip.defaults = {
animation: true
, placement: 'top'
, selector: false
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
, trigger: 'hover'
, title: ''
, delay: 0
, html: true
}
}(window.jQuery);

View file

@ -0,0 +1 @@
Bootstrap custom build containing only the tooltip component

View file

@ -88,6 +88,11 @@ $.namespace("pskl");
drawingLoop.addCallback(this.render, this);
drawingLoop.start();
// Init (event-delegated) bootstrap tooltips:
$('body').tooltip({
selector: '[rel=tooltip]'
});
this.connectResizeToDpiUpdate_();
},
@ -115,7 +120,10 @@ $.namespace("pskl");
* @private
*/
calculateDPIsForDrawingCanvas_ : function() {
var availableViewportHeight = $('.main-panel').height() - 50,
var userMessageGap = 80; // Reserve some height to show the user message at the bottom
var availableViewportHeight = $('.main-panel').height() - userMessageGap,
availableViewportWidth = $('.main-panel').width(),
previewHeight = $(".preview-container").height(),
previewWidth = $(".preview-container").width();